Square Blocks with Flex Box - css

Is there a way to get all boxes to be equal to the height (and width) of the largest box using display: flex; with flex-wrap: wrap;. It appears to only work on folks in the same line.
This pen illustrates the problem some more: http://codepen.io/komplexb/pen/gbqgXq

Given that you are already setting a height on the parent element (and that the parent element is square), you would just need to give the children flexbox items a height of 50%.
In doing so, the flex-basis (shorthand) value of 50% combined with a height of 50% will result in perfectly square flexbox items since the parent is square.
Updated Example
li {
flex: 0 0 50%;
height: 50%;
color: white;
text-align: center;
}

Related

Wrapping Flexbox Without Extra Width

I'm trying to display a bunch of boxes in a container, such that they fill a row then wrap around when they reach the container's maximum width.
I can make the basic layout easily by putting the following styles on the container <div>:
border: 1px solid black;
display: flex;
flex-wrap: wrap;
max-width: calc(100vw - 500px);
That gets me what I want, but the problem is ... let's say each inner box takes up 300px, and on my screen the container has a width of 800px. I'll get two boxes per row.
However, the flexbox and its border won't stop at 600px. It will keep going to the full 800px, even though there's nothing in the remaining 200px.
I've tried playing with the width and max-width properties, but nothing (eg. fit-content, max-content, 100%) made the container constrain itself to the size of its boxes (ie. 600px).
Is it possible to have a wrapping flexbox where the flexbox's width doesn't extend past the boxes inside of it (when there is leftover space)?
Is it possible to have a wrapping flexbox where the flexbox's width doesn't extend past the boxes inside of it (when there is leftover space)?
Yes, though not in the way envisioned in this question.
A parent of dynamic width containing children with explicit width will result in remainder width.
The standard approach is to divide the remainder width among children, growing them dynamically until enough remainder width exists to fit another child.
Drag the bottom right corner to resize this parent horizontally and get a feel for how this approach attacks the problem.
.parent {
background-color: navy;
display: flex;
flex-wrap: wrap;
gap: 2px;
padding: 2px;
width: 400px;
overflow: scroll;
resize: horizontal;
}
.child {
flex-basis: 150px; /* Desired width */
flex-grow: 1; /* Fill up remaning space at a rate of 1 */
background-color: crimson;
height: 75px;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
There are also many good solutions to this problem using Grid layout.
The approach in dealing with remainder width envisioned in this question appears to be removing it from the parent entirely, which is not possible.
I've tried playing with the width and max-width properties, but nothing (eg. fit-content, max-content, 100%) made the container constrain itself to the size of its boxes (ie. 600px).
In order to calculate how many children can fit at the dynamic width, said width has to be set on the parent, at which point the parent is committed and can't then re-adjust its width. This is the issue with any container and not just Flexbox.

Centered element in flexbox won't stretch till max width

How can I have an element that is centered in a flex box, stretch up to it's max-width ?
In this example, I want the red box to stretch up to 400px;
How can I make this happen ?
To make it work I added width:100% on top of maw-width:400px
Just use flex
.my-box {
background: red;
height: 100px;
flex: 0 400px;
}
and
flex-direction: row;

Flex container with divs children not stacking horizontally

I'm fairly new to flexbox, and can't figure out how to do what I'm trying. I'd like for the repeated content to stack horizontally to the right. I would like the items to shrink to fit the width of the content (if the title/report id text is longer/shorter). I'm trying to make the red box only as wide as the content and stack to the right. The purple box(container) is flex. It seems like the red div is the culprit that I can't figure out. I've tried converting to inline-block and played with the flex-grow and flex-shrink, but nothing seems to work for me. There might be a style somewhere else in the project that is competing, but not sure what to look for if that's the case...
Styles of the purple container div:
line-height: 1.5;
display: flex;
flex-direction: column;
max-height: 22.8125rem;
padding-bottom: .5rem;
margin-bottom: 1rem;
background-color: #394b54;
flex-basis: 100%;
-webkit-box-flex: 1;
flex-grow: 1;
I'd like for the repeated content to stack horizontally to the right
Use the default flex-direction: row.
I would like the items to shrink to fit the width of the content
Use the default flex-grow: 0 and flex-basis: content.

scrolling flex container does not fit centered items [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 6 years ago.
HTML:
<div id="container">
<div class="item">Foo</div>
<div class="item">Bar</div>
</div>
CSS:
#container {
display: flex;
justify-content: center;
overflow: auto;
}
.item {
flex-grow: 1;
min-width: 200px;
max-width: 300px;
}
When the above container shrinks to less than 400px, a horizontal scroll bar appears as expected. However, the first item becomes partially obscured by the left edge of the container, even when scrolled all the way to the left. As the container shrinks, more of the item is obscured.
Demo: http://jsfiddle.net/FTKcQ/. Resize result frame to observe. Tested in Chrome 30 and Firefox 24.
If justify-content is changed from center to to any other value (e.g. space-between), then all content is visible by scrolling. Why do centered items behave differently?
The goal here is to have a row of centered items, each of which will grow in width between some range. If the container cannot fit all minimal-width items, it should scroll to display them all.
According to MDN (Flex item considerations), this behavior is expected for now:
Flexbox's alignment properties do "true" centering, unlike other centering methods in CSS. This means that the flex items will stay centered, even if they overflow the flex container. This can sometimes be problematic, however, if they overflow past the top edge of the page, or the left edge, as you can't scroll to that area, even if there is content there! In a future release, the alignment properties will be extended to have a "safe" option as well.
For now, if this is a concern, you can instead use margins to achieve centering, as they'll respond in a "safe" way and stop centering if they overflow. Instead of using the align- properties, just put auto margins on the flex items you wish to center. Instead of the justify- properties, put auto margins on the outside edges of the first and last flex items in the flex container.
So, you can achieve then expected result, using margins for alignment. Just add margin-left: auto for first item and margin-right:auto for last.
My demo: http://jsfiddle.net/WFxQk/
try with style sheet
#container {
background-color: green;
display: flex;
/* justify-content: center */ ;
align-items: center;
overflow: auto;
}
.item {
background-color: white;
border: 1px solid black;
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
min-width: 200px;
max-width: 300px;
margin: auto;
}
I removed justify-content, making it to the default flex-start. And, added margin:auto which seems that it makes center alignment.
Updated Demo: http://jsfiddle.net/FTKcQ/1/

Flexible box layout model: How should auto margins in the cross-axis direction behave?

Please help me to understand one issue with the flexible box layout model for which I get different results in Firefox and Chrome.
Consider the following HTML fragment:
<body>
<header>Header</header>
<footer>Footer</footer>
</body>
styled via
body {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
header {
max-width: 400px;
height: 20px;
background-color: yellow;
margin: 0 auto;
}
footer {
width: 400px;
height: 20px;
background-color: green;
margin: 0 auto;
}
The header box has a maximum width constraint of 400px while the footer has a fixed width of 400px. When I try this code in Gecko-based browsers (Firefox 21 and 24 in my case) both header and footer are horizontally centered (as I hoped for by giving them left and right auto margins) but only the footer has a width of 400px while the header's width is just the width of the content even if enough horizontal space was available.
In WebKit/Blink-based browsers (Chrome 25 and 28 in my case) the header and footers are both centered and are both 400px wide (in case there is enough horizontal space), and this is exactly what I want to achieve.
Obviously, either Firefox or Chrome must be wrong. How do you understand the spec: http://www.w3.org/TR/css3-flexbox/? What is the desired behaviour?
If you want to play around, here is a JSFiddle: http://jsfiddle.net/4Rv7K/.
Note that one has to enable the flexible box layout model in the release version of Firefox. It is the setting layout.css.flexbox.enabled. (Without it, one is actually not testing anything about flexboxes.)
P.S.: The bug was in Chromium's engine and has apparently been fixed by now: https://code.google.com/p/chromium/issues/detail?id=242654
The Firefox/Gecko behavior is correct.
WebKit is stretching up to 400px (the max-width) due to the header element's default "align-self: stretch" value. However, the spec is clear that "align-self: stretch" is only supposed to stretch if you have no auto margins in the cross axis. Quoting the spec:
If a flex item has ‘align-self: stretch’, [...] and neither of its
cross-axis margins are ‘auto’, the used outer cross size is the used
cross size of its flex line, clamped according to the item's min and
max cross size properties
http://www.w3.org/TR/css3-flexbox/#cross-sizing
The exception for "neither of its cross-axis margins are auto" is what Firefox is honoring here and WebKit/Blink appear to be ignoring.
Now, to achieve your desired layout: It looks like you want both stretchiness and centering, and I don't think you can get both of those things simultaneously in the cross axis.
You can get them simultaneously in the main axis of a flex container, though -- so you can fix this by adding a horizontal flex container around the header and the footer.
I've done that here:
http://jsfiddle.net/4Rv7K/16/
The relevant code (just with the 'header' for simplicity):
body {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
horizFlex {
display: -webkit-flex;
display: flex;
}
header {
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
max-width: 400px;
height: 20px;
background-color: yellow;
margin: 0 auto;
}
[...]
<body><horizFlex><header>Header</header></horizFlex></body>
I think this achieves the layout you're looking for by wrapping the header and footer each in a horizontal flex container. The flex container stretches to the width of its parent (the body), and inside of it we have a single flex item (e.g. the ), which is flexible up to its max-width, and which we center (with auto margins) once it has reached its max-width.
For an element that lacks a definite size with auto margins, it looks like the element's fit-content width is supposed to be used as the element's actual width while the remaining space is counted as margin. For Chrome, it appears to be behaving inappropriately only when using flex-direction: column.
http://codepen.io/cimmanon/pen/fuhyF
ul {
display: -webkit-flex;
display: flex;
height: 5em;
background: yellow;
}
li {
margin: auto;
border: 1px solid;
}
ul.column {
-webkit-flex-direction: column;
-flex-direction: column;
}
If you look at a list with the above styles, Opera, Firefox, and Chrome agree that the li elements are shrink wrapped when the direction is row. Under the column direction, only Firefox and Opera shrink wrap the li, while Chrome has the li take the full width of the flex container.

Resources