SISYN
SISYN

Reputation: 2269

Expanding lists push other relative positioned elements up - they should stay still

Let me start off with this fiddle: https://jsfiddle.net/Lwhpgmma/

Basically I have some list items like this:

    <ul class="specifics">
        <li>
            <ul>
                <li>Filter by Hosting</li>
                <li data-value="ghost" class="active">Ghost Host</li>
                <li data-value="they">They Host</li>
                <li data-value="you">You Host</li>
                <li data-value="server">Server</li>
            </ul>
        </li>
        <li>
            <ul>
                <li>Filter by Game Mode</li>
                <li data-value="1" class="active">Soccar</li>
                <li data-value="2">Snowday</li>
                <li data-value="3">Hoops</li>
            </ul>
        </li>
    </ul>

The inner <ul> is hidden via line-height: 0; on the parent <li> element. However, when an <li> element is clicked, the .active class is added and it gets set to line-height: normal;

This all works fine, except that it causes some ugly results when these first-tier <li> elements are stacked on-top of each other, like they are in the fiddle demo.

You'll notice when you click Manfield or $100 list elements, that the list elements above them (Server and Soccar) get pushed up. They should stay in the same place they currently are, and the menu from the active <li> should simply flow over the other inactive <li> elements.

I tried changing the first-tier elements from <li> to <span> which solved the issue of the top options bringing their horizontal siblings along for the ride, but doesn't solve the issue of the bottom elements pushing their upper siblings when they expand.

I hope this makes sense.

Upvotes: 1

Views: 103

Answers (1)

Saurav Rastogi
Saurav Rastogi

Reputation: 9731

Use CSS Positioning for this and instead of overflow use flexbox, like:

.dot-overflow {
  position: relative;
}

.dot-overflow.active ul {
  position: absolute;
  bottom: 0;
  background: #0F1316;
}

/* Make it a flex container */
ul.specifics {
  display: flex;
  flex-wrap: wrap;
}

Have a look at the working snippet below (use full screen to see it properly):

// handle the specifics dropdowns
var allSpecifics = $('ul.specifics > li');
$(document).on('click', 'ul.specifics > li', function(event) {
  var openThis = ($(this).hasClass('active')) ? false : true;
  allSpecifics.removeClass('active');
  if (openThis)
    $(this).addClass('active');
  else {
    // selected an option
    $(event.target).closest('li[data-value]').addClass('active').siblings().removeClass('active');
  }
}).click(function(event) {
  if (!$(event.target).closest('ul.specifics > li').length || $(event.target).closest('ul.specifics > li.active > ul > li:first-of-type').length) {
    allSpecifics.removeClass('active');
  }
});
.specifics-container {
  position: absolute;
  z-index: 2;
  bottom: 50px;
  left: 0;
  right: 0;
  max-width: 100%;
}

ul.specifics {
  display: flex;
  flex-wrap: wrap;
  position: relative;
  list-style: none;
  padding: 0;
}

ul.specifics > li {
  display: inline-block;
  position: relative;
  box-shadow: 0 0 32px 1px #010;
  /*border-right: 1px ridge rgba(225, 255, 225, 0.165);*/
  padding: 9px 0;
  margin: 0;
  width: 24.5%;
  text-align: center;
  cursor: pointer;
  background: #13141c;
  transition: all 0.40s ease;
  -o-transition: all 0.40s ease;
  -moz-transition: all 0.40s ease;
  -webkit-transition: all 0.40s ease;
}

ul.specifics > li > i {
  display: block;
  position: absolute;
  left: 12px;
  top: 11px;
  font-size: 20px;
  color: rgba(225, 225, 225, 0.3);
}

ul.specifics > li > ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: block;
  width: 100%;
  max-height: 420px;
  background: none;
  text-align: center;
}

ul.specifics > li.active > ul {
  overflow-y: scroll;
}

ul.specifics > li > ul::-webkit-scrollbar {
  /* this is added to the remodal open() function */
  width: 0;
  /* remove scrollbar space */
  background: transparent;
  /* optional: just make scrollbar invisible */
}

ul.specifics > li > ul > li {
  background: none;
  width: 100%;
  margin: 0;
  padding: 0;
  display: block;
  line-height: 0;
  opacity: 0;
  color: #777;
  font-family: 'Play', sans-serif;
  font-size: 22px;
  transition: all 0.40s ease;
  -o-transition: all 0.40s ease;
  -moz-transition: all 0.40s ease;
  -webkit-transition: all 0.40s ease;
}

ul.specifics > li > ul > li:first-of-type {
  font-size: 16px;
  color: #ccc;
}

ul.specifics > li > ul > li.active {
  line-height: normal;
  opacity: 1;
  color: #ddd;
}

ul.specifics > li.active > ul > li {
  line-height: normal;
  opacity: 1;
  padding: 16px 0;
}

ul.specifics > li.active > ul > li:first-of-type {
  padding: 6px 0;
  margin: 0 0 12px 0;
}

ul.specifics > li.active > ul > li.active {
  background: rgba(0, 91, 36, 0.15);
}

ul.specifics > li.active > ul > li:hover {
  color: #ddd;
  background: rgba(0, 31, 96, 0.1);
}

ul.specifics > li.active > ul > li:first-of-type:hover {
  background: none;
}

ul.specifics > li.active > i {
  opacity: 0;
}

ul.specifics > li:last-of-type {
  /*border-right: none;*/
}

ul.specifics > li:hover {
  background: #1b1d24;
}

ul.specifics > li.active > ul > li:first-of-type:before {
  font-family: Arial, "Helvetica CY", "Nimbus Sans L", sans-serif !important;
  font-size: 24px;
  position: absolute;
  top: 6px;
  right: 0;
  display: block;
  width: 35px;
  content: "\00d7";
  text-align: center;
  transition: all 0.40s ease;
  -o-transition: all 0.40s ease;
  -moz-transition: all 0.40s ease;
  -webkit-transition: all 0.40s ease;
}

ul.specifics > li.active > ul > li:first-of-type:hover:before {
  color: red;
}


@media (max-width: 991px) {
  ul.specifics {
    background: #13141c;
  }
  ul.specifics > li {
    width: 49.5%;
  }
}

.dot-overflow {
  position: relative;
}

.dot-overflow.active ul {
  position: absolute;
  bottom: 0;
  background: #0F1316;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="specifics-container">
  <ul class="specifics">
    <li class="dot-overflow">
      <i class="fa fa-wifi"></i>
      <ul>
        <li>Filter by Hosting</li>
        <li data-value="ghost" class="active">Ghost Host</li>
        <li data-value="they">They Host</li>
        <li data-value="you">You Host</li>
        <li data-value="server">Server</li>
      </ul>
    </li>
    <li class="dot-overflow">
      <i class="fa fa-gear"></i>
      <ul>
        <li>Filter by Game Mode</li>
        <li data-value="1" class="active">Soccar</li>
        <li data-value="2">Snowday</li>
        <li data-value="3">Hoops</li>
      </ul>
    </li>
    <li class="dot-overflow">
      <i class="fa fa-map"></i>
      <ul>
        <li>Filter by Map</li>
        <li data-value="248" class="active">Manfield</li>
        <li data-value="1337" i>Wasteland</li>
        <li data-value="421">Utopia</li>
        <li data-value="121">Stadium</li>
      </ul>
    </li>
    <li class="dot-overflow">
      <i class="fa fa-ticket"></i>
      <ul>
        <li>Filter by League</li>
        <li data-value="100" class="active">$100</li>
        <li data-value="50">$50</li>
        <li data-value="20">$20</li>
        <li data-value="5">$5</li>
        <li data-value="1">$1</li>
        <li data-value=".5">50¢</li>
        <li data-value="0">Free</li>
      </ul>
    </li>
  </ul>
</div>

Hope this helps!

Upvotes: 1

Related Questions