CSS flexbox wrap not resizing to fit contents [duplicate] - html

This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
CSS when inline-block elements line-break, parent wrapper does not fit new width
(2 answers)
Closed 3 years ago.
A simplified plunkr to show the problem:
https://plnkr.co/edit/mHTHLEumQ04tInFVAz3z?p=preview
If you resize the right viewport until the two containers no longer fit on the same row, right one moves to a new line.
However the parent inline-flex container width does not change, throwing the top "header" element off - the "button" in "header" should be right aligned with the last item in the container below.
The two (or more) items have fixed width but no space between them. Those are the only elements with fixed width or height.
How can I force the flex container width to fit/shrink when items wrap to a new row (without using js, pure HTML/CSS)?
.main-flex {
display: -webkit-inline-flex;
display: inline-flex;
-webkit-flex-direction: column;
flex-direction: column;
}
.flex-container {
flex-grow: 1;
display: -webkit-inline-flex;
display: inline-flex;
-webkit-flex-direction: row;
flex-direction: row;
flex-wrap: wrap;
}
<div style="margin-top: 100px;" class="main-flex">
<div>
<span>header</span>
<span style="float:right">button</span>
</div>
<div class="flex-container">
<div style="height: 400px; width:250px; border: 1px solid black;"></div>
<div style="height: 400px; width:250px; border: 1px solid black;"></div>
</div>
</div>

In CSS, the parent container doesn't know when its children wrap. Hence, it continues scaling its size oblivious to what's going on inside.
Put another way, the browser renders the container on the initial cascade. It doesn't reflow the document when a child wraps.
That's why the container doesn't shrink-wrap the narrower layout. It just continues on as if nothing wrapped, as evidenced by the reserved space on the right.
More details here: Make container shrink-to-fit child elements as they wrap
But you don't need the container to shrink for your layout to work. It can be built with a few adjustments to your HTML and CSS.
.main-flex {
display: inline-flex;
flex-wrap: wrap;
}
.flex-container {
display: flex;
flex-direction: column;
}
.flex-container>div {
height: 400px;
width: 250px;
border: 1px solid black;
}
.flex-container:nth-child(2)>span {
align-self: flex-end;
}
<div class="main-flex">
<div class="flex-container">
<span>header</span>
<div></div>
</div>
<div class="flex-container">
<span>button</span>
<div></div>
</div>
</div>
revised demo

Related

flex-wrap in column direction flex - Container not adapting the width [duplicate]

This question already has answers here:
When flexbox items wrap in column mode, container does not grow its width
(9 answers)
Closed last year.
I don't know what silliness I've got myself into but I'm stuck in a common flexbox issue..
Here's a pen.. https://codepen.io/webdev51/pen/zYPWwbd
What I'm trying to achieve is the parent flex div to be adapting the width when flex item go into 2nd row using flex-wrap.
Desired/expected result:
Results I get:
And here's the most important part that is driving me nuts.
If I replicate the same in flex-direction: row; , it'll be working as expected and whenever the items drop in the next row, the container will adapt the height accordingly.
after changing display: inline-flex to display: flex, add align-content: flex-start;
.spaceship-group{
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 90vh;
align-content: flex-start;
justify-content: center;
position: relative;
border:2px solid orange;
}
.spaceship {
height: 240px;
width: 290px;
position: relative;
border:1px solid blue;
}
<div class="spaceship-group">
<div class="spaceship"></div>
<div class="spaceship"></div>
<div class="spaceship"></div>
<div class="spaceship"></div>
<div class="spaceship"></div>
</div>

Centered content is cut out of parent with fixed height and scrollbar

I have a parent with overflow-y and a fixed height. I wish to center align its child. The content of the child can vary in size, and sometimes it overflows the parent and triggers a scrollbar. In those cases, the top and bottom content of the child is cut out.
I wish the child to be center aligned, but only if it's smaller than the parent. Or it could always be center aligned, but then the content shouldn't be cut out.
Check out the problem here: https://jsfiddle.net/gumy023z/
.parent {
background-color: red;
height: 40px;
overflow-y: scroll;
/* Comment out the flex, and all the content will be available */
display: flex;
justify-content: center;
align-items: center;
}
<div class="parent">
<div class="child">
This is a test <br> This is a test <br> This is a test
</div>
</div>
The alignment will work in the flex axis of a flexbox. So you can switch to a column flexbox and give min-height: 0 (which overrides the default min-width: auto setting for a flex item) for the child element - see demo below:
.parent {
background-color: red;
height: 40px;
overflow-y: auto;
display: flex;
flex-direction: column; /* ADDED */
justify-content: center;
align-items: center;
}
.child {
min-height: 0; /* ADDED */
}
<div class="parent">
<div class="child">
1. This is a test <br> 2. This is a test <br> 3. This is a test
</div>
</div>

Center a flex item when its siblings have different widths [duplicate]

This question already has answers here:
Keep the middle item centered when side items have different widths
(12 answers)
Closed 5 years ago.
I know flexbox offers a great solution for centering items. But I run into an issue when I have 3 items and I'd like the center (2nd) item to be centered with respect to the window, regardless of the size of the other 2 items.
In my pen you can see the second item "Client Index" is off-center because the content on the right is larger than the content on the left. How can I force it to center itself?
.flex {
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="flex">
<span style="font-size:12px;">small</span>
<span style="font-size:20px;">Client Index</span>
<span style="font-size:18px;">Lots of content that moves the center</span>
</div>
My Codepen
One way would be to set flex-grow: 1; flex-basis: 0 so the 3 columns are distributed evenly, then you can center the text or the content in the middle one.
I'm using text-align to center the middle column. You could also use display: flex; justify-content: center; to do the same thing.
.flex {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex > span {
flex: 1 0 0;
}
.flex > span:nth-child(2) {
text-align: center;
}
<div class="flex">
<span style="font-size:12px;">small</span>
<span style="font-size:20px;">Client Index</span>
<span style="font-size:18px;">Lots of content that moves the center</span>
</div>
Use nested flex containers and auto margins.
.flex-container {
display: flex;
}
.flex-item {
flex: 1;
display: flex;
justify-content: center;
}
.flex-item:first-child>span {
margin-right: auto;
}
.flex-item:last-child>span {
margin-left: auto;
}
/* non-essential */
.flex-item {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
<div class="flex-container">
<div class="flex-item"><span>short</span></div>
<div class="flex-item"><span>medium</span></div>
<div class="flex-item"><span>lonnnnnnnnnnnnnnnnnnnng</span></div>
</div>
Here's how it works:
The top-level div is a flex container.
Each child div is now a flex item.
Each item is given flex: 1 in order to distribute container space equally.
Now the items are consuming all space in the row and are equal width.
Make each item a (nested) flex container and add justify-content: center.
Now each span element is a centered flex item.
Use flex auto margins to shift the outer spans left and right.
You could also forgo justify-content and use auto margins exclusively.
But justify-content can work here because auto margins always have priority. From the spec:
8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.

why do flexbox children have the same height? [duplicate]

This question already has answers here:
How to disable equal height columns in Flexbox?
(4 answers)
Closed 7 years ago.
I have two items inside a flex container, I gave the first item a specific height and I want the other's height to fits its actual content.
So the code is pretty simple: jsfiddle
.main {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row nowrap;
/* Safari 6.1+ */
flex-flow: row nowrap;
}
.sub {
border: 1px black solid;
flex-grow: 1;
}
#sub1 {
height: 300px;
margin-right: 50px;
}
<div class="main">
<div class="sub" id="sub1"> </div>
<div class="sub" id="sub2"> </div>
</div>
As you can see the second div stretched as the first ones's height increased, so how to prevent that, how to make the next child with no height specification hold its actual height as its actual content
Because the default value for align-items is stretch. Change that to flex-start if you want them to be top aligned and no stretch.
.main {
display: flex;
flex-flow: row nowrap;
align-items: flex-start;
}
.sub {
border: 1px black solid;
flex-grow: 1;
}
#sub1 {
height: 300px;
margin-right: 50px;
}
<div class="main">
<div class="sub" id="sub1"> </div>
<div class="sub" id="sub2"> </div>
</div>

Expanding iframe within Flexbox

I am trying to stretch the size of an iframe to fill the remaining space within my web app. I know the maximum space is being allocated for the div (by adding a border), but the iframe height itself is not expanding to fill the entire vertical height.
The problem is the row content iframe is not filling the entire vertical space, even though the flexbox is allocating that space appropriately.
Any ideas?
.box {
display: flex;
flex-flow: column;
height: 100vh;
}
.box .row.header {
flex: 0 1 auto;
}
.box .row.content {
flex: 1 1 auto;
}
.box .row.footer {
flex: 0 1 40px;
}
.row.content iframe {
width: 100%;
border: 0;
}
<div class="box">
<div class="row header">
<h1>Event Details</h1>
<div id="container">
<h5>Test</h5>
</div>
<div data-role="navbar">
<ul>
<li>Players
</li>
<li>Games
</li>
<li>Chat
</li>
</ul>
</div>
</div>
<div class="row content">
<iframe src="players.html"></iframe>
</div>
<div class="row footer">
<p><b>footer</b> (fixed height)</p>
</div>
</div>
Here are two things to consider:
When you create a flex container only the child elements become flex items. Any descendants beyond the children are not flex items and flex properties don't apply to them.
Your iframe is not a flex item because it is a child of div class="row content" which is a flex item, but not a flex container. Therefore, no flex properties apply and there is no reason for the iframe to stretch.
To apply flex properties to the children of flex items, you need to make the flex item also a flex container. Try this:
.box .row.content {
flex: 1 1 auto;
display: flex; /* new */
}
With the adjustment above the iframe's parent becomes a (nested) flex container, the iframe becomes a flex item, and default flex settings (including align-items: stretch) go into effect. The iframe should now occupy the full height of the container.
You can fix it with just flexbox, Make sure the container (wrapper) of the iframe has a height set or its parent has, this can be a in pixels percent or VH. and flex-direction:column. The iframe itself needs a flex:1 1 auto; nothing else is needed so no height or width set on it.
Internet explorer can have some problem with the width of the iframe. But it should work vertically. For IE11 make sure you set a min-height:0 on the wrapper.
body{
padding:1em;
display:flex;
flex-direction:column;
align-items:center;
justify-content: center;
height:100vh;
}
.wrap {
display: flex;
flex-direction: column;
width: 80vw;
height: 80vh;
border: 2px solid blue;
min-height: 0;
}
.frame {
flex: 1 1 auto;
border: 0;
}
Simplified jsfidle demo
Complex jsfidle demo