I'm using the following HTML
<div className="App">
<div className="AppMenu">
Menu
</div>
<div className="AppContainer">
Test
</div>
</div>
and this CSS:
.App {
min-height: 100vh !important;
max-height: 100vh !important;
height: 100vh !important;
background-color: red;
}
.AppMenu {
background-color: blue;
position: sticky;
top: 0px;
width: 100%;
font-size: 1.3em;
}
.AppContainer {
background-color: green;
}
how can I set / calc AppContainer size to take all heigh => 100vh-(AppMenu height)
with CSS (or js) ?
You already using the full height of a screen with 100vh. There is no need to use a nuke like !important which nearly always just mask the issue instead of solving it. Also min-height: 100vh; + max-height: 100vh; can be considered as bad coding. In this case you want a definite height of 100vh which is done by height: 100vh;. So you having 3 lines of code where you actually only would need 1.
The issue that you get a scrollbar and the screen is overflowing is caused by the default body margin. The element will be 100vh tall and use the default body amrgin which will cause an document height of more then 100vh. Therefor simply reset the default body amrgin to 0 with: body { margin: 0; }
However with that soultion you will have a potencial overflow issue. So you should either set an overflow rule to the container or use min-height instead.
To have the the AppContainer fill the remaining height there are multiple ways to solve it. The easiest way to solve it would be the sue of a CSS-Grid with grid-template-rows: min-content auto;. That way, the Menu will take up as much space as needed and the remining height will be used be the AppContainer.
body {
margin: 0;
}
.App {
height: 100vh;
background-color: red;
display: grid;
grid-template-rows: min-content auto;
}
.AppMenu {
background-color: blue;
position: sticky;
top: 0px;
font-size: 1.3em;
}
.AppContainer {
background-color: green;
}
<div class="App">
<div class="AppMenu">
Menu
</div>
<div class="AppContainer">
Test
</div>
</div>
Last but not least. for HTML you have to use class not className which would be invalid HTML as this attribute doesnt exist.
These lines make no sense. This can be removed:
max-height: 100vh !important;
height: 100vh !important;
To stretch .AppContainer to the full free height, use rule flex: 1:
.AppContainer {
...
flex: 1;
}
And for the .App, set the flex rules. Like this:
.App {
...
display: flex;
flex-direction: column;
}
Flex has very good browser support.
Do you need such a result?
.App {
min-height: 100vh !important;
background-color: red;
display: flex;
flex-direction: column;
}
.AppMenu {
background-color: blue;
position: sticky;
top: 0px;
width: 100%;
font-size: 1.3em;
}
.AppContainer {
background-color: green;
flex: 1;
}
<div class="App">
<div class="AppMenu">
Menu
</div>
<div class="AppContainer">
Test
</div>
</div>
Related
I'm facing a strange issue that might have link with flexbox misbehaving with max-height, but so far I didn't find any pure css solution.
I made a plunker to summarize the problem. If you resize your window to reduce its height, at some point you should have a scrollbar in the first block, but if you get back to a higher height, even if there is enough space, the scrollbar won't disappear unless you put your mouse over it (which feels very bugy) : https://plnkr.co/edit/VsJ7Aw8qZdSM1iJeL7Bj?p=preview
I have a main container (in flex) containing 2 blocks (also in flex).
The main container has its height set to 100%, allowing it to resize itself following the window size.
Both children have a fixed content and an overflow-y set to auto.
The first child has a max-height in % to let more height to the second child.
The issue seems to come from this max-height rule. If you remove it, then there's no problem, but I need this max-height...
I don't want to use something like:
.max { flex: 1 1 auto; }
.all { flex: 3 1 auto; }
because it would make my first block higher than its content depending on the window size. I want the first block to have at most its content height.
So my question is: Is it an implementation issue in many browsers (maybe all, but I only tested it in Chrome, IE10 and IE11), or is something wrong in my logic ?
Thank you.
UPDATE: I used a fixed height for my content in this example, but in my project it's a list of n elements in it. So I can't really set my max-height with px value.
UPDATE2: I can't use vh in .max max-height property because it takes 100vh as 100% of viewport height (basically your browser window height). But in my context, .main is already in other containers. Those containers have already their heights defined and are smaller than my window height.
/* Styles go here */
html {
height: 100%;
}
body {
height: calc(100% - 16px);
}
.main {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.max,
.all {
display: flex;
flex-direction: column;
width: 100%;
overflow-y: auto;
}
.max {
flex: 0 1 auto;
min-height: 103px;
max-height: 40%;
background-color: green;
}
.all {
flex: 2 1 auto;
min-height: 235px;
background-color: blue;
}
.content {
flex: 0 0 auto;
box-sizing: border-box;
height: 200px;
margin: 5px;
border: 1px dashed black;
background-color: white;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main">
<div class="max">
<div class="content"></div>
</div>
<div class="all">
<div class="content"></div>
</div>
</div>
</body>
</html>
It is a bug, in Chrome, a test in FF and Edge, it works fine.
Since you use full viewport height, change the max-height: 40%; to max-height: 40vh;.
Another way, as in below sample, is to change the 100% in height: 100% to 100vh.
I guess this works better because viewport units like vh is a fixed unit, which percent is not.
Plnkr demo: https://plnkr.co/edit/66W4a2lOI58XLudCmkw9?p=preview
html {
height: 100vh;
}
body {
height: calc(100vh - 16px);
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
}
.max,
.all {
display: flex;
flex-direction: column;
width: 100%;
overflow-y: auto;
}
.max {
flex: 0 1 auto;
min-height: 103px;
max-height: 40%;
background-color: green;
}
.all {
flex: 1 1 auto;
min-height: 235px;
background-color: blue;
}
.content {
flex: 0 0 auto;
box-sizing: border-box;
height: 200px;
margin: 5px;
border: 1px dashed black;
background-color: white;
}
<div class="main">
<div class="max">
<div class="content"></div>
</div>
<div class="all">
<div class="content"></div>
</div>
</div>
Yes it feels buggy. If you increase the height of the window the height of the first box does not get updated unless:
you decrease the height again
"put your mouse over it" (did not quite get your meaning here)
IMHO this is a browser bug.
If you set flex-grow to anything greater 0 for the first box, the height gets updated correctly, if you increase the height of the window (as you would expect) But using flex-grow isn't an option as the box could potentially grow bigger than its content.
Rather than using max-height:40% you should use the exact same height as you use for .content and use flex-grow: 1 as well to circumvent the "browser bug"
As an example, I've made a fiddle:
https://jsfiddle.net/L7mwpzux/3/
How do I make the div .container minimally fill the screen?
So when there is almost no content, it still fills the screen.
It's for a page that is shown when the checkout cart is empty. The content is too thin, so the screen is not fully filled with content.
P.s. I am not looking for an answer that assumes that the header or footer has a static height. I want to be able to use it also in situations where the height of the header or footer is variable.
Also, I would love a CSS solution, so no JavaScript or jQuery
You can use calc() and set 100vh - height of header, also add box-sizing: border-box to keep padding inside.
* {
box-sizing: border-box;
}
body,
html {
margin: 0;
padding: 0;
}
header {
height: 200px;
background-color: blue;
width: 100%;
}
.container {
padding: 50px;
min-height: calc(100vh - 200px);
}
footer {
width: 100%;
height: 200px;
background-color: #333;
}
<header>
</header>
<div class="container">
small text
</div>
<footer>
</footer>
Other approach is to use Flexbox and set display: flex on body which is parent element in this case with min-height: 100vh and then just set flex: 1 on .container so it takes rest of free height.
* {
box-sizing: border-box;
}
body,
html {
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
header {
height: 100px;
background-color: blue;
}
.container {
padding: 50px;
flex: 1;
}
footer {
height: 100px;
background-color: #333;
}
<header>
</header>
<div class="container">
small text
</div>
<footer>
</footer>
try this
min-height: calc(100vh - 400px);
here is the fiddle https://jsfiddle.net/L7mwpzux/1/
This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 6 years ago.
I've got a delicate problem for any CSS guru out there.
My green div has a flexible height, taking up the remaining.
And now I want to put a div inside that div which should be the half of the green div. But it seems like if Chrome treats it like half of the whole page rather than the flex item.
http://jsfiddle.net/unh5rw9t/1/
HTML
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>
CSS
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
}
#half_of_content {
height: 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
#Michael_B explained why Chrome behaves like this:
You gave the body a height: 100%. Then gave its child (.wrapper)
a height: 100%. Then gave its child (.content) a height: 100%.
So they're all equal height. Giving the next child (#half_of_content) a height: 50% would naturally be a 50% height
of body.
However, Firefox disagrees because, in fact, that height: 100% of .content is ignored and its height is calculated according to flex: 1.
That is, Chrome resolves the percentage with respect to the value of parent's height property. Firefox does it with respect to the resolved flexible height of the parent.
The right behavior is the Firefox's one. According to Definite and Indefinite Sizes,
If a percentage is going to be resolved against a flex item’s
main size, and the flex item has a definite flex
basis, and the flex container has a definite main
size, the flex item’s main size must be treated as
definite for the purpose of resolving the percentage, and the
percentage must resolve against the flexed main size of the
flex item (that is, after the layout algorithm below has been
completed for the flex item’s flex container, and the flex
item has acquired its final size).
Here is a workaround for Chrome:
#content {
display: flex;
flex-direction: column;
}
#content::after {
content: '';
flex: 1;
}
#half_of_content {
flex: 1;
height: auto;
}
This way the available space in #content will be distributed equally among #half_of_content and the ::after pseudo-element.
Assuming #content doesn't have other content, #half_of_content will be 50%. In your example you have a 2 in there, so it will be a bit less that 50%.
html,
body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
#content::after {
content: '';
flex: 1;
}
#half_of_content {
flex: 1;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
You could absolutely position div id="half_of_content".
#content {
flex: 1;
height: 100%;
background-color: green;
position: relative; /* new */
}
#half_of_content {
height: 50%;
background-color: yellow;
position: absolute; /* new */
width: 100%; /* new */
}
DEMO
With regard to your statement:
But it seems like if Chrome treats it like half of the whole page
rather than the flex item.
You gave the body a height: 100%. Then gave its child (.wrapper) a height: 100%. Then gave its child (.content) a height: 100%. So they're all equal height. Giving the next child (#half_of_content) a height: 50% would naturally be 50% height of body.
With absolute positioning, however, you don't need to specify parent heights.
Nesting flexboxes is a little buggy. I reworked your markup a little by adding an inner wrapper with display: flex; which seems to do the job. Here is the fiddle (also using class names instead of ids).
<div class="content">
<div class="wrapper-inner">
2
<div class="half">
2.1
</div>
</div>
</div>
.wrapper-inner {
position: absolute;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
Fix:
on #content set
display: flex;
flex-flow: column nowrap;
justify-content: flex-end
on #half_of_content set flex: 0 0 50%;
Caveat: you need to add an extra div as a child of #content.
Here's the full example:
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
display:flex;
flex-flow: column nowrap;
justify-content: flex-end;
background-color: green;
}
#half_of_content {
flex: 0 0 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>
I found several questions about but none of their solutions was working for me so here we go again.
Let's say I have this template of HTML
<html>
<div id="header">...</div>
<div id="contentA">...</div>
<div id="contentB">...</div>
<div id="footer">...</div>
</html>
The footer div should be at least 80px height, but if those 80px plus the height of all other 3 divs is not enough to fullfill the screen I want the footer to increase as much as the screen is filled with it below header, contentA and contentB.
BG-Color Solution
If you just want to let the remaining space have the same background-color as the footer (but not the body), you could add the footer bg-color to the html-tag:
html {
background-color: #footer_color;
}
body {
background-color: #body_color;
}
#footer {
min-height: 80px;
}
.
JS-Solution
If you have something more complex within your footer, you could use javascript/jquery to calculate the remaining space and set the footer to that height.
There is a similar question with a code example here: https://stackoverflow.com/a/14329340/3589841
.
Flexbox-Solution
If you only care about the latest browsers you can use the flexbox-box-model:
HTML:
<html>
<body>
<div id="flex_container">
<div id="header">...</div>
<div id="contentA">...</div>
<div id="contentB">...</div>
<div id="footer">...</div>
</div>
</body>
</html>
CSS:
html, body {
min-height: 100%;
}
#flex_container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: flex-start;
}
#header {
flex: 0 1 auto;
}
#contentA {
flex: 0 1 auto;
}
#contentB {
flex: 0 1 auto;
}
#footer {
flex: 0 1 100%;
min-height: 80px;
}
I believe you're going for something like this, have a look http://jsfiddle.net/dusUK/
Using CSS, we create a class, which in this case is fullheight, and we apply the following:
.fullheight {
display: block;
position: relative;
background: red;
height: 100%;
}
We also then apply the following to html, body
html, body {
height: 100%;
min-height: 100%;
}
Why in the following example the height of the inner div is not like wrapper's div ?
Live demo here.
HTML:
<div class="wrapper">
<div class="inner">Hello</div>
<div class="inner">Peace</div>
</div>
CSS:
.wrapper {
background-color: #000;
min-height: 100px;
}
.inner {
display: inline-block;
background-color: #777;
height: 100%;
}
If I change min-height: 100px; to height: 100px;, then it looks OK. But, in my case, I need min-height.
Some properties in CSS inherit the value of the parent automatically, some don't. Minimum height must be explicitly stated when you want it to inherit the parent's value:
min-height: inherit;
I believe this is the output you want: http://jsfiddle.net/xhp7x/
.wrapper {
display: table;
background-color: #000;
height: 100px;
width: 100%;
}
.wrapper2 {
height: 100%;
display: table-row
}
.inner {
height: 100%;
display: inline-block;
background-color: #777;
margin-right: 10px;
vertical-align: top;
}
Had to add a second DIV wrapper2.
Tested on chrome and firefox.
You want to specify both, CSS height is not the same as min-height. You want to specify both height and min-height.
height = When used as a %, this is a percent of the window height
min-height = as you drag the window smaller, the DIV with a % height will continue to reduce until it hits the min-height
max-height = as you drag the window larger, the DIV with a % height will continue to increase until it hits the max-height
http://jsfiddle.net/gpeKW/2/ I've added a sample here with borders.
Slight change to the answer from your comment, you are pretty much correct from your original CSS.
The below HTML will have a minimum div height of 100px. As the size of the inner DIV increases, the wrapper will automatically expand. I have demonstrated this by adding a style attribute to the first inner class.
<html>
<head>
<title>Untitled Page</title>
<style type="text/css">
.wrapper
{
background-color: #000;
min-height:100px;
}
.inner
{
display: inline-block;
background-color: #777;
height: 100%;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="inner" style="height:200px">test</div>
<div class="inner">Peace</div>
</div>
</body>
</html>
I know one way to set the div child height the same as its parent div height is to use relative for the parent and absolute position for the child.
.wrapper {
background-color: #000;
min-height: 100px;
position: relative;
}
.inner {
display: inline-block;
background-color: #777;
position: absolute;
height: 100%;
}
But this way will cause some problem, you have to adjust the child element so that it will be displayed properly
P/s: Why don't you set it to the same height as its parent height? I mean, 100% is not x%... just thinking..
Anyway, happy coding ;)
I certainly joined answers and the result using 'min-height' for the -main HTML tag- (class = "main-page-container"):
HTML:
<div id="divMainContent">
<!-- before or after you can use multiples divs or containers HTML elements-->
<div> </div>
<div> </div>
<main class="main-page-container">
<div class="wrapper">
1
<div class="wrapper2">
2
<div class="child">3</div>
</div>
</div>
</main>
<!-- before or after you can use multiples divs or containers HTML elements-->
<div class="footer-page-container bg-danger" > more relevant info</div>
</div>
CSS:
/*#region ---- app component containers ---- */
#divMainContent {
height: 100%;
display: flex;
flex-direction: column;
/*optional: max width for screens with high resolution*/
max-width: 1280px;
margin:0 auto;
}
.main-page-container {
display: inline-table;
height: 70%;
min-height: 70%;
width: 100%;
}
.footer-page-container{
flex:1; /* important in order to cover the rest of height */
/* this is just for your internal html tags
display: flex;
flex-direction: column;
justify-content: space-between; */
}
/*#endregion ---- app component containers ---- */
.wrapper {
background: blue;
max-width: 1280px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100%;
}
.wrapper2 {
width: 90%;
margin: auto;
background: pink;
display: flex;
flex-wrap: wrap;
gap: 20px;
height: 90%;
}
.child {
min-height: 100px;
min-width: 300px;
background: orange;
position: relative;
width: 33%;
}