4
votes

I am wondering if there is a CSS selector that would auto-magically target the last div on a row created by either flexbox or floats.

In our particular use, we have an image grid with different width images. In its full width, there are rows with 3 images (each 33%) and rows with 2 images (50/50 or 60/40). When viewed with a vertical tablet all images change to 50% and it is two per row, on a phone 100%. All of the images are within a single overall container, not row containers (because of the three becoming two).

Like many grid type layouts we have a 2% margin-right, that needs to be reset to 0 on the right most div.

Currently using the traditional "last" class to remove the margin manually and a pseudo :nth-child(odd) to manipulate the vertical tablet layout. I am playing with two variations, one using floats and one using flexbox.

Is there a single css selector that would target the last div in each case?


Expanding on layouts:

On full sized monitor
|img1 - 33%|2%|img2 - 33%|2%|img3 - 33%|
|img4 - 40%|2%|img5 - 60%|
|img6 - 33%|2%|img7 - 33%|2%|img8 - 33%|

On a vertical tablet
|img1 - 50%|2%|img2 - 50%|
|img3 - 50%|2%|img4 - 50%|
|img5 - 50%|2%|img6 - 50%|
|img7 - 50%|2%|img8 - 50%|

On phone
|img1 - 100%|
|img2 - 100%|
|img3 - 100%|
|img4 - 100%|
etc ps I know my percentages do not add up.

2
Could you provide some example HTML, and indicate within it which element you want targeted? It's a bit hard to follow.Super Cat
If they were in row containers, using :last-child would solve the problem. As they are not, I don't think CSS would be able to guess what's the last div of each row.lucasnadalutti
@lucasnadalutti yes that would make life easier, but the number of divs changes per row as the viewer width narrowsTom
Sorry guys, posted an answer here which was intended to be for another question. Deleted already.lucasnadalutti
Are you using media queries? Flexbox magic? Please include your code. And see if Multiple flexboxes with margin-right, except the last one in the row? helps.Oriol

2 Answers

3
votes

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>
2
votes

No, there is not a cool CSS selector that can achieve this.

The only way that I know to get this efect easily is to set a wrapper to your flexbox container.

Let all the elements inside the flexbox container to have the same 2% margin right.

And set the flexbox container to have a 2% overflow to the right of the wrapper, that will be hidden. So you get the illusion that the elements align with the right border of the wrapper.