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?
Related
I'd like to horizontally center align a flex child inside a flex container.
However, when the child gets align-self: center it shrinks to width = 0.
Note that both the container and the child have max-width.
How would you solve this?
.container {
display: flex;
flex-direction: column;
max-width: 400px;
outline: 2px solid red;
}
.child {
display: flex;
flex-direction: column;
max-width: 200px;
height: 50px;
background-color: #ccc;
/* This causing the child to shrink to width = 0 */
/* align-self: center; */
}
<div class="container">
<div class="child">
</div>
</div>
The issue is the stretch effect that you disable by changing the alignment of the element. By default align-items is set to stretch thus the element will try to fill its parent width (or height for a row direction).
You can put back this feature using width:100%
.container {
display: flex;
flex-direction: column;
max-width: 400px;
outline: 2px solid red;
}
.child {
display: flex;
flex-direction: column;
max-width: 200px;
height: 50px;
width:100%;
background-color: #ccc;
align-self: center;
}
<div class="container">
<div class="child">
</div>
</div>
align-items sets the default alignment for all of the flex container’s items, including anonymous flex items. align-self allows this default alignment to be overridden for individual flex items.ref
When I write such code, I know that the text does not break.
.a {
display: flex;
border: 1px solid yellow;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
The cause of this problem is that min-width: auto sets the text width of the flex item tomin-width.Therefore, this problem is solved with min-width: 0.
.a {
display: flex;
border: 1px solid yellow;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
min-width: 0; /* add this code! */
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
Next I wrote such a code.
However, the min-width of that code did not work as I expected and a long word overflowed. This is a problem that did not occur at flex-direction: row. What is the cause of this?
Why does min-width: 0 not work in flex-direction: column?
.a {
display: flex;
flex-direction: column;
border: 1px solid yellow;
align-items: start;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
min-width: 0;
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
For flex-direction: row the main-axis is horizontal and the cross-axis is vertical.
For flex-direction: column they switch so the main-axis is vertical and cross-axis is horizontal, you know.
Now let me remind you that
justify-content, flex-grow, flex-shrink and flex-basis properties work on the main-axis
align-items works on the cross-axis
When you set align-items: start you're overriding the default align-items: stretch and your flex-item can take any width which is greater than min-width (as neither width nor max-width are specified).
To achieve the desired behavior it would be enough to remove align-items: start;
min-width: 0 can be also safely removed as it does nothing.
See the snippet below:
.a {
display: flex;
flex-direction: column;
border: 1px solid yellow;
/* align-items: start; let's use default value instead */
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
/* min-width: 0; this does nothing */
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
You just need to give div .b an explicit width, or the element will expand to fit content. Using your code, this is as simple as:
.a {
display: flex;
flex-direction: column;
border: 1px solid yellow;
align-items: start;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
// min-width: 0;
width: 100%;
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
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)?
This question already has an answer here:
Remove space (gaps) between multiple lines of flex items when they wrap
(1 answer)
Closed 5 years ago.
I have made a simple flexbox jsfiddle To play around with all flexbox values, but stumbled upon something that I can't explain my .item divs are spaced out for some reason and .grid is automatically stretching to full height, I'm not entirely sure why this happens?
HTML
<div class="container">
<div class="grid">
<div class="item red">a</div>
<div class="item yellow">b</div>
<div class="item blue">c</div>
</div>
</div>
CSS
.container {
width: 320px;
height: 480px;
background: black;
padding:15px;
margin: 20px auto;
display: flex;
}
.grid {
background: white;
display: flex;
width: 100%;
justify-content: flex-start;
align-items: flex-start;
flex-direction: row;
flex-wrap: wrap;
}
.item {
width: 100%;
flex-grow: 0;
flex-basis: 100%;
align-self: auto;
align-items: flex-start;
padding: 10px 0;
}
.red { background: red; }
.yellow { background: yellow; }
.blue { background: blue; }
The align-items: flex-start (set on .grid) causes this type of behavior. As specified in the MDN docs
The CSS align-items property defines how the browser distributes space between and around flex items along the cross-axis of their container.
If you disable it, the value will be set to stretch by default (each flex item will be stretched to fill the container).
Can't figure out how to keep the child items same height on both sides after aligning their content to the middle.
My aim is to create a layout as seen in picture:
<div class="halves">
<div class="half">
<div class="half-inner is-right">H1</div>
</div>
<div class="half">
<div class="half-inner is-left">H2
<br> asdfs df <br>a sdfadsf sdfa dadsf df asdf afdf sadf asdf </div>
</div>
.halves{
display: flex;
border: 5px solid red;
.half{
flex: 1;
border: 10px solid yellow;
/* align-items: center; */
display: flex;
.half-inner{
max-width: 100px;
&.is-right{
margin-left: auto;
background: pink;
}
&.is-left{
background: green;
}
}
}
}
My current code here: http://codepen.io/zsitro/pen/YqpLba
In my example uncommenting /* align-items: center; */ you can see the child item collapses.
I appreciate any guidance. ty
align-items: center forces the div into the center of a flex container, and in the event of no specific declarations of width/height/flex-basis/whatnot, it makes the div as big as its content, preserving the whitespace. If you want the div to stretch, you will need the the align-items value to be stretch so it takes up the entire height of the parent container.
Additionally, if you want the .half-inner divs to be equal in width: flex: 1 (or flex-grow: 1) is a child property, so the declaration you currently have only applies to the .half divs, not the .half-inner divs. Since the parent .half div is a flex container, you can just add flex:1 under the .half-inner CSS and you should be good to go.
.halves{
display: flex;
border: 5px solid red;
.half{
flex: 1;
border: 10px solid yellow;
align-items: stretch;
display: flex;
.half-inner{
max-width: 100px;
flex: 1;
&.is-right{
margin-left: auto;
background: pink;
}
&.is-left{
background: green;
}
}
}
}