Seletor para uma tag seguida diretamente por outra tag

88

Isso seleciona todas as <B>tags diretamente precedidas por <A>tags:

A+B {
    /* styling */
}

Qual é o seletor para todas as <A>tags seguidas diretamente por <B>tags?

Aqui está um exemplo de HTML adequado à minha pergunta:

<a>some text</a>
<b>some text</b>
Mostafa Farghaly
fonte
3
Por favor, dê-nos um exemplo de DOM como Ae Bestão relacionados.
Gumbo
2
Eles estão relacionados por serem irmãos, e B é seguido por A. O OP deseja selecionar todos os bs que são seguidos por as, semelhante a a+bonde você pode selecionar todos os bs que são precedidos diretamente por a.
Anthony,
2,5 anos depois, há alguma atualização para essa resposta? Também estou procurando segmentar a seguido por b.
chovy

Respostas:

29

Você não pode em css.

Editar: Para ser um pouco mais útil, se você usar, por exemplo, jQuery (uma biblioteca JavaScript), você pode usar .prev().

Jeroen
fonte
parece que a única solução está usando JavaScript
Mostafa Farghaly
2
Obrigado Jeroen! Isso resolveu meu problema. Visto que meu "A" flutua para a esquerda e "B" flutua para a direita, não importa a ordem em que coloquei a marcação.
BobRodes
53

Você quer definir o estilo A dado que tem um elemento B diretamente dentro ou seguido? Como isso:

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

// OR

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

Você não pode fazer isso em CSS (ainda). Eric Meyer afirma que este tipo de seletor foi discutido algumas vezes na lista de discussão CSS e não é factível. Dave Hyatt, um dos principais desenvolvedores do WebKit, comenta com uma boa explicação de por que isso não pode ser feito.

Confira: postagem no blog de Shaun Inman e o comentário de Eric Meyer .
David Hyatt também pesa .

Nick Presta
fonte
quero dizer, o segundo, eu entendo o problema, obrigado, nick :)
Mostafa Farghaly
17

Você pode SOMENTE fazer o inverso: isso seleciona todas as marcas diretamente precedidas por marcas.

Isso é logicamente equivalente ao seu pedido.

Costumo usar isso para definir o estilo de uma linha de muitas caixas de seleção com rótulos

CSS:

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

DOM:

<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>
Marco Marsala
fonte
3
Acho que você quis digitar "entrada + rótulo" no CSS para que a margem esquerda seja aplicada ao rótulo.
CAK2 de
1
@ CAK2 - Acho que ele quis dizer isso direito. Ao fazer label+inputa margem é aplicada a todos os inputelementos a partir do segundo . É uma forma criativa de criar espaço entre eles, mas não no início ou no final da fila. Nesse caso, é equivalente a input:not(:first-child).
David
1

Embora não seja muito útil, hoje em dia você pode conseguir esse comportamento invertendo a ordem de seus elementos ao gerar o HTML e aplicando as regras de CSS: display: flexeflex-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>

Além disso, se você tiver 2 ou mais elementos embutidos, poderá obtê-lo aplicando float: right, pois eles serão exibidos na ordem inversa:

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>

Mihai Matei
fonte