简体   繁体   中英

Overflow-y not working with fr

I have the next html structure:

<div id="container">
  <header></header>
  <div id="content">
     <div class="something"></div>
     <div class="lateralInfo">
        <div class="menu"></div>
        <div class="data">
             // A lot of data 
        </div>          
     </div>      
  </div>
  <footer></footer>
</div>

And using the next css style:

*{
    margin: 0;
    padding: 0;
    border:0;
    box-sizing: border-box;
}

 #container{
    position: absolute;
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-rows: 50px 1fr 10px;
    align-items:stretch;
    justify-items:stretch;
}
#content{
    display: grid;
    grid-template-columns: 1fr 300px;
    background-color:rgb(128, 126, 126);
}
.something{
    position: relative;
    overflow-y:hidden;
    overflow-x:hidden;
    padding:10px;
    margin:30px 0px;
} 
.lateralInfo{
    background-color:#eaeaea;
    box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5);
    position: relative;
    height: 100%;
    align-content:flex-start;
    display:grid;
    grid-template-rows: auto 1fr;
}
  .data{
     padding:10px;
     display:grid;
     grid-gap:10px;
     align-content: flex-start;
     overflow-y: scroll;
}

This give me the next output: 在此处输入图片说明


The problem comes when I insert a lot of divs in .data , where I writed HERE in the image.

.data{
  overflow-y: scroll;
}

overflow-y is not working. I checked some post where they say that it needs height specified at the parent to work but :

Im using fr in all the parents of .data what means that they need to use al the free space, but not more. So the height is specified. Then why is not working?


Actually im using:

var contentHeight = $("#content").innerHeight();
$(".lateralInfo").css("height", contentHeight);  

to set a height when the site loads to adjust to each screen, But this is what fr should be doing in css.

So why is this happening since there is a fr height on all parents? And how to solve this with only css??

JSFiddle here

Problem

You are using 1fr , and that can't work with overflow .

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

Documentation about overflow : https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

The fr unit is a fractional, flexible unit that distributes the available space. It doesn't define an actual height .


Solutions

  1. Use JavaScript

Your JavaScript solution is a good way to correct that “unwanted” behaviour:

 $(".lateralInfo").css("height", $("#content").innerHeight()); 
 * { margin: 0; padding: 0; border: 0; box-sizing: border-box; } #container { position: absolute; width: 100%; height: 100%; display: grid; grid-template-rows: 50px 1fr 10px; align-items: stretch; justify-items: stretch; } #content { display: grid; grid-template-columns: 1fr 300px; background-color: rgb(128, 126, 126); } .something { position: relative; overflow-y: hidden; overflow-x: hidden; padding: 10px; margin: 30px 0px; background-color: purple; } .lateralInfo { background-color: #eaeaea; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5); position: relative; height: 0px; align-content: flex-start; display: grid; grid-template-rows: auto 1fr; } .data { padding: 10px; display: grid; grid-gap: 10px; align-content: flex-start; overflow-y: scroll; } .server { padding: 10px; background-color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"> <header></header> <div id="content"> <div class="something"></div> <div class="lateralInfo"> <div class="menu"></div> <div class="data"> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> </div> </div> </div> <!--/div REMOVED --> <footer></footer> </div> 

(Note that you had an extra </div> at the end of your HTML)

⋅⋅⋅

  1. Use of CSS absolute or fixed positioning

If you want to avoid the use of JavaScript, you may want to use absolute or fixed positioning in your CSS:

 * { margin: 0; padding: 0; border: 0; box-sizing: border-box; } #container { position: relative; width: 100%; height: 100%; } header { position: fixed; height: 50px; top: 0; } footer { position: fixed; height: 10px; bottom: 0; } #content { position: fixed; top: 50px; bottom: 10px; width: 100%; background-color: rgb(128, 126, 126); } .something { position: fixed; top: 50px; bottom: 10px; left: 0; right: 300px; overflow-y: hidden; overflow-x: hidden; margin: 30px 0px; background-color: purple; padding: 10px; } .lateralInfo { position: fixed; right: 0; width: 300px; top: 50px; bottom: 10px; background-color: #eaeaea; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5); align-content: flex-start; display: grid; grid-template-rows: auto 1fr; overflow-y: scroll; } .data { padding: 10px; display: grid; grid-gap: 10px; align-content: flex-start; } .server { padding: 10px; background-color: red; } 
 <div id="container"> <header></header> <div id="content"> <div class="something"></div> <div class="lateralInfo"> <div class="menu"></div> <div class="data"> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> <div class="server"></div> </div> </div> </div> <footer></footer> </div> 


Hope it helps

The CSS solution by Takit Isy will also scroll the div class="menu" .

I think when you want to solve that problem, you have to change the html code a little bit.

Starting from your original code, wrap a new div style="position:relative" around your div class="data" and add this to the CSS of .data :

position:absolute;
height:100%;
width:100%;

Explanation:

Because of fr the last child node of lateralInfo will get some sort of min-height. But it won't get a max-height and you can't assign that manually, because it would be a formular. That's why your old solution not worked.

So two problems had to be solved: don't let the last child element of lateralInfo grow to big and give the scrollable element some sort of max-height. Wraping the new div around div class="data" and give div class="data" position:absolute solves the first problem (because the new div won't grow with it's absolute positioned content). The second problem is solved by the height:100% (this works because we have the new parent element with the desired height).

Full Code:

<div id="container">
  <header></header>
  <div id="content">
     <div class="something"></div>
     <div class="lateralInfo">
        <div class="menu">menu doesn't scroll away</div>
        <div style="position:relative">
           <div class="data">
              // A lot of data 
           </div>          
        </div>
     </div>      
  </div>
  <footer></footer>
</div>

CSS:

*{
    margin: 0;
    padding: 0;
    border:0;
    box-sizing: border-box;
}

 #container{
    position: absolute;
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-rows: 50px 1fr 10px;
    align-items:stretch;
    justify-items:stretch;
}
#content{
    display: grid;
    grid-template-columns: 1fr 300px;
    background-color:rgb(128, 126, 126);
}
.something{
    position: relative;
    overflow-y:hidden;
    overflow-x:hidden;
    padding:10px;
    margin:30px 0px;
} 
.lateralInfo{
    background-color:#eaeaea;
    box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5);
    position: relative;
    height: 100%;
    align-content:flex-start;
    display:grid;
    grid-template-rows: auto 1fr;
}
.data{
     position:absolute;
     height:100%;
     width:100%;
     padding:10px;
     display:grid;
     grid-gap:10px;
     align-content: flex-start;
     overflow-y: scroll;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM