简体   繁体   中英

Using 'order' property to position flex item between siblings

I have a flex-box with one to three flex-items.

The proper layout should look like <div></div><h2></h2><div></div> in the containing flex-box.

I have code to make this work (see this ) only if the layout order stays the same.

My question is: how is there a way to make sure, if the markup is not always in that order (say one of my co-workers fails to do it correctly), how can I set it so that the <h2> always gets displayed in the middle (or as close as possible in the case that there are only one div and one h2).

To accomplish this I have been making use of the order property; however, I am either not using it to its full potential or it is the wrong solution.

I have made this jsfiddle as a testing ground for it but there is also this sample:

.diff-order {
  order: 2
}
.diff-order:not(h2) {
  order: 1;
}

 .container { display: flex; } .container > * { flex: 1; /* KEY RULE */ border: 1px dashed red; } h2 { text-align: center; margin: 0; } .container > div { display: flex; } .diff-order { order: 2 } .diff-order:not(h2) { order: 1; } p { text-align: center;} p > span { background-color: aqua; padding: 5px; } 
 <div class="container"> <h2> I'm an h2 </h2> <div> <span>I'm a span</span> <span>I'm a span</span> </div> <div> <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 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> 

What it accomplishes is it moves the <h2> to the end of the containing div. I am trying to see if there is a way to set the order so that <h2> will always be the center item. Maybe the pseudo-classes :before and :after can be utilized (maybe as replacements for the div's around the h2...).

Thank you.

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> 


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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM