I want to have a child fill the exactly entire flex box of a flex layout.
If I use the following HTML:
<div class="parent">
<div class="child1">
should have 100px height
</div>
<div class="child2">
<div class="intermediatechild2">
<div class="subchild2">should have 200px height and padding</div>
</div>
</div>
</div>
and apply the following css:
.parent {
display: flex;
flex-direction : column;
height: 300px;
width: 200px;
}
.child1 {
height: 100px;
background: #008800;
flex: 0 0 auto;
}
.child2 {
height: 100%;
background: #003300;
flex: 0 0 auto;
}
.subchild2 {
height : 100%;
background: #ff0000;
}
.intermediatechild2 {
padding: 20px;
height : 100%;
width : 100%;
box-sizing: border-box;
border: 2px solid blue;
}
I get an overflowing intermediatechild. The height 100% seems to be relative to .parent
A fiddle can be found here:
http://jsfiddle.net/8znFV/4/
I did not understand exactly what you want, but if what you want is only leave. Subchild2 100% and follow the father's height (intermediatechild2), you'll have to add the father's height (intermediatechild2) with px and remove the height. child2.
Recalling that, you have to count the padding in father's height (intermediatechild2), so if you want. Subchild2 has 200px in height, will have to leave her father (intermediatechild2) with 240px, leaving 20 padding-top and 20 padding-bottom height of more than 200.
A note, only work in chrome as your css code is nonstandard, if you want I can breastfeed him at another time =)
Hope it helps
Here's an example: http://zip.net/bsmZgF
Just Remove height:100% from .child2and it will work. this will give 100% height to child2 element so it's going outside of parent.
It should be auto adjusted that's the purpose of flexbox and 100% height is giving more height(same as parent) to child2.
I fixed the problem. The solution lies in staying "display:flex". Once you started flex layout, you seem not to be able to step back to "display:block" with "height:100%".
<div class="parent">
<div class="child1">
should have 100px height
</div>
<div class="child2">
<div class="intermediatechild2">
<div class="subchild2">should have 200px height including padding</div>
</div>
</div>
</div>
css:
.parent {
display: flex;
flex-direction : column;
height: 300px;
width: 200px;
}
.child1 {
height: 100px;
background: #008800;
}
.child2 {
background: #003300;
flex: 1;
display: flex;
}
.subchild2 {
background: #ff0000;
flex: 1;
}
.intermediatechild2 {
padding: 20px;
display : flex;
box-sizing: border-box;
border: 2px solid blue;
}
working fiddle : http://jsfiddle.net/8znFV/6/
Related
There are plenty of questions on how to make a parent's width that of it's child that are suggested as similar questions, this is not what I want.
I am working on theming a piece of software for branding purposes, I do not control the software and only have access to CSS modifications, so JavaScript or modifying the DOM is out of the question or this would be trivial.
Using CSS only, is it possible to achieve the following.
I have a container div that holds two columns, the main content area, and a sidebar. The sidebar contains multiple divs that wrap content for different sidebar elements. The content of these sidebar elements are designed to be scaled to 100% width of it's parent, which works when the parent has a fixed width, which is by default 25% of the container.
What we need is for the sidebar to disappear when it's content is hidden. The content within each sidebar element can be set to display: none, but when all the elements are hidden the sidebar still takes up empty space. The example below using a min-width: fit-content and a max width of the 25% which was previously it's fixed size, which works fine for hiding the sidebar when the content is hidden, but the content in the sidebar doesn't grow. Is there a way to make the content inside of .sidebarElementWrapper below, grow to fit the max-width of #sidebarArea
* {
margin: 0;
box-sizing: border-box;
}
#container {
height: 100%;
display: flex;
flex-direction: row;
}
#contentArea {
width: 100%;
background: #A84652;
}
#sidebarArea {
max-width: 25%;
min-width: fit-content;
background: #4262C2;
}
.sidebarElement {
width: 100%;
padding: 12px;
background: #8b8b8b;
border-bottom: 1px solid #2c2c2c;
}
<div id="container">
<div id="contentArea">
</div>
<div id="sidebarArea">
<div class="sidebarElementWrapper">
<div class="sidebarElement">Sidebar Element 1</div>
</div>
<div class="sidebarElementWrapper">
<div class="sidebarElement">Sidebar Element 2</div>
</div>
</div>
</div>
To hide the content of a sidebar element, the .sidebarElement is set to display: none, not the wrapper, just of note. Since the wrapper still exists, and the content isn't removed, just hidden, the :empty pseudo-selector also doesn't work.
Edit: Just to clarify as I don't think it was clear after reading through this again, when the content is hidden the sidebar should be gone, doesn't matter how whether it's through display:none or width or some other mechanism. When there is sidebar content it should be 25% the width of the container.
Edit again: Because of some comments, I'm going to attempt to explain this again.
The sidebar has a min and max width, it does not have a fixed width, the sidebar will scale to fit the content inside it. Because the sidebar does not have a fixed width, elements basing their width on 100% of the parent do not act like you may expect, instead the sidebar is defaulting to the min-width from what I can tell, which is the minimum width required to fit the content. I am not looking for this, I want the sidebar to extend out to 25% of the container width, which you can see if you copy this code into a file (because the snippet above will run in a smaller pane it may actually be wider than 25% so it may not be representative)
* {
margin: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100%;
}
#container {
height: 100%;
display: flex;
flex-direction: row;
}
#contentArea {
width: 100%;
background: #A84652;
}
#sidebarArea {
max-width: 25%;
min-width: fit-content;
background: #4262C2;
}
.sidebarElement {
width: 100%;
padding: 12px;
background: #8b8b8b;
border-bottom: 1px solid #2c2c2c;
}
<div id="container">
<div id="contentArea">
</div>
<div id="sidebarArea">
<div class="sidebarElementWrapper">
<div class="sidebarElement">Sidebar Element 1</div>
</div>
<div class="sidebarElementWrapper">
<div class="sidebarElement">Sidebar Element 2</div>
</div>
</div>
</div>
In the end, I have a div with a min and max width, and a child element using a percent. The percent width (ie. width:100%) does not scale the child to the element's max width, but 100% of the current width, so no, the code as above does not achieve what I need.
I found a way to do it, fill-available.
.sidebarElement {
width: 100vw;
...
max-width: fill-available;
max-width: stretch;
max-width: -webkit-fill-available;
max-width: -moz-available;
}
Once this is done, the min-width on #sidebarArea can be removed.
* {
margin: 0;
box-sizing: border-box;
}
html,body {
width: 100%;
height: 100%;
}
#container {
height: 100%;
display: flex;
flex-direction: row;
}
#contentArea {
width: 100%;
background: #A84652;
}
#sidebarArea {
max-width: 25%;
background: #4262C2;
}
.sidebarElement {
width: 100vw;
padding: 12px;
background: #8b8b8b;
border-bottom: 1px solid #2c2c2c;
max-width: fill-available;
max-width: stretch;
max-width: -webkit-fill-available;
max-width: -moz-available;
}
<body>
<div id="container">
<div id="contentArea">
</div>
<div id="sidebarArea">
<div class="sidebarElementWrapper">
<div class="sidebarElement">Sidebar Element 1</div>
</div>
<div class="sidebarElementWrapper">
<div class="sidebarElement">Sidebar Element 2</div>
</div>
</div>
</div>
</body>
In the following HTML, I want to set the height of left and right 100% of the parent element. In addition, the left div has fixed width. The right should use all of the remaining width.
I think because of using display: flex; in the parents div, the width of the left div doesn't stay constant. How can I set fixed width for it and allocate all of the remaining space to the right.
Edit: the calc(100-52px) is the height of the parent. The question is only about setting fixed width of 100px to the left so that it doesn't change on resizing the window.
Here's what I'm trying:
body {
padding: 0;
margin: 0;
}
.parent {
background: red;
display: flex;
height: calc(100vh - 52px);
}
.left {
width: 100px;
background: yellow;
}
.right {
background: orange;
width: 100%;
}
<div class="parent">
<div class="left">the width should be fixed, not flexible</div>
<div class="right">width should be all of the remaining</div>
</div>
parent { display: -webkit-box;display:-webkit-flex;display: -ms-flexbox;display:flex;flex-wrap: wrap; }
.parent > [class*='col-'] { display: flex; flex-direction: column; }
You can use width: calc(100% - 100px) or flex: 1 for the right div.
Percentage values are calculated from the parent element, therefore you need to extract static values from 100% to get the remaining area.
But as you are already using a flex container here, you can just set flex: 1, which is the shorthand for flex-grow: 1, that will allow your container to take all the extra space in the parent container, since no other items are available.
Add a flex declaration to the .left selector:
flex: 0 0 100px;
flex syntax:
none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
So this declaration is stating: "don't grow, don't shrink, define the initial size as 100px"
Read more: flex (MDN)
If right is to stand 52px away from the far right, then a margin will do . Please clarify your question.
body {
padding: 0;
margin: 0;
}
.parent {
background: red;
display: flex;
height: calc(100vh - 52px);
}
.left {
width: 100px;
background: yellow;
}
.right {
flex-grow: 1;
background: orange;
margin-right: 52px;
}
<div class="parent">
<div class="left">the width should be fixed, not flexible</div>
<div class="right">width should be all of the remaining</div>
</div>
Set flex: 0 0 100px; on your .left div (you can remove width: 100px) if you want it to be a constant 100px - so no growing or shrinking.
body {
padding: 0;
margin: 0;
}
.parent {
background: red;
display: flex;
height: calc(100vh - 52px);
}
.left {
flex: 0 0 100px;
background: yellow;
}
.right {
background: orange;
width: 100%;
}
<div class="parent">
<div class="left">the width should be fixed, not flexible</div>
<div class="right">width should be all of the remaining</div>
</div>
see if this helps you, comment if you need any changes
stackblits link for 1 fixed width, 1 relative column
Similar to this question I´m struggling with using CSS grid to create a layout with fixed header and footer containing an middle row, which should use the remaining space of the .static or .dynamic dynamic container. So in this case, both oth them should have a complete height of 200px. Subtracting the 40px (2x 20px for header + footer) the remaining space for the content should be 160px. As you can see at the example, the red reference div on the left is clearly smaller than the whole "sandwich" of div containers. The .dynamic div element is to large and will stretch the whole div container. I want to prohibit this!
Here are a few additional conditions I have to fullfill:
The whole layout should be dynamic, so the .wrapper div later wont have a static height, but will fill 100% of the given height. therefore onlydynamic will be used, since this also uses 100% of the height. The showcase with .static is just there to show that it doesn´t even work with fixed heights.
Neither static nor dynamic should work with overflow to create scrollbars or hidden overflowing content. It should just restrict the dynamic area between .header and .footer to an height.
The containing .content container will expand itself to 100% width and should be treatet as a kind of blackbox: every component should be able to be inserted here. The content will always use 100% of the height and should not strech the ambient parent divs. The content will contain an scrollbar on its own, if the height of the content will be heigher than the dynamically allocated space of the .dynamic container
How am I able to solve this issue with the given description?
Please see the provided example and feel free to adapt it as you need to!
.wrapper {
display: flex;
flex-direction: row;
height: 200px;
max-height: 200px;
width: 100%;
}
.measurement {
height: 200px;
max-height: 200px;
min-height: 200px;
min-width: 3px;
background-color: red;
border: 2px solid blue;
padding: 2px;
margin: 1px;
}
.static,
.dynamic {
display: grid;
grid-template-rows: 20px 1fr 20px;
width: 50%;
border: 2px solid blue;
padding: 2px;
margin: 1px;
}
.static {
height: 200px;
max-height: 200px;
/*should NOT have an overflow/scrollbar but fit to the remaining space*/
}
.dynamic {
height: 100%;
max-height: 100%;
/*should NOT have an overflow/scrollbar but fit to the remaining space*/
}
.content {
height: 100%;
width: 100%;
overflow: auto;
/* Blackbox like content, always expands to 100% width and height */
/* could contain content that is larger than the dynamic-height div and will get scrollbar then */
}
.fixed-height {
background-color: green;
}
<div class="wrapper">
<div class="measurement"></div>
<div class="static">
<div class="fixed-height">TOP</div>
<div class="dynamic-height">
<div class="content">
TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST
</div>
</div>
<div class="fixed-height">BOTTOM</div>
</div>
<div class="dynamic">
<div class="fixed-height">TOP</div>
<div class="dynamic-height">
<div class="content">
TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST
</div>
</div>
<div class="fixed-height">BOTTOM</div>
</div>
</div>
EDIT
As you can see in the image below, the TEST and BOTTOM text is beyond the blue borders. I´m not about the few pixels difference between the borders and the red reference but I'm concerned about the overflow over the bottom border.
This is the expected behaviour: there should be a scrollbar inside the content area, no overflow and no scrollbar inside dynamic div
You need to merge the div.content with the div.dynamic-height and set the max-height: 100% property to your .dynamic-height class.
.content doesn't need an height, it's setted by the definition of the grid row.
.wrapper {
display: flex;
flex-direction: row;
height: 200px;
max-height: 200px;
width: 100%;
}
.measurement {
height: 200px;
max-height: 200px;
min-height: 200px;
min-width: 3px;
background-color: red;
border: 2px solid blue;
padding: 2px;
margin: 1px;
}
.static,
.dynamic {
display: grid;
grid-template-rows: 20px 1fr 20px;
width: 50%;
border: 2px solid blue;
padding: 2px;
margin: 1px;
}
.static {
height: 200px;
max-height: 200px;
/*should NOT have an overflow/scrollbar but fit to the remaining space*/
}
.dynamic {
height: 100%;
max-height: 100%;
/*should NOT have an overflow/scrollbar but fit to the remaining space*/
}
.content {
width: 100%;
overflow: auto;
/* Blackbox like content, always expands to 100% width and height */
/* could contain content that is larger than the dynamic-height div and will get scrollbar then */
}
.fixed-height {
background-color: green;
}
.dynamic-height {
max-height: 100%;
}
<div class="wrapper">
<div class="measurement"></div>
<div class="static">
<div class="fixed-height">TOP</div>
<div class="dynamic-height content">
TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST
</div>
<div class="fixed-height">BOTTOM</div>
</div>
<div class="dynamic">
<div class="fixed-height">TOP</div>
<div class="content dynamic-height">
TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST<br>TEST
</div>
<div class="fixed-height">BOTTOM</div>
</div>
</div>
Why doesn't "Box 2" fill the full (available) space? The height:100% is ignored...
HTML:
<div id="container">
<div id="box1">Box 1</div>
<div id="box2">Box 2</div>
<div id="box3">Box 3</div>
</div>
CSS:
body {
margin: 0 auto;
}
#container {
width: 100%;
height: 100%;
background: #cccccc;
display: -webkit-flex;
display: flex;
flex-direction: column
}
#box1 {
background: red;
height: 50px
}
#box2 {
background: yellow;
-webkit-flex: 1;
flex: 1
}
#box3 {
background: green;
height: 50px
}
http://jsfiddle.net/618axkjy/2/
Thanks!
It's because the parent #container element doesn't have a height of 100%. At the moment, the height of the body element is determined by the height of the #container element (since it's the only child). Since you're defining the height of the #container element using percentages, the height will remain the same since the parent's height is also the same.
You need to set the height of the html/body elements to 100%:
Updated Example
html, body, #container {
height: 100%;
}
..or you could define the height of the #container element in viewport-percentage units, vh:
Updated Example
#container {
height: 100vh; /* 100% of the viewport height */
}
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%;
}