I have a simple layout which I took from MDN's flexbox page. It has a header and a main content area.
<header>header</header>
<div id='main'>
<article>article</article>
<aside>aside</aside>
</div>
I would like to have the main content area extend to the bottom of the viewport or further if it needs to accommodate its children. I tried fiddling with flexbox but I still can't specify that I want it to take up all space vertically like I can horizontally.
The only two options I can think of are:
A) Javascript to calculate the required height
B) Tiling a background image on the body to make it appear as though the content area is extended all the way down
Can anyone think of an alternatives to fill up the viewport and also contain children if the children extend past the bottom of n the screen?
https://jsfiddle.net/1cpcsvjr/5/
** Update ** I amended my jsfiddle with more content in the article sub element. The content will bleed out of the flex container.
#main
{
height: 100vh;
}
100vh means 100% of the viewport height, you can change this value if you need to.
you can set height to html an body to fill entitre window and use flex from body as well.
body {
font: 24px Helvetica;
background: #999999;
display:flex;
flex-flow: column;
}
html, body {
height:100%;
margin:0;
}
#main {
margin: 0px;
padding: 0px;
display: flex;
flex-flow: row;
flex:1;/* fills entire space avalaible (or share evenly if sibblings)*/
}
#main > article {
margin: 4px;
padding: 5px;
border: 1px solid #cccc33;
background: #dddd88;
flex: 3 1 60%;
order: 2;
}
#main > nav {
margin: 4px;
padding: 5px;
border: 1px solid #8888bb;
background: #ccccff;
flex: 1 6 20%;
order: 1;
}
header {
display: block;
margin: 4px;
padding: 5px;
min-height: 100px;
border: 1px solid #eebb55;
border-radius: 7pt;
background: #ffeebb;
}
<header>header</header>
<div id='main'>
<article>article</article>
<aside>aside</aside>
</div>
https://jsfiddle.net/1cpcsvjr/2/
Flexbox solution.
You have to set the html & body elements to 100% height.
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
font: 24px Helvetica;
background: #999999;
min-height: 100%;
display: flex;
flex-direction: column;
}
#main {
margin: 0px;
padding: 0px;
flex: 1;
background: pink;
display: flex;
}
#main > article {
margin: 4px;
padding: 5px;
border: 1px solid #cccc33;
background: #dddd88;
flex: 3 1 60%;
order: 2;
}
#main > nav {
margin: 4px;
padding: 5px;
border: 1px solid #8888bb;
background: #ccccff;
flex: 1 6 20%;
order: 1;
}
header {
display: block;
margin: 4px;
padding: 5px;
min-height: 100px;
border: 1px solid #eebb55;
border-radius: 7pt;
background: #ffeebb;
}
<header>header</header>
<div id='main'>
<article>article</article>
<aside>aside</aside>
</div>
Related
The header has a dynamic height, how can the main take up the rest of the page height?
header {
margin: auto;
width: 50%;
height: auto;
}
h1 {
text-align: center;
}
main {
background-color: aqua;
}
<header>
<h1>Add new task in your list</h1>
<app-add-to-do-list></app-add-to-do-list>
</header>
<main>
</main>
To do this, you can use the vh property, which is viewport height, in the width and height of each one and define a height for each of them, example:
header{
height: 30vh;
}
main{
height: 70vh;
}
Also, you can add an overflow-scroll as well.
When you add height auto it only stretches to the size of it's content. If you would want the container to take some of the free space you have to add min-height: 20rem;
Here I have created codepen with examples:
https://codepen.io/brtskr-the-animator/pen/JjMQRbd
body{
min-height: 20rem;
background: #222;
color: white;
}
*{
margin: 0 0 2rem 0;
}
header{
height: auto;
border: 1px solid green;
}
.ex1{
height: 5rem;
border: 1px solid yellow;
}
.ex2{
min-height: 5rem;
border: 1px solid blue;
font-size: 6rem;
}
.ex3{
height: auto;
border: 1px solid pink;
font-size: 10rem;
}
In the example below, is there a way to override the size of the h1 tags so they do not overflow (I do not want to just hide the overflow).
We really want the 'strictContainer' to be 100px of height and not bigger. I searched for an analoguous to size:auto but found nothing.
h1 {
height: 80px; border:solid black
}
.strictContainer {
height: 150px; border:solid gold
}
<div class="strictContainer">
<h1>Hello
</h1>
<h1>Hello
</h1>
</div>
Assuming you cannot modify the original CSS. You can override the size of h1 using a new rule make it have more precedence.
One way to fit both the h1 tags in the container is to make them have equal heights:
/* original rules */
h1 {
height: 80px;
border: 2px solid black
}
.strictContainer {
height: 150px;
border: 2px solid gold;
}
/* overrides */
.strictContainer>h1 {
/* need to override default margins */
margin: auto 0;
/* make them have equal heights*/
height: 50%;
box-sizing: border-box;
/* uncomment following to have auto height */
/*height: auto;*/
}
<div class="strictContainer">
<h1>Hello</h1>
<h1>Hello</h1>
</div>
User agents(browsers) put default styles on some html elements. For example, Chrome has following style on h1 tags by default:
h1 {
display: block;
font-size: 2em;
margin-block-start: 0.67em;
margin-block-end: 0.67em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
}
In order to fit both the tags we need to override margins. I used margin: auto 0;. This means vertical margin is auto and horizontal margin is 0.
We've used box-sizing: border-box; to make borders part of the dimensions. Otherwise we would have to calculate height using height: calc(50% - 4px);
solution 2 You can make the container a flexbox:
/* original rules */
h1 {
height: 80px;
border: 2px solid black
}
.strictContainer {
height: 150px;
border: 2px solid gold;
}
/* overrides */
.strictContainer {
display: flex;
flex-direction: column;
justify-content: space-around; /* play with this */
}
.strictContainer>h1 {
/* need to override default margins */
margin: 0;
height: auto;
flex: 0 0 auto;
/* for 50% height use this */
/*flex: 1 0 auto;*/
}
<div class="strictContainer">
<h1>Hello</h1>
<h1>Hello</h1>
</div>
Note: In your code snippet you've used 150px height for the container so I've used the same. If your issue is with margins then you can use
You can use overflow: hidden to hide any content that may overflow, but I think you are asking for height: min-content.
.container {
width: 10em;
padding: 0.5em;
height: min-content;
background: peachpuff;
}
.content {
height: 5em;
border: 1px solid red;
}
<div class="container">
<div class="content">Hello this is some content la la la la la</div>
</div>
Overflow hidden is used to hide element that overflows
overflow:hidden
/**
other values are visible(default),scroll and auto
ww3schools.com/css/css_overflow.asp
**/
/*
you can remove the default setting
for box-sizing you can check out the following link
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
*/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/*
I highly recommend you to use % or vh/vw instead of px
It makes your website responsive
*/
h1 {
height: 50%;
border: 2px solid black;
}
.strictContainer {
height: 150px;
border: 2px solid gold;
}
<div class="strictContainer">
<h1>Hello</h1>
<h1>Hello</h1>
</div>
At the top level of my website layout are 4 div tags.
The first one is a full width header section, with css:
#header {
margin-top: 0px;
height: 70px;
border: 4px double rgb(255,255,255);
border-radius: 20px;
background: rgb(88,150,183) no-repeat fixed left top;
padding: 0px;
}
At the bottom is a full width footer:
#footer {
clear: both;
margin: 0px;
color:#cdcdcd;
padding: 10px;
text-align: center;
border: 4px double rgb(88,150,183);
border-radius: 20px;
}
On the left is my main menu section:
#categories {
float:left;
width:150px;
border: 4px double rgb(88,150,183);
border-radius: 20px;
}
All of those 3 elements work fine. They're in the right place and that doesn't change whatever screen resolution the user has on their monitor, or whether they view it on not maximum screen size.
My problem is with the main element of the page - where all the interesting stuff is. It's directly to the right of the menu div - or rather, it should be. My css is:
#main {
float:right;
min-height: 440px;
width: 80%;
margin-bottom: 20px;
padding:20px;
border: 4px double rgb(88,150,183);
border-radius: 20px;
}
width 80% works OK for most of my users, but for those with less resolution, the main element shifts below the menu, which is ghastly.
What I would ideally like is for the width set in the css #main to be something like (100% - 170px), thus leaving a nice margin between the menu and the main bit at all times and never pushing it below the menu. However, css standards don't fulfil that desire yet!
Could someone suggest how I amend my css to give me a nice clean page that's clean for all my users? Or do I need to go back to setting out my page using tables?
Using CSS3 flex
* { box-sizing: border-box; margin: 0; }
#parent{
display: flex;
}
#aside{
width: 170px; /* You, be fixed to 170 */
background: #1CEA6E;
padding: 24px;
}
#main{
flex: 1; /* You... fill the remaining space */
background: #C0FFEE;
padding: 24px;
}
<div id="parent">
<div id="aside">Aside</div>
<div id="main">Main</div>
</div>
Using CSS3 calc
width: calc(100% - 170px);
Example:
* { box-sizing: border-box; margin: 0; }
#aside {
background: #1CEA6E;
width: 170px;
float: left;
padding: 24px;
}
#main {
background: #C0FFEE;
width: calc(100% - 170px);
float: left;
padding: 24px;
}
<div id="aside">Aside</div>
<div id="main">Main</div>
Using float: left; and overflow
* { box-sizing: border-box; margin: 0; }
#aside{
width: 170px; /* You, be fixed to 170 */
float: left; /* and floated to the left */
padding: 24px;
background: #1CEA6E;
}
#main {
background: #C0FFEE;
padding: 24px;
overflow: auto; /* don't collapse spaces */
/* or you could use a .clearfix class (Google for it) */
}
<div id="aside">Aside</div>
<div id="main">Main</div>
Using style display: table;
* { box-sizing: border-box; margin: 0; }
#parent{
display: table;
border-collapse: collapse;
width: 100%;
}
#parent > div {
display: table-cell;
}
#aside{
width: 170px; /* You, be fixed to 170 */
background: #1CEA6E;
padding: 24px;
}
#main{
background: #C0FFEE;
padding: 24px;
}
<div id="parent">
<div id="aside">Aside</div>
<div id="main">Main</div>
</div>
Is this what you are looking for? You don't need any css3
Dont need any css3
.wrapper {
width: 800px;
height: 800px;
background-color: blue;
}
.content {
width: auto;
height: 100%;
background-color: yellow;
}
.menu {
width: 170px;
height: 100%;
float: left;
background-color: red;
}
<div class="wrapper">
<div class="menu">Menu</div>
<div class="content">
Aside
</div>
</div>
You can use 'calc' function supported by all modern browsers and IE9+, or switch to flexbox (supported by IE11+)
See this pen: https://codepen.io/neutrico/pen/MyXmxa
width: calc(100% - 170px);
Keep in mind that all borders matter unless you set 'box-sizing' to 'border-box' (or just remove these borders and apply them on child elements).
I have a question, I want to have my window split vertically
-----------
|Div 1 |D2|
| | |
-----------
#D2{
position: fixed;
top: 0;
right: 0;
height: 100vh
}
Here's the catch: D2 has an image, that scales proportionally, so the width is depended on the height.
Currently Div 1 is taking the full width (100%) and I don't know how to get it to do: 100vw-(#D2[val])vw
Flex ? play with this snippet at http://codepen.io/gcyrillus/pen/VaaaRK or run it below here.
If you think flex still too much up to date, then you can use display:table; http://codepen.io/gcyrillus/pen/WwwGXr
/* 101 */
body {
display: flex;
margin: 0;
}
#one {
flex: 1;
}
img {
display: block;
height: 100vh
}
/* extra */
body {
background: #F4BB2D
}
#one {
display: flex;
align-items: center;
justify-content: center;
text-align:right;
color: #89870A;
font-size: 7vw;
text-shadow: 1px 1px black, -1px -1px 1px gray
}
img {
box-shadow: 0 0 5px;
}
<div id="one">
Click Full Page <br/> Or Close
</div>
<div id="two">
<img src="http://lorempixel.com/200/500/nature/6" />
</div>
added some extra terrestrial words to try break it pushing D2 under
/* 101 */
body {
display: flex;
margin: 0;
}
#one {
flex: 1;
}
img {
display: block;
height: 100vh
}
/* extra */
body {
background: #F4BB2D
}
#one {
display: flex;
align-items: center;
justify-content: center;
text-align:right;
color: #89870A;
font-size: 7vw;
text-shadow: 1px 1px black, -1px -1px 1px gray
}
img {
box-shadow: 0 0 5px;
}
<div id="one">
<blocquote>ClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrCloseClickFullPageOrClose<br/>
<cite> Zi stutterer that came from mars </cite></blockquote>
</div>
<div id="two">
<img src="http://lorempixel.com/200/500/nature/6" />
</div>
Both the left and right panels have a height of 100%, but since the Header div takes up X amount of space, there is some vertical scrolling in the window that I want to get rid of.
How can I remove that vertical scrolling?
JSFiddle: http://jsfiddle.net/G7unG/1/
CSS and HTML
html, body{
height: 100%;
margin: 0;
}
.header{
background: #333;
padding: 15px;
text-align:center;
font-size: 18px;
font-family: sans-serif;
color: #FFF;
}
.leftpanel, .rightpanel{
height: 100%;
}
.leftpanel{
float: left;
width: 70%;
background: #CCC;
}
.rightpanel{
float: left;
width: 30%;
background: #666;
}
<div class="header">Header</div>
<div class="leftpanel">Left Panel</div>
<div class="rightpanel">Right Panel</div>
<div class="clearfix"></div>
Here's a modern solution using flexbox. Regardless of the height of the header the rest of the elements will stretch vertically to fill the remaining space. Here's the fiddle: http://jsfiddle.net/mggLY/1/.
HTML:
<div id = "wrapper">
<div class="header">Header</div>
<div>
<div class="leftpanel">Left Panel</div>
<div class="rightpanel">Right Panel</div>
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
border: 0;
}
html, body {
height: 100%;
}
.header{
background: #333;
padding: 15px;
text-align:center;
font-size: 18px;
font-family: sans-serif;
color: #fff;
}
.leftpanel{
background: #CCC;
}
.rightpanel{
background: #666;
}
#wrapper {
height: 100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
outline: 1px solid red;
}
#wrapper > .header {
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
}
#wrapper > .header + div {
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
#wrapper > .header + div > div:first-of-type {
-webkit-flex: 7 0 0;
flex: 7 0 0;
}
#wrapper > .header + div > div:last-of-type {
-webkit-flex: 3 0 0;
flex: 3 0 0;
}
You can use absolute positioning if you want to have it 100% height always. And then use scroll bars if required inside the leftpanel or the rightpanel.
Example: http://jsfiddle.net/G7unG/2/
html, body{
height: 100%;
margin: 0;
}
.header{
background: #333;
padding: 15px;
text-align:center;
font-size: 18px;
font-family: sans-serif;
color: #FFF;
height: 22px;
}
.leftpanel, .rightpanel{
top: 52px;
bottom: 0;
position: absolute;
}
.leftpanel{
width: 70%;
left: 0;
background: #CCC;
}
.rightpanel{
width: 30%;
right: 0;
background: #666;
}
Solution 2 - use fixed percentages for height: http://jsfiddle.net/G7unG/4/
html, body{
height: 100%;
margin: 0;
}
.header{
background: #333;
padding: 15px;
text-align:center;
font-size: 18px;
font-family: sans-serif;
color: #FFF;
height: 30%;
box-sizing: border-box;
}
.leftpanel, .rightpanel{
height: 70%;
float: left;
}
.leftpanel{
width: 70%;
left: 0;
background: #CCC;
}
.rightpanel{
width: 30%;
float: right;
background: #666;
}
You could use overflow: hidden; to protect the body to be scrollable.
according to your comment: http://jsfiddle.net/G7unG/9/
Like this: http://jsfiddle.net/G7unG/3/
html, body{
height: 100%;
margin: 0;
overflow:hidden;
}
You could use a "faux columns" type of structure -- adding the background color of your columns as "fixed" elements (they wont scroll with the page) behind your real columns.
<div id="left_faux"></div>
<div id="right_faux"></div>
div#left_faux {
position: fixed;
top:0;
left:0;
right:30%;
bottom:0;
background-color:#CCC;
}
div#right_faux {
position: fixed;
top:0;
left:70%;
right:0;
bottom:0;
background-color:#666;
}
.leftpanel{
float: left;
width: 70%;
}
.rightpanel{
float: left;
width: 30%;
}
This quick example is perhaps overly verbose, for demonstration purposes. I'm sure you can streamline the CSS so there aren't so many redundant definitions.
WORKING EXAMPLE
Use viewports. Browsers now support giving height a percentage of page height. Drop the 100 down to 80 if you've got a header taking up space.
div {
height:100vh;
}