How to Target The First and The Last Element Per Row in a Flex Layout

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?

Targeting the last div before flexbox or float wraps the rest

Basically what @vals said, but with some more details:

  • Let all flex items have the same margin-right, m.
  • Set the widths accordingly. For example, if you want n equal elements in a row, set width: calc(100%/n - m).
  • Let the flex container overflow its containing block, in order to hide the unwanted margin margin. Use margin: -m to achieve this.
  • Place the flex container in a wrapper with overflow: hidden.

.wrapper {  overflow: hidden;  border: 1px solid;}.flex {  display: flex;  flex-wrap: wrap;  margin-right: -2%;  text-align: center;}span {  margin-right: 2%;  border: 1px solid red;  box-sizing: border-box;}span:nth-child(-n + 3) { width: calc(100%/2  - 2%); }span:nth-child(n + 6)  { width: calc(100%/3  - 2%); }span:nth-child(1)      { width: calc(100%    - 2%); }span:nth-child(4)      { width: calc(100%*.4 - 2%); }span:nth-child(5)      { width: calc(100%*.6 - 2%); }
<div class="wrapper">  <div class="flex">    <span>100%</span>    <span>49%</span>    <span>49%</span>    <span>39%</span>    <span>59%</span>    <span>32%</span>    <span>32%</span>    <span>32%</span>  </div></div>

Keep the first and last items in a flex box on one row while moving the rest beneath it

Here is the flex solution, with order + min-width tricks.

View the JsFiddle demo, resize and see.

.wrap {    display: flex;    flex-wrap: wrap;    justify-content: space-between;}.wrap > .a {    background: lime;    order: 1;}.wrap > .b {    background: orange;    order: 2;    flex: 1;}.wrap > .c {    background: aqua;    order: 3;}@media screen and (max-width: 500px) {    .wrap > .b {        background: orange;        order: 3;        min-width: 100%;    }    .wrap > .c {        background: aqua;        order: 2;    }}
<div class="wrap">    <div class="a">A</div>    <div class="b">B</div>    <div class="c">C</div></div>

Flex-box: Align last row to grid

Add a ::after which autofills the space. No need to pollute your HTML. Here is a codepen showing it: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}

.grid::after {
content: "";
flex: auto;
}

Flex Box Last Row element

I need even space

Then use margin. Here's a combination with calc().

Simple math: 100% of full width - (3 elements in the row with the left and right margin, ergo, 6) divided by 3.

* {  box-sizing: border-box;  margin: 0;  padding: 0;}
*:after,*:before { box-sizing: border-box;}
.flex-container { display: flex; flex-wrap: wrap; flex-direction: row;}
.flex-container div { flex-basis: calc((100% - 6%)/3); margin: 1%; border: 1px solid #ccc; padding: 10px;}
<div class="flex-container">  <div>1</div>  <div>2</div>  <div>3</div>  <div>4</div>  <div>5</div></div>

style only first item in each flexbox row

As @AndyHoffman already mentioned in the comments, (as of March 2019) it is impossible to do it with pure css. If you tolerate a bit of javascript, then you could iterate over all the flex children and see if their position indicates that they are in the first column and apply styling accordingly. A rudimentary example is shown in the snippet below:

function highlightFirst(){  let flexChildren = document.querySelectorAll('.content');  let leftPosition = flexChildren[0].offsetLeft;  for(let flexChild of flexChildren){    if(flexChild.offsetLeft <= leftPosition){      flexChild.classList.add('firstColumn');    }else{      flexChild.classList.remove('firstColumn');    }  }}window.addEventListener('resize', highlightFirst);highlightFirst();
* {  list-style:none;  margin: 0;  padding: 0;}
.wrapper { display: flex; flex-wrap: wrap; border: solid 1px black;}
.content { height: 20px; background: grey; margin: 5px;}
.firstColumn { border: 2px dashed red;}
<ul class="wrapper">    <li class="content" style="width:  14px;">1</li>    <li class="content" style="width:  77px;">2</li>    <li class="content" style="width:  41px;">3</li>    <li class="content" style="width:  94px;">4</li>    <li class="content" style="width:  76px;">5</li>    <li class="content" style="width:  61px;">6</li>    <li class="content" style="width:  81px;">7</li>    <li class="content" style="width:  70px;">8</li>    <li class="content" style="width:  22px;">9</li>    <li class="content" style="width:  29px;">10</li>    <li class="content" style="width:  27px;">11</li>    <li class="content" style="width:  22px;">12</li>    <li class="content" style="width:  56px;">13</li>    <li class="content" style="width:  32px;">14</li>    <li class="content" style="width:  55px;">15</li>    <li class="content" style="width:  34px;">16</li>    <li class="content" style="width:  75px;">17</li>    <li class="content" style="width:  97px;">18</li>    <li class="content" style="width:  25px;">19</li>    <li class="content" style="width:  48px;">20</li></ul>


Related Topics



Leave a reply



Submit