Set number of div elements' width based on static width container - html

I want to set the width of the div elements' width accordingly depending on their container width. However, the number will be changed, so the width will need to be adjusted accordingly. Here is a CSSDeck link to explain the situation clearly:
http://cssdeck.com/labs/hvmkapkd
As you can see, both containers are identical (needed), also they have modular content (<div> elements) (which is also needed). Keeping the same structure, is it possible to auto adjust the width of the divs using CSS so that they fill up the whole container?
Then each item in the first container would have 33.333% width, and each item in the second container would have 20% width.

I found the solution right after posting the question.
Setting the .container elements as table and setting the colored content as table-cell made it.
Link is updated above, but here is the link once again anyway:
http://cssdeck.com/labs/hvmkapkd

Give the flex-box concept a chance (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)
.container{
height: 100px;
width: 100px;
background-color: lightgray;
margin: 20px;
/* flexbox setup */
display: -webkit-flex;
-webkit-flex-direction: row;
display: flex;
flex-direction: row;
}
.container > div {
height: 100%;
/* flexbox setup */
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
}
(http://cssdeck.com/labs/full/hvmkapkd)

Related

Why's CSS percentage (%) height applied to grand-child of flex element?

I'm trying to check how CSS 100% height property works. But there's one thing I can't understand.
Why's 100% height working perfectly on .flex-grand-child (Chrome)? Does .flex-child have height property? So why it's even working???
Here's JSFiddle
html, body {
height: 100%;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.flex-parent {
flex: 1 0 auto;
display: flex;
}
.flex-child {
width: 300px;
}
.flex-grand-child {
height: 100%;
background-color: green;
}
<div class="container">
<div class="flex-parent">
<div class="flex-child">
<div class='flex-grand-child'></div>
</div>
</div>
</div>
This is a particular case where the browser can handle percentage value on height due to the stretch effect of flexbox. The flex-child has a default alignment equal to stretch which is equivalent to having height:100% then the flex-parent is also filling its parent height with flex-grow:1. At the end, the browser was able to correctly resolve the height:100% of flex-grand-child
If the flex item has align-self: stretch, redo layout for its contents, treating this used size as its definite cross size so that percentage-sized children can be resolved.ref
If you disable the stretch alignment, it will break:
html,
body {
height: 100%;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.flex-parent {
flex: 1 0 auto;
display: flex;
}
.flex-child {
width: 300px;
min-height: 200px;
align-self: flex-start; /*this will break it*/
border: 1px solid;
}
.flex-grand-child {
height: 100%;
background-color: green;
}
<div class="container">
<div class="flex-parent">
<div class="flex-child">
<div class='flex-grand-child'></div>
</div>
</div>
</div>
To use simple words: When having the stretch effect, the browser will first define the parent height based on its own parent (the content play no role here) then the browser will make the content height:100% of the previous calculated height. Without stretch the browser need to consider the content to define the height of the parent and here we will fall into the classic issue of percentage height.
Related question to get more cases where percentage can be resolved without having an explicit height defined on the parent element: Why is my Grid element's height not being calculated correctly?
Here is the relevant part of the specification dealing with this: https://www.w3.org/TR/css-sizing-3/#percentage-sizing
It's a bit complex but it's different from the CSS2 specification where percentage will always fail if the parent height is not specified:
If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
The .flex-parent element has flex-grow: 1 applied, giving it the full height of the .container (height: 100%). It also has display: flex applied, making it a flex container.
This latter setting automatically triggers align-items: stretch, which causes the flex item – .flex-child – to expand the full height of the container. So the .flex-child computes to height: 100%.
Modern browsers, now accepting flex heights as a reference point for children with percentage heights, set the child of the flex item – .flex-grand-child – to the full height of the parent, which is height: 100%.
More details here: Chrome / Safari not filling 100% height of flex parent
You have .container as a flex container with a flex-direction of column, so by default, the child element will stretch to fill. So .flex-parent is stretching to fill .container.
Since .flex-parent is also a flex-container, .flex-child is stretching to fill that.
Finally, since .flex-grand-child has height 100%, it is also filling the entire area.

I don't understand why my div with height auto is taking the full height of its parent

I have a div.grid that contains multiple div.column inside using flexbox. When a div.column increases in height due to having more content inside, all other div.column also increase in height.
It is to my understaind that this shouldn't help as their height is set to auto.
Also, my grid is using the flex display, with flex-wrap: wrap. I think is what is causing it, but I haven't found any explanation to why it is changing the children's height.
I have tried changing the following properties, in different combinations and manners, of parent and children: position, display, height.
These are the computed styles only, not my actual code.
div.grid {
display: flex;
flex-wrap: wrap;
width: 960px;
}
div.column {
display: block;
flex-basis: 37.5%;
flex-grow: 0;
flex-shrink: 0;
/* height is actually set to auto, but it is computed like this */
height: 132px;
}
<div class="grid">
<div class="column">something</div>
<div class="column">something<br>else<br>here</div>
<div class="column">something</div>
</div>
I expected the children to not fill the full height of the parent when the children don't all have the same amount of content.
As LGSon has asnwered in the comments:
Using flex: display automatically defaults align-items to stretch making the height of the children stretch to fill the height of the wrapper. It is also not shown in the computed properties, which is why it didn't cross my mind to check it.
Therefore, the solution was to add align-items: flex-start to .grid.

Flex-basis is not acting as width when set within display: flex set to flex-direction: row

Hi guys here is the codepen for more details including html: [https://codepen.io/Onsopen/pen/BmvNJe?editors=1100][1]
body {
display: flex;
margin: 0;
flex-direction: column; // so here i am using body tag as overall container
min-height: 100vh;
background: #2c3e50;
}
header {
display: flex;
justify-content: space-between;
}
main {
display: flex; // <-here the main html tag is being set as display flex and by default is row direction.
flex-basis: 200px; // <-THE PROBLEM is the 200px are set as height??
}
article {
flex-basis: 60%; // <- over here i am setting the tags within main tag individually
background: #ecf0f1;
}
nav {
flex-basis: 20%; <- over here i am setting the tags within main tag individually
background: #95a5a6;
order: -1;
}
aside {
flex-basis: 20%; <- over here i am setting the tags within main tag individually
background: #3498db;
}
header, footer {
background: #1abc9c;
flex-basis: 100px;
}
I am trying to make holy grail layout with flexbox and I am facing a strange behavior from flex-basis within the main tag which is set as display: flex with direction as row.So the items all line up as a row.
When trying to set the flex-basis instead of acting on or as the width is actually just acting as height which is strange considering that the flex-basis stretch is dependent on the direction and main axis which within the main tag is set to row with display: flex as default.
Is it because the <body> tag set to flex-direction:column is influencing the <main> tag item thus when setting the main tag item as flex-basis: 200px is actually responding as an individual item within a column, like the other items within tag (nav, aside, article) stretch on the side because of being under flex row direction within main. Was thinking that would be the cause.
However after some research I read at csstricks that items set to display: flex are not influenced by the other parent above them. So kind of when Individual items that are child become parent they are not anymore influenced by the previous parent in terms of direction. Just a guess but would love some help. I figure out to solve this with body tag set to row and it worked well as their are different ways to solve it but on this specific situation seems strange.
Any reason to why so?
The flex-basis: 200px; set in the main is affecting the height of itself, which is what it's suppose to.
And why, because the flex-basis is a flex item property and whether it affect height or width is based on its parent, the flex container's, flex-direction, which in your case is the body having column.
If to control the main's width, you need to use just that, width:
main {
display: flex;
flex-basis: 200px; /* height */
width: 500px; /* width */
}

Make flex item have 100% height and overflow: scroll [duplicate]

This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 5 years ago.
I want a flex item to take 100% of remaining height and display the overflow: scroll bar.
It looks like problem comes from my #userList which takes 100% of the window height and not taking the remaining space .
body {
display: flex;
flex-direction: column;
min-height: 100%;
margin:0px;
}
.wrapper {
display: block;
flex: 1 1 auto;
display: flex;
flex-direction: row; /
}
#chatContainer {
background: orange;
width: calc(100% - 350px);
display: flex;
flex-direction: column;
}
#tabs{
background-color: red;
flex: 1 1 0px;
display: flex;
}
#usersContainer {
flex: 1 1 0;
display:flex;
flex-direction:column;
}
#userListWrapper {
background-color:pink;
flex: 1 1 auto;
display:flex;
}
#userList {
-webkit-flex: 1 1 auto;
overflow: auto;
min-height: 0px;
height:100%;
}
.input {
background-color: #49FFFC;
}
<div class="wrapper">
<div id="chatContainer">
<div id="webcamContainer">webcam</div>
<div id="tabs">tabs here</div>
<div id="footer" style="background-color:#A0C8FF;height:50px">footer</div>
</div>
<div id="usersContainer" style="background-color:blue">
<div class="input">searchInput1</div>
<div class="input">searchInput2</div>
<div id="userList">
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>user1<br>user2<br>
</div>
</div>
</div>
https://jsfiddle.net/jpo31gq9/
The main problem you are having is a violation of the rules governing percentage heights in CSS.
Basically, when using percentage heights, you must always specify the height of the parent element. Otherwise, the element with a percentage height has no frame of reference, and the height computes to auto (the height of the content).
From the spec:
CSS height property
percentage Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes to "auto".
auto The height depends on the values of other properties.
source: https://www.w3.org/TR/CSS21/visudet.html#propdef-height
So if you plan to use percentage heights, you need to specify a height on every parent element up to the root element (html) or up to a fixed height declaration (such as height: 250px).
In your CSS, you have body { min-height: 100%; }. However, there is no height specified on the parent (html).
The following parent elements in your code are missing a height declaration:
html
body (min-height doesn't count)
.wrapper
#chatContainer
With the following adjustments your layout works.
html { height: 100%; } /* NEW */
body {
display: flex;
flex-direction: column;
/* min-height: 100%; */
margin: 0px;
height: 100%; /* NEW */
}
.wrapper {
display: block;
flex: 1 1 auto;
display: flex;
flex-direction: row;
height: 100%; /* NEW */
}
#chatContainer {
background: orange;
width: calc(100% - 350px);
display: flex;
flex-direction: column;
height: 100%; /* NEW */
}
Revised Fiddle
It's also worth mentioning some variations among current browsers.
Percentage Heights: Chrome/Safari vs Firefox/IE
Although the traditional implementation of percentage heights uses the value of the height property, recently some browsers have broadened their scope.
As evidenced in the following posts, Firefox and IE are now also using flex heights to resolve the percentage height of child elements.
Chrome / Safari not filling 100% height of flex parent
Height is not correct in flexbox items in Chrome
Flexbox in Chrome--How to limit size of nested elements?
Chrome ignoring flex-basis in column layout
Bottom line: Chrome and Safari resolve percentage heights based on the value of the parent's height property. Firefox and IE11/Edge use the parent's computed flex height.
For now, the simplest cross-browser solution to this problem would be, in my view, using the height property across the board for percentage heights.

Height of flex element is not respected unless display: table is set?

http://jsfiddle.net/u2zedzob/12/
<div class="wrapper">
<div class="main-content"></div>
<div class="footer"></div>
</div>
*, *:before, *:after {
box-sizing: border-box;
}
.wrapper {
background-color: red;
height: 300px;
width: 300px;
display: flex;
flex-direction: column;
}
.main-content {
height: 100%;
width: 100%;
background-color: green;
}
.footer {
height: 30px;
width: 100%;
background-color: blue;
display: table;
}
In this example, the footer's height is 30px and main-content grows to fill the rest of the space. Perfect!
However, if I remove the display: table property of footer -- its height becomes 27.266px. This can also be prevented by setting the footer's min-height to 30px.
I'm not too familiar with flex logic. Why is this happening? Is there a more elegant solution where the height of footer will be respected? Maybe a flex property I am missing?
When working with flex box model you do not need to set height property for the child elements which should scale. Instead you would use e.g. the flex-grow property. In the given case where just one element should be scaled a value of 1 would be appropriate (as no proportions need to be defined here).
Have a look at the updated example where the height of the .main-content element is scaled according to the available space and the height of the .footer element is retained correctly by 30px without setting the display property:
http://jsfiddle.net/u2zedzob/21/
For further information maybe check this guide:
http://css-tricks.com/snippets/css/a-guide-to-flexbox/
The flex-grow property is explained as:
This defines the ability for a flex item to grow if necessary. It
accepts a unitless value that serves as a proportion. It dictates what
amount of the available space inside the flex container the item
should take up.
If all items have flex-grow set to 1, every child will set to an equal
size inside the container. If you were to give one of the children a
value of 2, that child would take up twice as much space as the
others.