Garuuk Garuuk - 5 months ago 16
CSS Question

ul list disappears with overflow-y

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style media="screen">
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;
}

.list-wrap{
overflow-y: auto;
height:100%;
}

.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;
}

</style>
</head>
<body>
<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>
</body>
</html>


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.

the fiddle https://jsfiddle.net/u8yqecdm/

Add absolute property 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>

Comments