Make height 100% of page? - html

I'm experimenting with Flexbox a bit and I was wondering whether there is a property, such as flex: 1, that allows the height of an element to be 100% of the page height without adding scroll bars to scroll down. If I was to resize it, it would stick and not add scroll bars. I hope you understand. I added a fiddle with height just set at 1000px and I was hoping if any of you guys/girls would know how to set it to be 100% of the page.
https://jsfiddle.net/mL594h73/
HTML:
<div class="wrapper">
<div class="box-1"></div>
<div class="box-2"></div>
</div>
CSS:
.wrapper {
display: flex;
}
.box-1 {
flex: 1;
width: 200px;
height: 1000px;
background-color`enter code here`: #2ABB9B;
}
.box-2 {
flex: 1;
width: 200px;
height: 1000px;
background-color: #16A085;
}

use height:100vh in .wrapper and remove default margin from body
body {
margin: 0
}
.wrapper {
display: flex;
height: 100vh
}
.wrapper>div {
flex: 1;
width: 200px;
}
.box-1 {
background-color: #2ABB9B;
}
.box-2 {
background-color: #16A085;
}
<div class="wrapper">
<div class="box-1"></div>
<div class="box-2"></div>
</div>

Just remove the default margin from the body and add min-height to your parent div wrapper like this:
body {
margin: 0px;
}
.wrapper {
min-height: 100%;
display: flex;
}

Maybe an alternative is to set a ´position:absolute´ to get height:100% working properly. Also you can set display:table for the main container, and display:table-cell to containers inside to fit the height:100%
.wrapper {
display:table;
position:absolute;
width:100%;
height:100%;
}
.box-1 {
display:table-cell;
vertical-align:middle;
text-align:center;
width: 200px;
background-color: #2ABB9B;
}
.box-2 {
display:table-cell;
vertical-align:middle;
text-align:center;
width: 200px;
background-color: #16A085;
}
Example working: https://jsfiddle.net/mL594h73/1/

Related

CSS flex-box, how do I make an item stretch smaller than the content in the cross-axis direction?

I'm trying to make a container with side-by-side divs, one item has a fixed width and the other item has a fixed height. However, the flexible-height div won't shrink below its contents.
.parent {
background: #f00;
display: contents;
}
.container {
background: #0f0;
width: 25vw;
display: flex;
}
.object {
background: #00f;
margin: 10px;
width: 100px;
flex-shrink: 0;
}
.object.flexes-main-axis {
flex-grow: 1;
flex-shrink: 1;
}
.object.sets-cross-axis-size {
height: 75px;
}
.object.shrinks-cross-axis-below-content {
overflow-y: auto;
}
.child {
background: #f0f;
height: 100px;
width: 100px;
}
<div class='parent'>
<div class='container'>
<div id="object1" class='object flexes-main-axis sets-cross-axis-size'></div>
<div id="object2" class='object shrinks-cross-axis-below-content'>
<div class="child"></div>
</div>
</div>
</div>
I'm trying to get object2 to shrink and show a vertical scroll bar when I shrink object1 below 100px. The magenta box represents fixed-height content I can’t shrink, while object1 represents the element I want to control the container’s height.
The blue is hardcoded 75px tall, while the magenta is hardcoded 100px.
As the main .container has no height set it will grow to fit the tallest child. A main .container with a fixed height: ..px would still not make .child shrink. That's Flexbox.
But, if you set the .child to height: 100% and you will see it shrink:
* { outline: 1px dashed } /* for debugging */
.parent {
background: #f00;
display: contents;
}
.container {
background: #0f0;
width: 25vw;
display: flex;
}
.object {
background: #00f;
margin: 10px;
width: 100px;
flex-shrink: 0;
}
.object.flexes-main-axis {
flex-grow: 1;
flex-shrink: 1;
}
.object.sets-cross-axis-size {
height: 75px;
}
.object.shrinks-cross-axis-below-content {
overflow-y: auto;
}
.child {
background: #f0f;
height: 100%; /* Changed from 100px */
width: 100px;
}
<div class='parent'>
<div class='container'>
<div id="object1" class='object flexes-main-axis sets-cross-axis-size'>1</div>
<div id="object2" class='object shrinks-cross-axis-below-content'>
<div class="child">2</div>
</div>
</div>
</div>
So, I figured it out. I needed to add an extra wrapper div between object2 and child with height set to 0. Object2 will scroll to accommodate child overflow, but child's height won't count toward object2's content as far as the flexbox is concerned. Now as you change object1's height below child's height, you'll get a scroll bar in object2.
Also in this version, I made object1 responsive to the viewport width, so you can try it out by resizing the browser window.
.container {
display: flex;
background-color: red;
padding: 10px;
width: 50vw;
}
.sizecontroller {
aspect-ratio: 16 / 9;
background-color: blue;
padding: 10px;
flex-grow: 1;
flex-shrink: 1;
align-self: flex-start;
}
.sizeresponsive {
overflow-y: auto;
background-color: green;
padding: 10px;
flex-grow: 0;
flex-shrink: 0;
}
.sizeeraser {
height: 0;
background-color: purple;
padding: 10px;
}
.sizefixed {
width: 25px;
height: 250px;
background-color: yellow;
padding: 10px;
}
<div class="container">
<div class="sizecontroller"></div>
<div class="sizeresponsive">
<div class="sizeeraser">
<div class="sizefixed"></div>
</div>
</div>
</div>

Content overflowing flex item despite overflow property

I have a pretty simple page setup in the following manner using flexboxes:
The blue div is supposed to make up 25% in height and the violet div 75%. In case there are too many lines in the blue div, it should stay the same size an show a scrollbar. This works for a few lines, but breaks at some point and the blue div overflows and grows into the violet one. I'm new to flexboxes, so I don't really understand why this is happening. Would I be better off not using flexboxes? Thankful for any hints or pointer at this point.
This is the code I use (run in full page):
function lines(noLines) {
var text = "line</br>".repeat(noLines);
document.getElementById("lower").innerHTML = text;
}
* {
box-sizing: border-box;
}
.body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
#static1 {
height: 30px;
width: 100%;
background-color: red;
}
#static2 {
height: 40px;
width: 100%;
background-color: orange;
}
#content {
display: flex;
flex: 1;
}
#left {
width: 40%;
background-color: yellow;
}
#right {
width: 60%;
display: flex;
flex-direction: column;
}
#upper {
flex: 3 0;
background-color: violet;
}
#lower {
flex: 1;
background-color: blue;
overflow: auto;
}
<div class="body">
<div id="static1">Some static div</div>
<div id="static2">Another static div. Flexbox below fills rest of remaining screen.</div>
<div id="content">
<div id="left">
Left part, fixed width in percentage.</br>
Click to enter lines into the bottom right:</br>
<button onclick=lines(20)>Few Lines</button>
<button onclick=lines(200)>Many Lines</button>
</div>
<div id="right">
<div id="upper">Flexbox with flex=3.</div>
<div id="lower">Flexbox with flex=1.</div>
</div>
</div>
</div>
For the overflow property to work properly, the container needs an actual height or max-height. Flex heights (you have flex: 1 on .content) won't cut it.
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. ~ MDN
Since you already know the height of the primary container (100vh) and the first two rows (30px and 40px), the rest is simple using the calc() function.
function lines(noLines) {
var text = "line</br>".repeat(noLines);
document.getElementById("lower").innerHTML = text;
}
.body {
display: flex;
flex-direction: column;
height: 100vh; /* adjustment */
}
#static1 {
flex-shrink: 0; /* disable shrinking */
height: 30px;
/* width: 100%; */
background-color: red;
}
#static2 {
flex-shrink: 0; /* disable shrinking */
height: 40px;
/* width: 100%; */
background-color: orange;
}
#content {
height: calc(100vh - 70px); /* new */
display: flex;
/* flex: 1; */ /* may work in some browsers, but not reliable */
}
#left {
width: 40%;
background-color: yellow;
}
#right {
width: 60%;
display: flex;
flex-direction: column;
}
#upper {
flex: 3 0;
background-color: violet;
}
#lower {
flex: 1;
background-color: aqua; /* adjusted for illustration */
overflow: auto;
}
body {
margin: 0; /* new; override browser default */
}
* {
box-sizing: border-box;
}
<div class="body">
<div id="static1">Some static div</div>
<div id="static2">Another static div. Flexbox below fills rest of remaining screen.</div>
<div id="content">
<div id="left">
Left part, fixed width in percentage.<br> Click to enter lines into the bottom right:<br>
<button onclick=lines(20)>Few Lines</button>
<button onclick=lines(200)>Many Lines</button>
</div>
<div id="right">
<div id="upper">Flexbox with flex=3.</div>
<div id="lower">Flexbox with flex=1.</div>
</div>
</div>
</div>
jsFiddle demo
I hope this is what you mean, but If I'm wrong, apologies. The problem I can see lies in the way you are using flex: 1 & flex: 3 to define the proportions of the right column, without specifying to what height their parent container has, i.e. #right has no height, so the box can always expand as it gets more filled with content.
Please try this, I hope this works and if I can answer anything else, just ask please.
The only thing I changed was your CSS and added max-height: calc(100vh - 70px); to the #right div. And changed overflow: auto; to overflow-y: scroll;
* {
box-sizing: border-box;
}
.body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
#static1 {
height: 30px;
width: 100%;
background-color: red;
}
#static2 {
height: 40px;
width: 100%;
background-color: orange;
}
#content {
display: flex;
flex: 1;
}
#left {
width: 40%;
background-color: yellow;
}
#right {
width: 60%;
display: flex;
flex-direction: column;
max-height: calc(100vh - 70px);
}
#upper {
flex: 3;
height: 75%;
background-color: violet;
}
#lower {
flex: 1;
height: 25%;
background-color: blue;
overflow-y: scroll;
}
Change the top part of CSS to this:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

Flex cuts off child items

I have the following code structure
.parent {
display: flex;
flex-direction: column;
}
.img {
width: 100%
}
.content {
flex: 1;
overflow-y: scroll;
}
.container {
border: 1px solid;
display: flex;
flex-direction:column;
margin:20px;
}
<div class="parent">
<img src="https://www.everythingcarers.org.au/media/1982/sample.jpg"/>
<div class="content">
</div>
<div class="footer">
<div class="container">
<div><button>Button1</button><div>
<div><button>Button2</button><div>
</div>
</div>
</div>
What I want is the footer to occupy its original width and height(height: 144px) , and make the content scrollable based on the available space according to screen resolution.Currently, the footer is getting cut off on some screens. I've tried changing the flex values for content and footer, but it doesn't work.Thanks
If you want to limit your parent to the height of the screen so the footer is always visible, you need to set a height of 100% on your div (and body and html) and also move the image inside your content container (or have a seperate one that will scroll if it too large for the screen)
body,
html {
margin: 0;
height: 100%;
}
.parent {
height: 100%;
display: flex;
flex-direction: column;
}
img {
display:block;
width: 100%
}
.content {
flex: 1;
overflow-y: scroll;
}
.container {
border: 1px solid;
display: flex;
flex-direction: column;
margin: 20px;
}
<div class="parent">
<div class="content">
<img src="https://www.everythingcarers.org.au/media/1982/sample.jpg" />
</div>
<div class="footer">
<div class="container">
<div><button> Button1 </button></div>
<div><button> Button2 </button></div>
</div>
</div>
</div>
I think setting your parent height to 100vh and giving your footer a fixed height should fix it:
https://codepen.io/chrishalley/pen/zbwRMw
body {
margin: 0;
}
.parent {
display:flex;
flex-direction:column;
background-color: orangered;
height: 100vh;
}
.content {
flex: 1;
overflow-y: scroll;
}
img {
width: 300px;
}
.footer {
height: 144px;
}

How to get the content of the bottom element of a flexbox to be 100% height its container

If I make a flexbox with 2 children and column flow and set the second child to flex-grow 1 the second child expands to fill the flexbox. This works
(ps: Didn't want to clutter the example with safari support so use Chrome or Firefox)
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
background-color: blue;
flex: 1 0 auto;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">bottom (blue)</div>
</div>
But, if I then put a child #inside inside #bottom and set its height to 100% it doesn't increase its height to match even though the flexbox has stretched #bottom.
added css
#inside {
background-color: green;
height: 100%;
}
html
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside</div> <!- added ->
</div>
</div>
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
background-color: blue;
flex: 1 0 auto;
}
#inside {
background-color: green;
height: 100%;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside (green)</div>
</div>
</div>
So I add a height: 100% to #bottom but now bottom is as big as #outer instead of the flex stretched size.
#bottom {
background-color: blue;
flex: 1 0 auto;
height: 100%; /* added */
}
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
background-color: blue;
flex: 1 0 auto;
height: 100%;
}
#inside {
background-color: green;
height: 100%;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside (green) (would not scroll if working)</div>
</div>
</div>
How do I get #bottom to stretch to fit the flexbox and also get a the child #inside to be 100% height of its container #bottom?
Flex has a quirk where you need to set the height to 0.
Change the #bottom rule's height property to this height: 0;
For the inside to work I changed it to "position: absolute" and as well added a position:relative to the bottom
Update
If you don't want to use absolute position, you can set these 2 css rules like this:
(Note though, that this propagates the original issue if a new inner div is used like the first one)
#bottom {
position: relative;
background-color: blue;
flex: 1 0 auto;
height: 0;
display: flex;
}
#inside {
background-color: green;
flex: 1 0 auto;
}
Sample using "position: absolute"
* {
box-sizing: border-box;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
color: white;
}
#outer {
display: flex;
flex-flow: column;
height: 100%;
}
#top {
background-color: red;
}
#bottom {
position: relative;
background-color: blue;
flex: 1 0 auto;
height: 0;
}
#inside {
background-color: green;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
<div id="outer">
<div id="top">top</div>
<div id="bottom">
<div id="inside">inside (would not scroll if working)</div>
</div>
</div>
How do I get #bottom to stretch to fit the flexbox and also get a the child #inside to be 100% height of its container #bottom?
Just add two lines of code to the CSS.
CSS
#bottom {
background-color: blue;
flex: 1 0 auto;
display: flex; /* NEW */
}
#inside {
flex: 1; /* NEW */
background-color: green;
}
DEMO: http://jsfiddle.net/wf2L8dse/
Here's what's happening:
You have a flex container (#outer) with two flex items (#top and #bottom).
#outer is in column alignment.
#bottom has flex: 1 (i.e., flex-grow: 1), so it occupies all available height in the container.
A new element (#inside) is made a child of #bottom and must occupy the same height as parent.
Solution:
Make #bottom a (nested) flexbox. This activates default flex rules.
One such rule is align-items: stretch, which tells flex items (#inside) to stretch the full height of their container. (Height, in this case, because the flex-direction is row, by default.)
Then apply flex: 1 (or flex-grow: 1) to #inside, so it expands the full width of the container.
Addressing the height: 100% issue
I'm not sure there's anything wrong with your code. You have applied height: 100% to #inside and, as required by the spec when using percentage heights, specified a height for all parent elements including body and the root element (html).
The only thing you may want to consider (to remove the vertical scrollbar on the browser window), is applying overflow: hidden to body.
DEMO: http://jsfiddle.net/wf2L8dse/1/

Expand div vertically to available space

I have a simple page with 3 div on top of each other but I cannot get the middle content div to use all the vertical space available on screen. Note that top and bottom height cannot be fixed and that it has to be compatible with IE9.
HTML
<div class="container">
<div>Top</div>
<div class="content">Middle</div>
<div>Bottom</div>
</div>
CSS
.container {
background-color: #dddddd;
}
.content {
height: 100%;
min-height: 100%;
}
I also put that on Fiddle to demonstrate the issue: http://jsfiddle.net/quaxkq40/
Thanks.
If flexible box layout is an option, it can be done simply by displaying the container as a flex box and the nested <div>s as flex items:
html, body {
height: 100%;
margin: 0;
}
.container {
background-color: #dddddd;
height: 100%;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
<div class="container">
<div>Top</div>
<div class="content">Middle</div>
<div>Bottom</div>
</div>
Note: Vendor prefixes omitted due to brevity.
Otherwise, you'll probably end up with CSS tables:
html, body {
height: 100%;
margin: 0;
}
.container {
background-color: #dddddd;
display: table;
height: 100%;
}
.container > div {
display: table-row;
}
.content {
height: 100%;
}
<div class="container">
<div>Top</div>
<div class="content">Middle</div>
<div>Bottom</div>
</div>
Each of the above methods has its own pros/cons, choose one that meets the requirements with care.
You could display the div's inside .container as table rows.
body, html {
height: 100%;
}
.container {
background-color: #dddddd;
display: table;
height: 100%;
width: 100%;
}
.container>div {
display: table-row;
}
.content {
height: 100%;
min-height: 100%;
background: lightblue;
}
UPDATED FIDDLE