CSS: последний n-й ребенок до n % 3 == 0

#css

Вопрос:

У меня есть небольшая сетка элементов, в строках не более 3 элементов перед переносом в следующую строку.

 [] [] []
[] [] []
[]
 
 <div style="display: flex; flex-wrap: wrap;">
  <div style="width: 33%" />
  <div style="width: 33%" />
  <div style="width: 33%" />
  <div style="width: 33%" />
  <div style="width: 33%" />
  <div style="width: 33%" />
  <div style="width: 33%" />
</div>
 

(встроенные стили используются только для краткости)

То, что я хочу сделать, это указать a margin-bottom для всех элементов, кроме тех, которые находятся в самой последней строке. Я не совсем уверен , как это сделать, так как мне, по сути, нужно ориентироваться на последнее nth-child до тех пор, пока n % 3 == 0 , но CSS, похоже, не обладает такой возможностью.

Есть ли вообще возможность делать здесь то, что я хочу?

Комментарии:

1. У вас также есть возможность указать верхний предел для всех элементов, кроме первых 3 🙂

2. Может быть, это то, что вы ищете, Выбрав последнюю строку сетки в CSS

3. @BrunoSdoukos, с опцией, о которой я сказал, мы будем использовать margin-top для всех, кроме первых 3, нам не нужно знать, сколько элементов в любой строке.

4. @CharanKumar Вау, вот это да… супер очевидное решение, о котором я должен был подумать. Мило! Хотите, чтобы это был ответ, чтобы я мог его принять?

5. Опубликовано в качестве ответа

Ответ №1:

Это похоже на проблему XY, поэтому я не собираюсь прямо отвечать на ваш вопрос и вместо этого предлагаю эту альтернативу:

Я бы рекомендовал использовать display: grid вместо display: flex , но независимо от этого вы должны использовать row-gap родительский элемент, а не пытаться использовать margin его на любом из дочерних элементов:

 .parent {
  column-gap: 1em;
  display: grid;
  /* gap: 1em; - this is a shorthand for column-gap and row-gap */
  grid-template-columns: repeat(3, 1fr);
  row-gap: 1em;
}

.parent > * {
  background-color: black;
  height: 50px;
} 
 <div class="parent">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div> 

Комментарии:

1. даже у flexbox есть свойство gap

2. Не интересуют пробелы или сетка.

Ответ №2:

Вы можете сделать, как показано ниже:

 .box {
  display:flex;
  flex-wrap:wrap;
  
}
.box * {
  flex:0 0 30%;
  margin:5px;
  height:50px;
  background:red;
}

.box *:nth-last-child(1),
.box *:nth-last-child(2):nth-child(3n   2),
.box *:nth-last-child(2):nth-child(3n   1),
.box *:nth-last-child(3):nth-child(3n   1) {
  background:blue;
} 
 <div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div> 

Другой синтаксис, использующий :is()

 .box {
  display:flex;
  flex-wrap:wrap;
  
}
.box * {
  flex:0 0 30%;
  margin:5px;
  height:50px;
  background:red;
}

.box *:nth-last-child(1),
.box *:nth-last-child(2):is(:nth-child(3n   1),:nth-child(3n   2)),
.box *:nth-last-child(3):nth-child(3n   1) {
  background:blue;
} 
 <div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div> 

Ответ №3:

@Devildude4427: простое альтернативное решение состоит в том, чтобы установить верхний предел для всех элементов, за исключением первых 3 элементов (которые будут в первой строке), в которых вам не нужно беспокоиться о том, что будет в конце.