Existe um seletor CSS “irmão anterior”?

+ é para o próximo irmão. Existe um equivalente para o irmão anterior?

Não, não há um seletor “irmão anterior”.

Em uma nota relacionada, ~ é para o irmão sucessor geral (o que significa que o elemento vem depois deste, mas não necessariamente imediatamente depois) e é um seletor CSS3. + é para o próximo irmão e é CSS2.1.

Veja Combinador irmão adjacente dos seletores de nível 3 e 5.7 Seletores de irmãos adjacentes da Especificação de CSS de Nível 2 da Cascading Style Sheets, nível 2, Revisão 1 (CSS 2.1) .

Eu encontrei uma maneira de estilizar todos os irmãos anteriores (oposto de ~ ) que podem funcionar dependendo do que você precisa.

Digamos que você tenha uma lista de links e, ao passar o mouse sobre um, todos os anteriores devem ficar vermelhos. Você pode fazer assim:

 /* default link color is blue */ .parent a { color: blue; } /* prev siblings should be red */ .parent:hover a { color: red; } .parent a:hover, .parent a:hover ~ a { color: blue; } 
  

Seletores de nível 4 introduzem :has() (anteriormente o indicador de assunto ! ) Que lhe permitirá selecionar um irmão anterior com:

 previous:has(+ next) {} 

… Mas, no momento em que escrevo, está a alguma distância além do limite para o suporte ao navegador.

Considere a propriedade de order dos layouts flex e grid.

Vou me concentrar no flexbox nos exemplos abaixo, mas os mesmos conceitos se aplicam ao Grid.


Com o flexbox, um seletor irmão anterior pode ser simulado.

Em particular, a propriedade de order flexível pode mover elementos ao redor da canvas.

Aqui está um exemplo:

Você deseja que o elemento A fique vermelho quando o elemento B for pairado.

 
  • A
  • B

PASSOS

  1. Faça o ul um recipiente flexível.

     ul { display: flex; } 

  1. Inverta a ordem dos irmãos no markup.

     
    • B
    • A

  1. Use um seletor de irmãos para direcionar o Elemento A ( ~ ou + irá fazer).

     li:hover + li { background-color: red; } 

  1. Use a propriedade de order flexível para restaurar a ordem dos irmãos na exibição visual.

     li:last-child { order: -1; } 

… e voilà! Um seletor irmão anterior nasce (ou pelo menos simula).

Aqui está o código completo:

 ul { display: flex; } li:hover + li { background-color: red; } li:last-child { order: -1; } /* non-essential decorative styles */ li { height: 200px; width: 200px; background-color: aqua; margin: 5px; list-style-type: none; cursor: pointer; } 
 
  • B
  • A

Eu tive a mesma pergunta, mas depois tive um momento “duh”. Em vez de escrever

 x ~ y 

Escreva

 y ~ x 

Obviamente, isso corresponde a “x” em vez de “y”, mas responde “existe uma correspondência?” pergunta, e simples travessia DOM pode levá-lo para o elemento certo de forma mais eficiente do que o loop em javascript.

Eu percebo que a pergunta original era uma questão de CSS, então essa resposta é provavelmente completamente irrelevante, mas outros usuários de Javascript podem tropeçar na questão através da pesquisa como eu fiz.

Dois truques . Basicamente invertendo a ordem HTML de seus elementos desejados em HTML e usando
~ Próximo operador de irmãos :

float-right + inverte a ordem dos elementos HTML

 div{ /* Do with the parent whatever you know just to make the inner float-right elements appear where desired */ display:inline-block; } span{ float:right; /* float-right the elements! */ } span:hover ~ span{ /* On hover target it's "previous";) elements */ background:red; } 
 
5 4 3 2 1

+ é para o próximo irmão. Existe um equivalente para o irmão anterior?

Você pode usar os dois seletores de machado :! e ?

Existem dois seletores irmãos subsequentes no CSS convencional:

  • + é o seletor irmão imediato subseqüente
  • ~ é o seletor irmão subsequente

No CSS convencional, não há seletor de irmãos anterior .

No entanto, na biblioteca de pós-processador CSS do ax , há dois seletores irmãos:

  • ? é o seletor irmão anterior imediato (oposto de + )
  • ! é o seletor irmão anterior (oposto de ~ )

Exemplo de trabalho:

No exemplo abaixo:

  • .any-subsequent:hover ~ div seleciona qualquer div subsequente
  • .immediate-subsequent:hover + div seleciona o div subsequente imediato
  • .any-previous:hover ! div .any-previous:hover ! div seleciona qualquer div anterior
  • .immediate-previous:hover ? div .immediate-previous:hover ? div seleciona o div anterior imediato
 div { display: inline-block; width: 60px; height: 100px; color: rgb(255, 255, 255); background-color: rgb(255, 0, 0); text-align: center; vertical-align: top; cursor: pointer; opacity: 0; transition: opacity 0.6s ease-out; } code { display: block; margin: 4px; font-size: 24px; line-height: 24px; background-color: rgba(0, 0, 0, 0.5); } div:nth-of-type(-n+4) { background-color: rgb(0, 0, 255); } div:nth-of-type(n+3):nth-of-type(-n+6) { opacity: 1; } .any-subsequent:hover ~ div, .immediate-subsequent:hover + div, .any-previous:hover ! div, .immediate-previous:hover ? div { opacity: 1; } 
 

Hover over any of the blocks below

Hover for ? selector
Hover for ! selector
Hover for ~ selector
Hover for + selector

Outra solução flexbox

Você pode usar o inverso da ordem dos elementos em HTML. Então, além de usar order como na resposta de Michael_B, você pode usar flex-direction: row-reverse; ou flex-direction: column-reverse; dependendo do seu layout.

Amostra de trabalho:

 .flex { display: flex; flex-direction: row-reverse; /* Align content at the "reversed" end ie beginning */ justify-content: flex-end; } /* On hover target its "previous" elements */ .flex-item:hover ~ .flex-item { background-color: lime; } /* styles just for demo */ .flex-item { background-color: orange; color: white; padding: 20px; font-size: 3rem; border-radius: 50%; } 
 
5
4
3
2
1

Não há nenhuma maneira oficial de fazer isso no momento, mas você pode usar um pequeno truque para conseguir isso! Lembre-se que é experimental e tem alguma limitação … (verifique este link se você se preocupa com a compatibilidade do navegador)

O que você pode fazer é usar um seletor CSS3: a pseudo class chamada nth-child()

 #list>* { display: inline-block; padding: 20px 28px; margin-right: 5px; border: 1px solid #bbb; background: #ddd; color: #444; margin: 0.4em 0; } #list :nth-child(-n+4) { color: #600b90; border: 1px dashed red; background: orange; } 
 

The oranges elements are the previous sibling li selected using li:nth-child(-n+4)

1

2

3

4
5

6

7

8

9

Se você souber a posição exata, uma exclusão baseada em :nth-child() de todos os irmãos seguintes funcionaria.

 ul li:not(:nth-child(n+3)) 

Qual selecionaria todos os li antes do 3º (por exemplo, 1º e 2º). Mas, na minha opinião, isso parece feio e tem um uso muito apertado.

Você também pode selecionar a n-filho da direita para a esquerda:

 ul li:nth-child(-n+2) 

O que faz o mesmo.

Não há um seletor de irmãos “anterior” infelizmente, mas você ainda pode obter o mesmo efeito usando o posicionamento (por exemplo, flutuar para a direita). Depende do que você está tentando fazer.

No meu caso, eu queria um sistema de sorting CSS de 5 estrelas. Eu precisaria colorir (ou trocar o ícone de) as estrelas anteriores. Flutuando cada elemento corretamente, eu estou essencialmente obtendo o mesmo efeito (o html para as estrelas deve ser escrito ‘para trás’).

Estou usando FontAwesome neste exemplo e trocando entre os unicodes de fa-star-o e fa-star http://fortawesome.github.io/Font-Awesome/

CSS:

 .fa { display: inline-block; font-family: FontAwesome; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* set all stars to 'empty star' */ .stars-container { display: inline-block; } /* set all stars to 'empty star' */ .stars-container .star { float: right; display: inline-block; padding: 2px; color: orange; cursor: pointer; } .stars-container .star:before { content: "\f006"; /* fontAwesome empty star code */ } /* set hovered star to 'filled star' */ .star:hover:before{ content: "\f005"; /* fontAwesome filled star code */ } /* set all stars after hovered to'filled star' ** it will appear that it selects all after due to positioning */ .star:hover ~ .star:before { content: "\f005"; /* fontAwesome filled star code */ } 

HTML: (40)

JSFiddle: http://jsfiddle.net/andrewleyva/88j0105g/

Dependendo do seu objective exato, existe uma maneira de obter a utilidade de um seletor pai sem usar um (mesmo se houvesse um) …

Diga que temos:

  

O que podemos fazer para que o bloco Socks (incluindo as colors das meias) se destaque visualmente usando o espaçamento?

O que seria bom, mas não existe:

 ul li ul:parent { margin-top: 15px; margin-bottom: 15px; } 

O que existe

 li > a { margin-top: 15px; display: block; } li > a:only-child { margin-top: 0px; } 

Isso define todos os links de âncora para ter uma margem de 15px na parte superior e redefine-o de volta para 0 para aqueles sem elementos UL (ou outras tags) dentro de LIs.

Eu tive um problema semelhante e descobri que todo problema dessa natureza pode ser resolvido da seguinte maneira:

  1. Dê a todos os seus itens um estilo.
  2. dê ao item selecionado um estilo.
  3. dê aos itens seguintes um estilo usando + ou ~.

e desta forma você será capaz de estilizar seus itens atuais e anteriores (todos os itens sobrescritos com itens atuais e seguintes) e seus próximos itens.

exemplo:

 /* all items (will be styled as previous) */ li { color: blue; } /* the item i want to distinguish */ li.milk { color: red; } /* next items */ li ~ li { color: green; } 
  • Tea
  • Milk
  • Juice
  • others

Espero que ajude alguém.

Como já foi dito muitas vezes – com div ~ p todos os elementos

que são precedidos por um elemento

são selecionados.

Confira esta lista de todos os seletores CSS.