Задать свойства css для элемента, если предыдущий элемент считается :last-child

Есть пример кода. В нем мы видим, что у двух div есть класс new-alert-item. Как прописать свойства css для одного div class="nf-line", который стоит после последнего div new-alert-item? Количество new-alert-item не статично, их число постоянно меняется.

.alerts .new-alert-item:last-child ~ .nf-line{
  border: 1px solid #000;
}
<div class="alerts">
  <div class="alert-item-wrapp new-alert-item">1</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp new-alert-item">2</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">3</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">4</div>
  <div class="nf-line"></div>
</div>


Ответы (4 шт):

Автор решения: Инквизитор

"Задать свойства css для элемента, если предыдущий элемент считается :last-child" - полный бред. Если элемент ":last-child", он по определению не может быть "предыдущим", он последний (у данного родителя).

nth-of-type() и last-of-type не сработают, т.к. у вас всё <div>'ы. Но если бы вы могли элементы с классом new-alert-item сделать какими-то другими, то получилось бы.

Конкретно в вашей ситуации, если заранее неизвестно количество элементов с классом new-alert-item, то без JS не обойтись. Ну а если их именно два, то можно так:

.alerts .new-alert-item~.new-alert-item+.nf-line {
  border: 1px solid #000;
}
<div class="alerts">
  <div class="alert-item-wrapp new-alert-item">1</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp new-alert-item">2</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">3</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">4</div>
  <div class="nf-line"></div>
</div>

→ Ссылка
Автор решения: Qwertiy

После того, как появится поддержка селектора :has, вероятно, заработает такое (если у кого есть сафари 15.4+, прокомментируйте пожалуйста):

.new-alert-item + .nf-line:not(:has(~ .new-alert-item)) {
  border: 1px solid #000;
  min-height: 1em;
}
<div class="alerts">
  <div class="alert-item-wrapp new-alert-item">1</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp new-alert-item">2</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">3</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">4</div>
  <div class="nf-line"></div>
</div>

→ Ссылка
Автор решения: Qwertiy

Возможно, подойдёт что-то такое:

.alerts {
  display: flex;
  flex-direction: column;
}

.alert-item-wrapp {
  order: 1;
}

.new-alert-item {
  order: -1;
}

.alerts::after {
  content: "";
  height: 1em;
  background: silver;
}
<div class="alerts">
  <div class="alert-item-wrapp new-alert-item">1</div>
  <div class="alert-item-wrapp new-alert-item">2</div>
  <div class="alert-item-wrapp">3</div>
  <div class="alert-item-wrapp">4</div>
</div>

→ Ссылка
Автор решения: De.Minov

Запись .elem:nth-child(2) вернёт не второй элемент из всех .elem, а именно второй из всех элементов которые есть в том же родителе, в котором находится ..
Т.е. запись .parent .elem:nth-child(2) будет эквивалентен .parent *:nth-child(2).

Да, было бы круто если бы было так же как document.getElementsByClassName('.elem')[1], но увы.
Вашу логику проще реализовать на JS.

let selector = document.querySelectorAll('.new-alert-item');
let selectorLast = selector[selector.length - 1]
let selectorNext = selectorLast.nextElementSibling; // берём следующий элемент у последнего `.new-alert-item`


if(selectorNext.classList.contains('nf-line')) // если след. элемент `.nf-line`
  selectorNext.style.border = '1px solid #000'; // то выдаём ему бордер
else
  selectorLast.insertAdjacentHTML('afterend', '<div class="nf-line" style="border: 1px solid #000"></div>'); // Если нет, то создаём такой элемент.
<div class="alerts">
  <div class="alert-item-wrapp new-alert-item">1</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp new-alert-item">2</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">3</div>
  <div class="nf-line"></div>
  <div class="alert-item-wrapp">4</div>
  <div class="nf-line"></div>
</div>

Так же можно вообще убрать .nf-line, JS его создаст.

let selector = document.querySelectorAll('.new-alert-item');
let selectorLast = selector[selector.length - 1]
let selectorNext = selectorLast.nextElementSibling; // берём следующий элемент у последнего `.new-alert-item`


if(selectorNext.classList.contains('nf-line')) // если след. элемент `.nf-line`
  selectorNext.style.border = '1px solid #000'; // то выдаём ему бордер
else
  selectorLast.insertAdjacentHTML('afterend', '<div class="nf-line" style="border: 1px solid #000"></div>'); // Если нет, то создаём такой элемент.
<div class="alerts">
  <div class="alert-item-wrapp new-alert-item">1</div>
  <div class="alert-item-wrapp new-alert-item">2</div>
  <div class="alert-item-wrapp">3</div>
  <div class="alert-item-wrapp">4</div>
</div>

→ Ссылка