Prevent block stretching in flexbox in IE - css

I will provide code right away to explain my problem:
HTML:
<div class="outer">
<div class="inner">abc</div>
</div>
CSS:
.outer {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
background-color: blue;
height: 500px;
}
.inner {
background-color: yellow;
min-height: 40px;
display: inline-flex;
width: 60%;
background-color: yellow;
border: 1px solid black;
}
As you can see the inner block is vertically streched, however, if you add another inner block, it behaves properly.
It seems to be an issue just in IE. Is there a way around to make the inner block not strech (when there is just one inside of the outer block)?

Related

Image in flexbox column not rendering properly in Chrome

I have a div with one image and one paragraph in it.
<div id="container">
<img src="..." />
<p>
This is my text
</p>
</div>
I use flex-box and flex-direction: column to align them.
#container {
display: flex;
flex-direction: column;
height: 300px;
width: 400px;
}
img {
max-width: 80%;
flex-basis: 50%;
}
p {
flex-basis: 50%;
}
Since both img and p have flex-basis 50% I would expect each of them to take up 50% of the space. In Firefox it works, but in Chrome the image is bigger (in height) than the container itself.
I have made a jsfiddle to demonstrate this: https://jsfiddle.net/q2esvro9/1/
How can I get the behaviour from Firefox in Chrome?
(Another interesting fact: In Internet Explorer 11 the image and text take up the same space, but the image is stretched in width. Which means 3 different behaviours for a very short and simple CSS code)
#container {
display: flex;
align-items: center;
align-content: center;
text-align: center;
flex-direction: column;
border: solid 2px red;
height: 300px;
width: 400px;
}
img {
max-width: 80%;
flex-basis: 50%;
}
p {
flex-basis: 50%;
border: solid 2px green;
}
<div id="container">
<img src="https://image.freepik.com/free-icon/apple-logo_318-40184.jpg" />
<p>
This is my text
</p>
</div>
There are flexbox rendering variations between the major browsers.
When dealing with images, the number of variations grows.
What I've found to work consistently across browsers is to not use img elements in a flex formatting context (i.e., don't make them flex items).
Instead, wrap an img in a div element, making the div the flex item and keeping the image in a block formatting context.
#container {
display: flex;
align-items: center;
align-content: center;
text-align: center;
flex-direction: column;
border: solid 2px red;
height: 300px;
width: 400px;
}
#container > div {
flex: 0 0 50%; /* 1 */
min-height: 0; /* 2 */
}
img {
height: 100%;
}
p {
flex-basis: 50%;
border: solid 2px green;
}
<div id="container">
<div>
<img src="https://image.freepik.com/free-icon/apple-logo_318-40184.jpg" />
</div>
<p>
This is my text
</p>
</div>
Notes:
The meaning and benefits of flex: 1
Why don't flex items shrink past content size?

Why flexbox not working responsive design with flex-direction?

i have doing my portfolio but i'm not good with CSS.
I'm using the Flexbox to do the design desktop and mobile but it not working...
It is like this, as i want, using flex-direction: column,:
Code of the div parent:
display: flex;
justify-content:center;
align-items:center;
background-color:#C4C4C4;
min-height: 100vh;
flex-direction: column;
But when i put in responsive, it stay like this:
The elements outside of div parent..
The code is the same, only changes the background-color.
background-color: red;
width:800px;
height:650px;
margin: 30px;
It not stay corrects.
If i dont use the flex-direction: column, it stay like this:
Someone why?
Your main issue was missing max-width: 100%; in the children so the width:800px would not overflow the container parent, take a look at the snippet
section {
display: flex;
justify-content: center;
align-items: center;
background-color: #C4C4C4;
min-height: 100vh;
padding: 15px 30px;
box-sizing: border-box;
}
#media(max-width:800px) {
section {
flex-direction: column;
}
}
div {
max-width: 100%;
width: 800px;
height: 650px;
margin: 15px
}
div:first-of-type {
background-color: red;
}
div:last-of-type {
background-color: blue
}
<section>
<div>red</div>
<div>blue</div>
</section>
max-width not set the width of the children elements.
Make sure you set a width to all of your containers; it looks like you want the gray container to fill the viewport, and the blocks to be evenly distributed.
Here's a working example:
.container {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
text-align: center;
background-color: gray;
width: 100vw;
height: 100vh;
}
.block {
background-color: #C4C4C4;
min-height: 33vh;
width: 90vw;
}
<div class="container">
<div class="block" style="background-color: red">
A
</div>
<div class="block" style="background-color: blue">
B
</div>
</div>

Flex auto margins behave differently in Chrome and Safari

Open this page in Chrome and in Safari and we can see the difference.
In Safari the "Maths" keyword is not on the right side as in Chrome.
Also the widths of the item-3 div is different in Chrome and in Safari.
My issue is that why it is different in Safari and what is the fix (I want CSS fix on the item-3).
flex-wrap: wrap is not a acceptable solution.
.main-container {
display: flex;
flex-direction: column;
width: 400px;
height: 300px;
border: 1px solid red;
}
.item-1 {
display: flex;
border: 1px solid blue;
}
.item-2 {
display: flex;
border: 1px solid green;
}
.item-3 {
display: flex;
margin-left: auto!important;
border: 2px solid yellow;
}
<div class="main-container">
<div class="item-1">Physics</div>
<div class="item-2">Chemistry</div>
<div class="item-3">Maths</div>
</div>
The width of .item-3 is different than its siblings because margin-left: auto packs the flex item to the right side. That's normal behavior for flex auto margins.
The reason margin-left doesn't work in Safari is a mystery / bug.
However, for cross-browser support, there is a simple flex alternative to auto margins in this case: align-self: flex-end
.main-container {
display: flex;
flex-direction: column;
width: 400px;
height: 300px;
border: 1px solid red;
}
.item-1 {
display: flex;
border: 1px solid blue;
}
.item-2 {
display: flex;
border: 1px solid green;
}
.item-3 {
display: flex;
align-self: flex-end; /* NEW */
border: 2px solid yellow;
}
<div class="main-container">
<div class="item-1">Physics</div>
<div class="item-2">Chemistry</div>
<div class="item-3"><span>Maths</span></div>
</div>
If you want .item-3 to keep the full width of the container, then use justify-content: flex-end.
.main-container {
display: flex;
flex-direction: column;
width: 400px;
height: 300px;
border: 1px solid red;
}
.item-1 {
display: flex;
border: 1px solid blue;
}
.item-2 {
display: flex;
border: 1px solid green;
}
.item-3 {
display: flex;
justify-content: flex-end; /* NEW */
border: 2px solid yellow;
}
<div class="main-container">
<div class="item-1">Physics</div>
<div class="item-2">Chemistry</div>
<div class="item-3">Maths</div>
</div>
How align-self: flex-end works
With align-self: flex-end you're shifting .item-3 along the cross axis all the way to the right.
This works because the flex container (.main-container) has flex-direction: column, which makes the main axis vertical and cross axis horizontal.
How justify-content: flex-end works
With justify-content: flex-end you're shifting the children of .item-3 along the main axis all the way to the right.
This works because .item-3 is a flex container with flex-direction: row (by default), which makes the main axis horizontal and cross axis vertical.
Then, as per the specification, text in a flex container that is not explicitly wrapped by an element, is considered an anonymous flex item. This allows justify-content to work.
4. Flex Items
Each in-flow child of a flex container becomes a flex item, and each
contiguous run of text that is directly contained inside a flex
container is wrapped in an anonymous flex item.
Why text-align: right doesn't work
text-align: right won't work because flex items (including anonymous ones) are considered block-level elements. The text-align property applies only to inline-level content.
More information
Learn more about flex alignment along the main axis here:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Learn more about flex alignment along the cross axis here:
How does flex-wrap work with align-self, align-items and align-content?

Flex box container width doesn't grow [duplicate]

This question already has answers here:
When flexbox items wrap in column mode, container does not grow its width
(9 answers)
Closed 6 years ago.
When using flex box in default row direction, the container height grows to contain all the flex items, even if it is absolutely positioned.
#container {
position: absolute;
display: flex;
flex-wrap: wrap;
}
#container > div {
flex: 0 0 200px;
height: 200px;
}
See http://codepen.io/tamlyn/pen/dPjLoN/?editors=110
However if the flex direction is changed to column, the container collapses to the width of a single flex item, even if the items wrap onto the next column.
#container {
position: absolute;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
#container > div {
flex: 0 0 200px;
width: 200px;
}
See http://codepen.io/tamlyn/pen/rarbeN?editors=110
How can I make the container contain all flex items in column mode?
I've actually found a CSS-only solution to this but it isn't the most perfect thing in the world. Here it is: http://codepen.io/anon/pen/vEPBKK
The trick here is to create a visibility: collapsed container. In flex, visibility: collapsed objects take themselves out of the normal flex flow but retain their dimensions for the purpose of layout. This widens the flex container to the desired width but leaves the flex items unaffected. There are a few caveats, however:
This requires a bit of fiddling. As you can see, the magic <div> is a set width but it uses :nth-child to determine how many boxes are before it. If your actual design breaks at more or less than 3 rows, you'll have to adjust this and you'll most certainly have to adjust the width of the object.
Because of a rendering bug, this does not work in IE. Luckily, IE's incorrect implementation does exactly what you wanted in the first place without any changes so all you have to do is give IE it's own stylesheet with some conditional statements and shoot the div.magic some good old display: none.
HTML
<div id="container">
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="magic"></div>
</div>
CSS
#container {
position: absolute;
display: flex;
flex-direction: column;
flex-wrap: wrap;
border: 1px solid #f00;
height: 650px;
padding: 1px;
}
#container div.fb {
border: 1px solid #555;
flex: 0 0 200px;
background-color: #ccc;
width: 200px;
margin: 1px;
height: 200px;
}
#container > div.magic {
height: 0;
margin: 0;
padding: 0;
visibility: collapsed;
}
#container > div.magic:nth-child(5),
#container > div.magic:nth-child(6),
#container > div.magic:nth-child(7) {
width: 408px;
}
#container > div.magic:nth-child(8),
#container > div.magic:nth-child(9),
#container > div.magic:nth-child(10) {
width: 612px;
}
#container > div.magic:nth-child(11),
#container > div.magic:nth-child(12),
#container > div.magic:nth-child(13) {
width: 816px;
}
I think this is the CSS you're looking for:
#container {
display: flex;
flex-flow: row wrap;
border: 1px solid #f00;
padding: 1px;
}
#container > * {
border: 1px solid #555;
background-color: #ccc;
height: 200px;
width: 200px;
margin: 1px;
}
The "Container" will always the the width of it's container, in this case the page, but now the boxes will adjust within it properly.
Let me know if I misunderstood your question.
Update
I've been playing with what you're asking for for several days now, and it really seems like it's not possible to do what you're asking... at least not in the direction that you're asking.
The container wants to be the maximum width possible. Unless you force the container to be the exact width, at which point it wont be the full width, but it wont flex with the flexing content either.
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
border: 1px solid #f00;
}
.flex-item {
background-color: #ccc;
padding: 5px;
width: 200px;
height: 150px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
border: 1px solid #555;
}
<div id="container" class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
The first try I do not understand what you mean
as reference material you can see this tutorial
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Align text to the bottom of a div

I tried to align my text to the bottom of a div from other posts and answers in Stack Overflow I learned to handle this with different CSS properties. But I can't get it done. Basically my HTML code is like this:
<div style='height:200px; float:left; border:1px solid #ff0000; position:relative;'>
<span style='position:absolute; bottom:0px;'>A Text</span>
</div>
The effect is that in FF I just get vertical line (the div in a collapsed way) and the text is written next to it. How can I prevent the div collapsing but having the width fitting to the text?
Flex Solution
It is perfectly fine if you want to go with the display: table-cell solution. But instead of hacking it out, we have a better way to accomplish the same using display: flex;. flex is something which has a decent support.
.wrap {
height: 200px;
width: 200px;
border: 1px solid #aaa;
margin: 10px;
display: flex;
}
.wrap span {
align-self: flex-end;
}
<div class="wrap">
<span>Align me to the bottom</span>
</div>
In the above example, we first set the parent element to display: flex; and later, we use align-self to flex-end. This helps you push the item to the end of the flex parent.
Old Solution (Valid if you are not willing to use flex)
If you want to align the text to the bottom, you don't have to write so many properties for that, using display: table-cell; with vertical-align: bottom; is enough
div {
display: table-cell;
vertical-align: bottom;
border: 1px solid #f00;
height: 100px;
width: 100px;
}
<div>Hello</div>
(Or JSFiddle)
You now can do this with Flexbox justify-content: flex-end now:
div {
display: flex;
justify-content: flex-end;
align-items: flex-end;
width: 150px;
height: 150px;
border: solid 1px red;
}
<div>
Something to align
</div>
Consult your Caniuse to see if Flexbox is right for you.

Resources