I have a flex-box with one to three flex-items.
The proper layout should look like i
When there are three elements in the container:
h2
AND
AND
h2
to always be in the middle...THEN, you can do something like this:
.container > div:first-of-type { order: 1; }
.container > h2 { order: 2; }
.container > div:last-of-type { order: 3; }
This translates to:
Regardless of the order of elements in the source,
- The first div will appear first in the visual order
- The
h2
will appear second in the visual order- The second div will appear last in the visual order
.container {
display: flex;
}
.container > * {
flex: 1;
border: 1px dashed red;
}
h2 {
text-align: center;
margin: 0;
}
.container > div:first-of-type { order: 1; }
.container > h2 { order: 2; }
.container > div:last-of-type { order: 3; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
<div class="container">
<div>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
<span>I'm span 3</span>
</div>
</div>
<div class="container">
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
<span>I'm span 3</span>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 4</span>
<span>I'm span 5</span>
<span>I'm span 6</span>
</div>
</div>
<div class="container">
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 3</span>
</div>
</div>
<div class="container">
<div>
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<div>
</div>
<h2>
I'm an h2
</h2>
</div>
<div class="container">
<div>
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<h2>
I'm an h2
</h2>
</div>
<div class="container">
<h2 class="diff-order">
I'm an h2
</h2>
<div class="diff-order">
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<div class="diff-order">
<span>I'm a span</span>
<span>I'm a span</span>
</div>
</div>
<p><span>TRUE CENTER</span></p>
For situations where there is one element in the container, add justify-content: space-around
.
Because each item already has flex: 1
applied, space-around
will have no effect when there are two or more items in the container.
However, when there is only one item, space-around
resolves to center
.
From the spec:
8.2. Axis Alignment: the justify-content property
The
justify-content
property aligns flex items along the main axis of the current line of the flex container.
space-around
Flex items are evenly distributed in the line, with half-size spaces on either end.
If the leftover free-space is negative or there is only a single flex item on the line, this value is identical to
center
.
.container {
display: flex;
justify-content: space-around; /* NEW */
}
.container > * {
flex: 1;
border: 1px dashed red;
}
h2 {
text-align: center;
margin: 0;
}
.container > div:first-of-type { order: 1; }
.container > h2 { order: 2; }
.container > div:last-of-type { order: 3; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
<div class="container">
<div>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
<span>I'm span 3</span>
</div>
</div>
<div class="container">
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
<span>I'm span 3</span>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 4</span>
<span>I'm span 5</span>
<span>I'm span 6</span>
</div>
</div>
<div class="container">
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 3</span>
</div>
</div>
<div class="container">
<div>
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<div>
</div>
<h2>
I'm an h2
</h2>
</div>
<div class="container">
<div>
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<h2>
I'm an h2
</h2>
</div>
<div class="container">
<h2 class="diff-order">
I'm an h2
</h2>
<div class="diff-order">
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<div class="diff-order">
<span>I'm a span</span>
<span>I'm a span</span>
</div>
</div>
<div class="container">
<h2 class="diff-order">
I'm an h2
</h2>
</div>
<p><span>TRUE CENTER</span></p>
You are now covered for ONE and THREE flex items.
For TWO items, it gets a bit trickier.
Since you always want the h2
centered, I would suggest having two divs in the container at all times, even if they're empty. Then flex: 1
will give all three items equal width.
.container {
display: flex;
justify-content: space-around;
}
.container > * {
flex: 1;
border: 1px dashed red;
}
h2 {
text-align: center;
margin: 0;
}
.container > div:first-of-type { order: 1; }
.container > h2 { order: 2; }
.container > div:last-of-type { order: 3; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
<div class="container">
<div>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
<span>I'm span 3</span>
</div>
</div>
<div class="container">
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
<span>I'm span 3</span>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 4</span>
<span>I'm span 5</span>
<span>I'm span 6</span>
</div>
</div>
<div class="container">
<div>
<span>I'm span 1</span>
<span>I'm span 2</span>
</div>
<h2>I'm an h2</h2>
<div>
<span>I'm span 3</span>
</div>
</div>
<div class="container">
<div>
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<div>
</div>
<h2>
I'm an h2
</h2>
</div>
<div class="container">
<div></div>
<div>
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<h2>
I'm an h2
</h2>
</div>
<div class="container">
<h2 class="diff-order">
I'm an h2
</h2>
<div class="diff-order">
<span>I'm a span</span>
<span>I'm a span</span>
</div>
<div class="diff-order">
<span>I'm a span</span>
<span>I'm a span</span>
</div>
</div>
<p><span>TRUE CENTER</span>
</p>