CSS: Select Last Ordered Flex Children

get last child when using Flex order Css

If you're really determined to do it like this, you can use javascript to find the last element that doesn't have the orderFirst class and style that. This does seem like a mis-use of the order property, though.

const mainWrap = document.querySelector(".mainWrap");

const children = [...mainWrap.children];
const ordered = children.filter((c) => !c.classList.contains("orderFirst"));

const last = ordered.pop();
last.style.setProperty("border-bottom", "none");
.mainWrap {
display: flex;
flex-direction: column;
}

.item {
order: 2;
border-bottom:1px solid #ccc;
}

.item.orderFirst {
order: 1;
}
<div class="mainWrap">
<div class="item">first</div>
<div class="item">second</div>
<div class="item orderFirst">third</div>
<div class="item">fourth</div>
<div class="item orderFirst">fifth</div>
<div class="item">Six</div>
<div class="item orderFirst">Seven</div>
</div>

Targeting flex items on the last or specific row

Unfortunately, in the current iteration of flexbox (Level 1), there is no clean way to solve the last-row alignment problem. It's a common problem.

It would be useful to have a flex property along the lines of:

  • last-row
  • last-column
  • only-child-in-a-row
  • alone-in-a-column

This problem does appear to be a high priority for Flexbox Level 2:

  • CSS Working Group Wiki - Specification Issues and Planning
  • https://lists.w3.org/Archives/Public/www-style/2015Jan/0150.html

Although this behavior is difficult to achieve in flexbox, it's simple and easy in CSS Grid Layout:

  • Equal width flex items even after they wrap

In case Grid is not an option, here's a list of similar questions containing various flexbox hacks:

  • Properly sizing and aligning the flex item(s) on the last row
  • Flex-box: Align last row to grid
  • Flexbox wrap - different alignment for last row
  • How can a flex item keep the same dimensions when it is forced to a new row?
  • Selector for an element alone in a row?
  • Aligning elements in last flexbox row
  • How can I allow flex-items to grow while keeping the same size?
  • Left-align last row of flexbox using space-between and margins
  • Inconsistent margin between flex items on last row
  • How to keep wrapped flex-items the same width as the elements on the previous row?
  • How to align left last row/line in multiple line flexbox
  • Last children of grid get giant gutter cause of flexbox space-between
  • Managing justify-content: space-between on last row
  • Flexbox space between behavior combined with wrap
  • Possible to use CSS Flexbox to stretch elements on every row while maintaining consistent widths?

Select last 3 children based on the number of children

Is this what you are looking for?

.flex-item:first-child:nth-last-child(7)

targets the first child when there are only 7 items so that

.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(n+5)

is only triggered when there are 7 items

.flex-container {  display: flex;  flex-flow: row wrap;  justify-content: space-between;  padding: 0;  margin: 0;  list-style: none;}
.flex-item { background: tomato; padding: 5px; width: 200px; height: 150px; margin-top: 10px; line-height: 150px; color: white; font-weight: bold; font-size: 3em; text-align: center;}
.flex-item:first-child:nth-last-child(7),.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(-n+4) { flex-basis: 23%;}
.flex-item:first-child:nth-last-child(7)~.flex-item:nth-child(n+5) { flex-basis: 31%; background: blue;}
<ul class="flex-container">  <li class="flex-item first">1</li>  <li class="flex-item">2</li>  <li class="flex-item">3</li>  <li class="flex-item">4</li>  <li class="flex-item">5</li>  <li class="flex-item">6</li>  <li class="flex-item">7</li></ul><br/><br/><ul class="flex-container">  <li class="flex-item first">1</li>  <li class="flex-item">2</li>  <li class="flex-item">3</li>  <li class="flex-item">4</li>  <li class="flex-item">5</li>  <li class="flex-item">6</li>  <li class="flex-item">7</li>  <li class="flex-item">8</li>  <li class="flex-item">9</li>  <li class="flex-item">10</li></ul><br/><br/><ul class="flex-container">  <li class="flex-item first">1</li>  <li class="flex-item">2</li>  <li class="flex-item">3</li>  <li class="flex-item">4</li>  <li class="flex-item">5</li></ul>

Position last flex item at the end of container

Flexible Box Layout Module - 8.1. Aligning with auto margins

Auto margins on flex items have an effect very similar to auto margins in block flow:

  • During calculations of flex bases and flexible lengths, auto margins are treated as 0.

  • Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.

Therefore you could use margin-top: auto to distribute the space between the other elements and the last element.

This will position the last element at the bottom.

p:last-of-type {
margin-top: auto;
}

.container {
display: flex;
flex-direction: column;
border: 1px solid #000;
min-height: 200px;
width: 100px;
}
p {
height: 30px;
background-color: blue;
margin: 5px;
}
p:last-of-type {
margin-top: auto;
}
<div class="container">
<p></p>
<p></p>
<p></p>
</div>

Order flex item at last position always

Normally the elements are laid out in the order of their appearance in the markup. However you can specify an implicit ordering using the order property in css. This will place elements according to their order. If two elements have the same value for this order property, they will stay be layed out following the original markup. In a way you can see it as form of grouping: first the ones with order 0, then with order 1, .... (setting a negative value for order would of course place them before the 0 group; that is how the -1 trick to place the element first works)

You can use this solve your problem by simply setting the order of the second child to 1, all other elements will have the default value of 0 so be placed before.

.child:nth-child(2) {
order: 1;
}

How can I show my flex child first with order: 1 without setting order: 2, etc. on the remaining children?

The initial value of order is zero for all flex items. Flex items with the same order value are laid out according to how they appear in the source. So to place a flex item first, you can simply give it order: -1 instead of order: 1, and you do not have to worry about how many other items there are:

.default-address {
order: -1;
}

Changing the order of a flex-container's child elements dynamically

This should work nicely for you:

.container > .nav.active {
order: -1;
}

See it working here:

var nav = $(".container");
var sections = $(".section");

$(window).on("scroll", function() {
var cur_pos = $(this).scrollTop();

sections.each(function() {
var top = $(this).offset().top,
bottom = top + $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find(".nav").removeClass("active");
nav.find("." + $(this)[0].id).addClass("active");
}
});
});
.container {
display: flex;
gap: 30px;
position: sticky;
justify-content: center;
top: 0;
}

.container .nav {
border: 1px solid black;
}

div.active {
background-color: black;
color: white;
}

.section {
height: 350px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}

.section.one {
background-color: yellow;
}

.section.two {
background-color: red;
}

.section.three {
background-color: green;
}

.section.four {
background-color: blue;
}

.section.five {
background-color: purple;
}

.container > .nav.active {
order: -1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="container">
<div class="nav one">item 1</div>
<div class="nav two">item 2</div>
<div class="nav three">item 3</div>
<div class="nav four">item 4</div>
<div class="nav five">item 5</div>
</div>

<div class="section one" id="one">item 1</div>
<div class="section two" id="two">item 2</div>
<div class="section three" id="three">item 3</div>
<div class="section four" id="four">item 4</div>
<div class="section five" id="five">item 5</div>


Related Topics



Leave a reply



Submit