Селектор для одного тега, за которым следует другой тег

88

Это выбирает все <B>теги непосредственно предшествовавшие по <A>тэгам:

A+B {
    /* styling */
}

Какой селектор для всех <A>тегов, за которыми следуют<B> теги?

Вот пример HTML, соответствующий моему вопросу:

<a>some text</a>
<b>some text</b>
Мостафа Фергалы
источник
3
Пиз дает нам пример DOM, как Aи Bсвязаны.
Gumbo
2
Они связаны тем, что являются братьями и сестрами, а за B следует A. OP хочет выбрать все bs, за которыми следует as, аналогично тому, a+bгде вы можете выбрать все bs, которым непосредственно предшествует a.
Энтони
Есть ли обновление этого ответа 2,5 года спустя? Я также ищу цель a, за которой следует b.
chovy

Ответы:

29

Вы не можете использовать css.

Изменить: чтобы быть немного более полезным, если вы используете, например, jQuery (библиотека JavaScript), вы можете использовать .prev().

jeroen
источник
похоже,
2
Спасибо, jeroen! Это устранило мою проблему. Поскольку у меня «A» плавает влево, а «B» - вправо, не имело значения, в каком порядке я поместил разметку.
BobRodes
53

Вы имеете в виду стилизовать A, учитывая, что у него есть элемент B непосредственно внутри или за ним? Как это:

<A>
    <B>
    </B>
</A>

// OR

<A>
</A>
<B>
</B>

Вы не можете сделать это в CSS (пока). Эрик Мейер заявляет, что этот вид селектора довольно много раз обсуждался в списке рассылки CSS, и его невозможно реализовать. Дэйв Хаятт, один из основных разработчиков WebKit, дает хорошее объяснение того, почему это невозможно.

Проверьте: сообщение в блоге Шона Инмана и комментарий Эрика Мейера .
Дэвид Хаятт тоже весит .

Ник Преста
источник
я имею в виду второй, я понимаю, в чем проблема, спасибо, ник :)
Мостафа Фергали
17

Вы можете делать ТОЛЬКО обратное: выбираются все теги, которым непосредственно предшествуют теги.

Это логически эквивалентно вашему запросу.

Я часто использую это, чтобы стилизовать ряд из многих флажков с помощью меток.

CSS:

label+input {
    margin-left: 4px;
}

ДОМ:

<input id="a" name="a" type="checkbox"/><label for="a">...</label>
<input id="b" name="b" type="checkbox"/><label for="b">...</label>
<input id="c" name="c" type="checkbox"/><label for="c">...</label>
Марко Марсала
источник
3
Я думаю, вы хотели ввести «input + label» в CSS, чтобы к метке применялось поле margin-left.
CAK2,
1
@ CAK2 - Думаю, он имел в виду все правильно. При этом label+inputмаржа применяется ко всем inputэлементам, начиная со второго . Это творческий способ создать пространство между ними, но не в начале или в конце ряда. В данном случае это эквивалентно input:not(:first-child).
Дэвид
1

Хотя это не очень удобно, в настоящее время вы можете добиться такого поведения, изменив порядок ваших элементов как при генерации HTML, так и путем применения правил CSS: display: flexиflex-direction: column-reverse

ul {
  display: flex;
  flex-direction: column-reverse;
}

.b ~ .a {
  color: red;
}
<ul>
    <li class="a">A 3</li>
    <li class="c">C 2</li>
    <li class="c">C 1</li>
    <li class="b">B 1</li>
    <li class="a">A 2</li>
    <li class="a">A 1</li>
</ul>

Кроме того, если у вас есть 2 или более встроенных элемента, вы можете добиться этого, применив float: right, поскольку они будут отображаться в обратном порядке:

ul {
  float: left;
  list-style-type: none;
}

li {
  float: right;
}

li:not(:first-child) {
  margin-right: 20px;
}

.b ~ .a {
  color: red;
}
<ul>
    <li class="a">A 3</li>
    <li class="c">C 2</li>
    <li class="c">C 1</li>
    <li class="b">B 1</li>
    <li class="a">A 2</li>
    <li class="a">A 1</li>
</ul>

Михай Матей
источник