Using 'Order' Property to Position Flex Item Between Siblings

Using 'order' property to position flex item between siblings

When there are three elements in the container:

  • div
  • h2
  • div

AND

  • the order of these elements varies in the source...

AND

  • you want the 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>

Centering an element between two siblings in flexbox

Here's the code you're using to align your flex items:

.header {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
}

With space-between the "Information" and "Contact" elements will be positioned at opposite edges of the container.

Because a flex container aligns items based on the distribution of free space, your middle item will be centered between them, not necessarily centered on the page.

With "Information" having a computed width of 174px, and "Contact" having a computed width of 135px, the middle item is off-center by 39px.

In order for the middle item to be centered on the page, its siblings would need to be equal width, so there is an equal balance of space on both sides.

The following post has two methods for centering items in a flex container when siblings vary in size:

  • Methods for Aligning Flex Items along the Main Axis (see box #71)

Using the flex order property across multiple containers

The flex order property applies only to siblings in the same container.

So using order to re-arrange a series of flex items spread across different containers will not work.

But based on your requirements, it doesn't appear you need multiple containers. All items can exist in a single container.

.wrapper {  display: flex;  flex-wrap: wrap;}
.child-1-1 { order: 1; }.child-1-2 { order: 3; }.child-2-1 { order: 2; }.child-2-2 { order: 4; }
.wrapper > div { flex: 1 0 40%; height: 50px; margin: 5px; border: 1px solid #ccc; background-color: lightgreen; display: flex; align-items: center; justify-content: center;}

@media ( max-width: 600px) { .wrapper { flex-direction: column; } div.child-2-1 { order: -1; background-color: orange; }}
<div class="wrapper">  <div class="child-1-1">child-1-1</div>  <div class="child-1-2">child-1-2</div>  <div class="child-2-1">child-2-1</div>  <div class="child-2-2">child-2-2</div></div>

How does the order property work on absolutely-positioned children of a flex container?

The statement you quoted from the spec:

Absolutely-positioned children of a flex container do not participate
in flex layout, but are reordered together with any flex item
children.

... doesn't actually exist in the order property definition. It's included at the end of the spec in the clarifications section.

Nonetheless, the order definition does say this:

Applies to: flex items and absolutely-positioned children of flex
containers

But that's all the definition says about absolutely-positioned children of a flex container. There is no further guidance or clarification.

Therefore, browser makers have significant discretion in implementing this feature. And it appears that the major browsers have not even begun implementation, as testing shows that order is doing nothing on abspos children of a flex container. Tested in Chrome, FF, IE11 and Edge.


Here's an interesting comment from a related question:

I don't consider this a legitimate solution, but if I add position:absolute with some javascript after the page loads instead of it being in the css file, order works as expected

Applying order property to flex items in different containers

With your current HTML structure, that is not possible.

The order property applies only to flex items that are siblings in the same flex container.

(And keep in mind that .row isn't even a flex container. So the children are not flex items.)

You can use order to re-arrange .row and .flex-item-2.

If you apply display: flex or inline-flex to .row, you can then use order to re-arrange .flex-item-1 and .flex-item-3.

But because they have different parents, the first two cannot be re-arranged with the latter two.

flexbox order: I want box to open under a element which is not a sibling

Using order will not work because order is in relation to the container not the DOM.

The CSS order property specifies the order used to lay out flex items in their flex container. Elements are laid out in the ascending order of the order value. Elements with the same order value are laid out in the order in which they appear in the source code.

MDN - "order"

CSS Grid can do this though.

Codepen Demo

.container {
padding: 5px;
display: grid;
width: 500px;
margin: 1em auto;
grid-auto-columns: 50px;
grid-auto-rows: 50px;
grid-gap: 5px;
}

.box {
border: 1px solid black;
width: 50px;
height: 50px;
}

#b1 {
background-color: red;
grid-column-start: 1;
grid-column-end: 2;
}

#b2 {
background-color: blue;
grid-column-start: 2;
grid-column-end: 3;
}

#b3 {
background-color: green;
grid-column-start: 3;
grid-column-end: 4;
}

#b4 {
background-color: yellow;
grid-column-start: 1;
grid-column-end: 2;
}

@media screen and (max-width: 500px) {
#b1,
#b2,
#b3,
#b4 {
grid-column-start: 1;
grid-column-end: 2;
}
#b3 {
grid-row-start: 4;
grid-row-end: 5;
}
#b4 {
grid-row-start: 3;
grid-row-end: 4;
}
}
<div class="container">
<div class="box" id="b1"></div>
<div class="box" id="b2"></div>
<div class="box" id="b3"></div>
<div class="box" id="b4"></div>
</div>

Flexbox order when in different divs?

The order property controls the re-ordering of flex items in the same container.

In your mark-up, .something is a flex item, along with siblings h1 and h4. The children of .something are in a different container and, hence, cannot be re-ordered with the parent and uncles.

If it's not absolutely necessary to have your image and paragraph in a different container, just put them in the main container. Then you can order everything however you like.

Here's an example:

.wrapper {  text-align:center;  display:flex;  flex-direction: column;}
img { height: 300px; align-self: center;}
p { order:3;}
h1 { order:1;}
h4 { order:2;}
<div class="wrapper">  <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Puffer_Fish_DSC01257.JPG/1280px-Puffer_Fish_DSC01257.JPG"></img>  <p>ICONS HERE</p>  <h1>TITLE</h1>  <h4>SUBTITLE</h4></div>

Flexbox items are overlapping z-index set on sibling elements

You can just remove the z-index from every item except the widgets bubbles. This will lead to the desired output of having the bubbles always on top of any container.

.container {
display: flex;
background: #eee;
margin-top: 5%;
height: 100px;
}

.container .flex-item {
flex: 0 0 1;
width: 25%;
height: 80px;
margin: 10px;
position: relative;
background: #ccc;
}

.container .flex-item .widget {
width: 70px;
height: 70px;
background-color: #004990;
border-radius: 50%;
position: absolute;
top: -35px;
right: -35px;
z-index:1;
}
<div class="container">
<div class="flex-item">
<div class="widget"></div>
</div>
<div class="flex-item">
<div class="widget"></div>
</div>
<div class="flex-item">
<div class="widget"></div>
</div>
<div class="flex-item">
<div class="widget"></div>
</div>
</div>


Related Topics



Leave a reply



Submit