How does a flexbox expand to it's child on overflow? - html

I have a flexbox layout.
The html is as follows:
<div class="grid">
<div class="row">
<div class="column">Content</div>
<div class="column">Content2</div>
<div class="column">Content2</div>
</div>
<div class="row">
<div class="column">Content</div>
<div class="column">Content2</div>
<div class="column">Content2</div>
</div>
</div>
and the css:
.grid {
overflow: auto;
width: 500px;
height: 400px;
background-color: #eee;
display: flex;
flex-direction: column;
}
.row {
background-color: #ddd;
align-items: stretch;
display: flex;
border: 2px solid black;
}
.column {
flex: 1 0 20em;
padding: 0.2em;
border: 2px solid lightblue;
/*background-color: hsla(0, 100%, 80%, 50%);*/
}
(see https://jsfiddle.net/bz71qptu/1/)
In the previous code, the .box element does not expand to the width of its children. How do I make it do this?
Edit
I have added an example of what I am hoping to achieve visually to the jsfiddle
Edit 2
I needed to change the question slightly to fit my particular issue. The parent element is aligned with flex-direction: column which means that using min-width doesn't seem to work. The min-width solution would be perfect without this.
Edit 3
I'm very thankful to everyone for helping, but I'm not sure I've exactly captured the behaviour I wanted to in my example, and even with all the advice I've been given I can't seem to make it do what I want. Here is a much better jsfiddle, if you look at this I've put borders up to show where everything is. I've read through the answers to see if I can adapt them to my situation, but I can't quite see it. I apologise if this fiddle is already answered.

Revised Answer
Your revised question changes the flex-direction from row to column.
With this adjustment, the flex property applied to .box is no longer relevant for your purposes, as it now handles vertical sizing. In other words, with column the flex property controls height not width.
As I mentioned in the comments, however, adding overflow: auto to .box seems to work perfectly (tested in Chrome, FF and IE11).
DEMO
You mentioned in your comments that it breaks the layout engine. The layout broke for me, as well in jsFiddle. Just hit [RUN] it again.
Ever since jsFiddle launched their upgrade a few days/weeks(?) ago it's been causing some confusion, as it now caches code. You may need to clear jsFiddle cookies (go to chrome://settings/cookies in your browser) or run revised code again after loading.
Original Answser
Instead of content for the flex-basis value, try auto or 0.
The content value isn't supported yet.
In fact, maybe simply flex: 1 will work for you.
See here:
CSS-Tricks ~ Common Values for flex
W3C Flexbox Spec ~ Common Values for flex

class .box is a flexbox container and a flexed child of class
.container
display: flex makes it act as a flexbox container
flex: 1 0 auto defines how it behaves as a child (of .container)
class .element is a flexed child of class .box
display: flex makes .element act as a flexbox container and yields no effect in your fidde (only when .element has children)
flex: 1 0 auto defines how it behaves as a child (of .box)
As you have not defined any sizes but 1000em for class .element, overflow: auto for class .container and flex-shrink: 0 (in flex: 1 0 auto) for both class .box and .element all elements react on the defined 1000em and can only grow to 1000em.
Change both flex: 1 0 auto to flex: 1 (defaults to flex: 1 1 auto) and your question has been answered!
Tiny update: .element change to flex: 1; min-width: 1000em
Fiddle

Related

Parent grid doesn't take child's min-content width into account

In Chrome and Safari, a parent styled with display: grid doesn't seem to take into account the fact that its child is width: min-content when calculating its own width or its children's positions. See for yourself:
#parent {
position: absolute;
background: lightgreen;
display: grid;
justify-content: flex-end;
}
#child {
padding: 25px;
box-shadow: inset 0 0 0 3px red;
width: min-content;
}
<div id="parent">
<div id="child">
<p>hello jello allegro rhino cello
</div>
</div>
The behavior I would naively expect would be:
to have the red box (child) aligned to the right (because of justify-content: flex-end)
to have the green box (parent) take the width of the red box (because it simply has no reason to be this wide, except that it's exactly the width of the child if it weren't min-content)
Question:
Is this an expected behavior? Do the specs say anything about this? Or is this a bug and Firefox got it right?
My assumption is that calculating a grid layout isn't O(1) or even O(n) and browsers need to bail-out early on edge cases, and width: min-content is probably kind of the same thing. But I'm just guessing here.
Bonus points if you can point me in the direction of an open ticket for this "bug" in either of the 3 big browsers!

Why is Firefox not honoring flexed div's height, but Chrome is?

This is best illustrated with a simple example.
I have a container with display: flex and flex-direction: column, with a single div inside with height: 300px and flex: 1.
Chrome renders the nested div at 300px tall, but Firefox renders it as a single line. Is this just a nuance between the implementation of flexbox between the two browsers, or is this bad code somehow? If a nuance, what's the best way to mitigate?
.container {
display: flex;
flex-direction: column;
}
.container > div {
background-color: #666;
color: white;
flex: 1;
height: 300px;
}
<div class="container">
<div>Single line in Firefox, but 300px tall in Chrome!</div>
</div>
The flex: 1 shorthand rule breaks down as follows:
flex-grow: 1
flex-shrink: 1
flex-basis: 0
Chrome sees this, but overrides flex-basis with height: 300px.
Firefox sees this, but does not override flex-basis with height: 300px.
The simple cross-browser solution is to get rid of the height rule and just use:
flex: 1 0 300px
In terms of the spec, Firefox has the correct behavior:
7.1. The flex
Shorthand
When a box is a flex item, flex is consulted instead of the main
size property to determine the main size of the box.
The flex item’s main size
property is
either the width or height property.

How exacty does the display: flex property work on a container div, and the flex property work on a div child?

I am trying to understand exactly how the display: flex property works in this layout: http://www.html.it/demo/javascript/55905/demo_index.html
As you can see in this layout there is an external div container having id="com" and that have this CSS:
.com {
align-items: stretch;
display: flex;
height: 100vh;
overflow: hidden;
}
So it have set the display: flex; coupled with the align-items: stretch; properties. So, reading here:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
It seems to me that it is defining a container in which the element are put one next to the other, but I am absolutely not sure if I am missing something.
Then, inside this container that defined the content having id="com__content", this one:
<div class="com__content">
that have the following CSS settings associated:
.com__content {
background: #404855 none repeat scroll 0 0;
flex: 8 1 0;
padding: 10vh 10vw;
position: relative;
}
Also this internal component have something related to the flex behavior.
What exactly does the flex: 8 1 0; property on this div mean?
flex: 8 1 0;
is shortcut stand for 'flex-grow', 'flex-shrink' and 'flex-basis'
first flex-grow 8 means: this div totally have 8/ total space
for exmple:
you have a div.first flex-grow: 1;
and another div.second flex-grow: 2;
the first div have only 1/3 psace in this line, and left over would be second div's place.
flex-shrink
This defines the ability for a flex item to shrink if necessary.
value 1 mean shrink 1 times
last flex-basis
defines the default size of an element before the remaining space is distributed.
you can setup as It can be a length(20% or 100px), it specifies the initial size of the flex item
as your mentions that article A Complete Guide to Flexbox had metion
flex
This is the shorthand for flex-grow, flex-shrink and flex-basis combined. The second and third parameters (flex-shrink and flex-basis) are optional. Default is 0 1 auto.

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

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)

box-orient in both direction?

What I am trying to do here is to make the <div>s (9 in my demo) to arrange like 井 (a 3x3 grid). My approach is to use the flexible box layout to make them spread evenly across the whole area.
<div id="container">
<div>1</div>
...
<div>9</div>
</div>
#container {
display: -webkit-box;
-webkit-box-align: stretch;
-webkit-box-orient: horizontal;
width: 300px;
height: 300px;
}
#container > div {
-webkit-box-flex: 1;
border: 1px solid black;
height: 50px;
}
However, this will make them line up in a single axis. I can change the orientation to vertical or horizontal, but not both. What is a better (and working) way to achieve this with only CSS? The float: left trick won't work here because the size of the container will vary.
You're actually looking at the wrong specification. The 2009 specification is being phased out in favor of the CR draft from Sept. 2012. To make a 3x3 grid with flexbox, you need to enable wrapping. The property from the 2009 draft for that was called box-lines, but the last remaining browser that follows that spec (Firefox) never implemented it.
http://jsfiddle.net/aUSWE/1/ (prefixes not included)
#container {
display: flex;
flex-flow: row wrap;
width: 300px;
height: 300px;
border: 1px solid black;
resize: both;
overflow:auto;
}
#container > div {
flex: 1 1 33%;
border: 1px solid black;
box-sizing: border-box;
}
http://www.w3.org/TR/2011/WD-css3-flexbox-20110322/#flex-order
It seems to me like the w3 standard for flexbox explicitly requires them to be either horizontal (LR/RL) or vertical (TB/BT), so I don't believe you can explicitly call for a 3x3 grid. As noted in the comments, the simplest solution seems to be three vertical flexbox divs with 3 horizontal flexbox divs inside of them (or the inverse). Unnecessary divs, indeed, but what else is CSS about? :)
You might look into grid-layout (http://www.w3.org/TR/2011/WD-css3-grid-layout-20110407/ ) since that seems like it's the grid cousin of flexbox. (Of course, that would be if you're designing solely for IE 10... http://caniuse.com/css-grid )