Garuuk Garuuk - 5 months ago 9
HTML Question

My unordered list disappears when I add overflow-y

I was messing around with overflows and I noticed that my list disappeared when I created the top-wrapper for my code.



body {
font-size: 36px;
overflow: hidden;
font-family: "Arial";
}
ul {
list-style-type: none;
}
li {
transition: color 0.2s ease;
}
li:hover {
color: red;
}
h1,h2 {
color: lightcoral;
}
.left,.right {
position: relative;
text-align: center;
display: inline-block;
width: 50%;
height: 100vh;
}
.right {
float: right;
background-color: lightgreen;
}
.left {
float: left;
background-color: lightblue;
}
.top-wrapper {
width: 100%;
}
.top-menu {
background-color: darkgreen;
height: 30px;
}
.sub-top-l,.sub-top-r {
display: inline-block;
width: 50%;
height: 20px;
font-size: 12px
}
.sub-top-l {
float: left;
background-color: darkblue;
}
.sub-top-r {
float: right;
background-color: darkred;
}
.list-wrap {
overflow-y: auto;
height: 100%;
}

<div class="content-wrapper">
<div class="left">
<h1>Cowabunga</h1>
</div>
<div class="right">
<div class="top-wrapper">
<div class="top-menu">

</div>
<div class="sub-top-l">
test
</div>
<div class="sub-top-r">
test
</div>
</div>
<div class="list-wrap">
<ul>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
</ul>
</div>
</div>
</div>





The only way to get the list to show is to add the display property absolute to the CSS class
.top-wrapper
.

Does anyone know why this is the default behavior? I'm looking for a detailed explanation.

JSFfiddle Demo

Add
position: absolute
to
.top-wrapper
to get it to show.

Answer

I can't write up a great/detailed explanation at the moment, but long story short, it's because of how floats work (they are positioned in the normal flow and then moved out of it in order to float against the furthest edge in their specified direction) and because you haven't cleared the element that is the sibling to the floated elements, the .list-wrap div.

Clearing an element will tell the next element in line (in this case, .list-wrap to move to a new line rather than try to wrap around the floated element.

position: absolute; works because that tells an element to display, absolutely, wherever you tell it to, relative to the nearest position: relative; ancestor (if there is one).

Here's a minimal demo with that element cleared:

.right {
    width: 50%;
    height: 100vh;
    background-color: lightgreen;
}
.sub-top-l, .sub-top-r {
    width: 50%;
}
.sub-top-l {
    float: left;
}
.sub-top-r {
    float: right;
}
.list-wrap {
    overflow-y: auto;
    clear: left;
}
<div class="content-wrapper">
    <div class="right">
        <div class="top-wrapper">
            <div class="sub-top-l">
                test
            </div>
            <div class="sub-top-r">
                test
            </div>
        </div>
        <div class="list-wrap">
            <ul>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
            </ul>
        </div>
    </div>
</div>

And here's a demo of your page with that element cleared:

body {
    font-size: 36px;
    overflow: hidden;
    font-family: "Arial";
}
ul {
    list-style-type: none;
}
li {
    transition: color 0.2s ease;
}
li:hover {
    color: red;
}
h1,h2 {
    color: lightcoral;
}
.left,.right {
    position: relative;
    text-align: center;
    display: inline-block;
    width: 50%;
    height: 100vh;
}
.right {
    float: right;
    background-color: lightgreen;
}
.left {
    float: left;
    background-color: lightblue;
}
.top-wrapper {
    width: 100%;
}
.top-menu {
    background-color: darkgreen;
    height: 30px;
}
.sub-top-l,.sub-top-r {
    display: inline-block;
    width: 50%;
    height: 20px;
    font-size: 12px
}
.sub-top-l {
    float: left;
    background-color: darkblue;
}
.sub-top-r {
    float: right;
    background-color: darkred;
}
.list-wrap {
    overflow-y: auto;
    clear: left;
    height: 100%;
}
<div class="content-wrapper">
    <div class="left">
        <h1>Cowabunga</h1>
    </div>
    <div class="right">
        <div class="top-wrapper">
            <div class="top-menu">

            </div>
            <div class="sub-top-l">
                test
            </div>
            <div class="sub-top-r">
                test
            </div>
        </div>
        <div class="list-wrap">
            <ul>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
                <li>test</li>
            </ul>
        </div>
    </div>
</div>