O sinal de mais ( +) é para o próximo irmão.
Existe um equivalente para o irmão anterior?
O sinal de mais ( +) é para o próximo irmão.
Existe um equivalente para o irmão anterior?
Respostas:
Não, não há seletor "irmão anterior".
Em uma nota relacionada, ~é para irmão sucessor geral (ou seja, o elemento vem após este, mas não necessariamente imediatamente após) e é um seletor CSS3. +é para o próximo irmão e é CSS2.1.
Consulte Combinador de irmão adjacente dos seletores de nível 3 e 5,7 Seletores de irmão adjacente da especificação de revisão 2 do Cascading Style Sheets Level 2 Revisão 1 (CSS 2.1) .
Encontrei uma maneira de estilizar todos os irmãos anteriores (opostos a ~) que podem funcionar dependendo do que você precisa.
Digamos que você tenha uma lista de links e, ao passar o mouse sobre um deles, 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;
}
<div class="parent">
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
</div>
float:right). Exigiu um colapso de espaço em branco entre unidades / palavras e preenchimento em vez de margens, mas funciona perfeitamente de outra maneira!
O nível 4 dos seletores apresenta:has() (anteriormente o indicador de assunto !) que permitirá que você selecione um irmão anterior com:
previous:has(+ next) {}
… Mas, no momento da redação, está a uma certa distância do limite do suporte do navegador.
:has()pseudo-classe.
orderpropriedade 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 de irmão anterior pode ser simulado.
Em particular, a orderpropriedade flex pode mover elementos pela tela.
Aqui está um exemplo:
Você deseja que o elemento A fique vermelho quando o elemento B estiver pairando.
<ul> <li>A</li> <li>B</li> </ul>
PASSOS
Faça ulum recipiente flexível.
ul { display: flex; }Inverta a ordem dos irmãos na marcação.
<ul>
<li>B</li>
<li>A</li>
</ul>Use um seletor de irmão para direcionar o elemento A ( ~ou +fará).
li:hover + li { background-color: red; }Use a orderpropriedade flex para restaurar a ordem dos irmãos na exibição visual.
li:last-child { order: -1; }... e pronto! Nasce um seletor de irmãos anterior (ou pelo menos simulado).
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;
}
<ul>
<li>B</li>
<li>A</li>
</ul>
Na especificação do flexbox:
5.4 Ordem de exibição: a
orderpropriedadeOs itens flexíveis são, por padrão, exibidos e dispostos na mesma ordem em que aparecem no documento de origem. A
orderpropriedade pode ser usada para alterar essa ordem.A
orderpropriedade controla a ordem na qual os itens flexíveis aparecem no contêiner flexível, atribuindo-os a grupos ordinais. É necessário um<integer>valor único , que especifica a qual grupo ordinal o item flexível pertence.
O ordervalor inicial para todos os itens flexíveis é 0.
Veja também orderna especificação CSS Grid Layout .
Exemplos de "seletores de irmãos anteriores" criados com a orderpropriedade flex .
.container { display: flex; }
.box5 { order: 1; }
.box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }
.box6 { order: -4; }
.box7 { order: -3; }
.box8 { order: -2; }
.box9 { order: -1; }
.box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
font-size: 1.5em; }
.box12 { order: 2; }
.box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
font-size: 1.5em; }
.box21 { order: 1; }
.box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }
/* non-essential decorative styles */
.container {
padding: 5px;
background-color: #888;
}
.box {
height: 50px;
width: 75px;
margin: 5px;
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
cursor: pointer;
}
<p>
Using the flex <code>order</code> property to construct a previous sibling selector
</p>
<div class="container">
<div class="box box1"><span>1</span></div>
<div class="box box2"><span>2</span></div>
<div class="box box3"><span>3</span></div>
<div class="box box5"><span>HOVER ME</span></div>
<div class="box box4"><span>4</span></div>
</div>
<br>
<div class="container">
<div class="box box9"><span>HOVER ME</span></div>
<div class="box box12"><span>HOVER ME</span></div>
<div class="box box6"><span>6</span></div>
<div class="box box7"><span>7</span></div>
<div class="box box8"><span>8</span></div>
<div class="box box10"><span>10</span></div>
<div class="box box11"><span>11</span></div>
</div>
<br>
<div class="container">
<div class="box box21"><span>HOVER ME</span></div>
<div class="box box13"><span>13</span></div>
<div class="box box14"><span>14</span></div>
<div class="box box15"><span>15</span></div>
<div class="box box16"><span>16</span></div>
<div class="box box17"><span>17</span></div>
<div class="box box18"><span>18</span></div>
<div class="box box19"><span>19</span></div>
<div class="box box20"><span>20</span></div>
</div>
O Flexbox está quebrando crenças antigas sobre CSS.
Uma dessas crenças é que um seletor de irmãos anterior não é possível no CSS .
Dizer que essa crença é generalizada seria um eufemismo. Aqui está uma amostra de perguntas relacionadas apenas no Stack Overflow:
Como descrito acima, essa crença não é totalmente verdadeira. Um seletor de irmão anterior pode ser simulado em CSS usando a orderpropriedade flex .
O z-indexMito
Outra crença de longa data tem sido que z-indexfunciona apenas em elementos posicionados.
De fato, a versão mais atual da especificação - o Rascunho do Editor W3C - ainda afirma que isso é verdade:
9.9.1 Especificando o nível da pilha: a
z-indexpropriedade
z-index
- Valor: auto | | herdar
- Inicial: auto
- Aplica-se a: elementos posicionados
- Herdado: não
- Porcentagens: N / A
- Mídia: visual
- Valor calculado: conforme especificado
(enfase adicionada)
Na realidade, porém, essas informações são obsoletas e imprecisas.
Elementos que são itens flexíveis ou itens de grade podem criar contextos de empilhamento mesmo quando positionsão static.
Os itens flexíveis pintam exatamente da mesma forma que os blocos embutidos, exceto que a ordem de documento modificada por ordem é usada no lugar da ordem bruta de documento e
z-indexvalores diferentes deautocriar um contexto de empilhamento, mesmo quepositionsejastatic.5.4 Ordenação do eixo Z: a
z-indexpropriedadeA ordem de pintura dos itens de grade é exatamente igual aos blocos embutidos, exceto que a ordem de documento modificada pela ordem é usada no lugar da ordem bruta de documento e
z-indexvalores diferentes deautocriar um contexto de empilhamento, mesmo quepositionsejastatic.
Aqui está uma demonstração do z-indextrabalho em itens flexíveis não posicionados: https://jsfiddle.net/m0wddwxs/
orderpropriedade não é uma solução, pois se destina exclusivamente a alterar a ordem visual , portanto, não restaura a ordem semântica original que você é forçado a alterar em HTML para que esta solução alternativa funcione.
z-indexfuncionará, mesmo quando "omg, não há positionespecificado!", A especificação menciona o conceito de contexto de empilhamento , o que é bem explicado por este artigo no MDN
float: right(ou qualquer outro meio de reverter a ordem, dos quais flex/ordertem poucos (menos?) Efeitos colaterais). Incitou dois violinos: demonstrando a float: rightabordagem , e demonstrandodirection: rtl
Eu tinha 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 a "existe uma correspondência?" pergunta, e uma simples passagem de DOM pode levá-lo ao elemento certo de forma mais eficiente do que fazer loop em javascript.
Sei que a pergunta original era CSS, portanto essa resposta provavelmente é completamente irrelevante, mas outros usuários de Javascript podem tropeçar na pergunta por meio de pesquisa, como eu fiz.
y ~ xpoderia resolver o meu problema
y ~ xnão responde a "existe uma correspondência?" pergunta, porque os dois seletores dados aqui significam coisas completamente diferentes. Não há como y ~ xproduzir uma correspondência, dada a subárvore, <root><x/><y/></root>por exemplo. Se a pergunta é "você existe?" então o seletor é simplesmente y. Se a pergunta é "y existe dado um irmão x em alguma posição arbitrária?" então você precisaria dos dois seletores. (Embora talvez eu esteja apenas procurando neste momento ...)
Dois truques . Invertendo basicamente a ordem HTML dos elementos desejados em HTML e usando o operador
~ Next siblings :
float-right + inverter a ordem dos elementos HTMLdiv{ /* 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;
}
<div>
<!-- Reverse the order of inner elements -->
<span>5</span>
<span>4</span>
<span>3</span>
<span>2</span>
<span>1</span>
</div>
direction: rtl;+ inversa da ordem dos elementos internos.inverse{
direction: rtl;
display: inline-block; /* inline-block to keep parent at the left of window */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
background:gold;
}
Hover one span and see the previous elements being targeted!<br>
<div class="inverse">
<!-- Reverse the order of inner elements -->
<span>5</span>
<span>4</span>
<span>3</span>
<span>2</span>
<span>1</span>
</div>
+é para o próximo irmão. Existe um equivalente para o irmão anterior?
! e?Existem 2 seletores de irmãos subsequentes no CSS convencional:
+é o imediato seletor de irmão subsequente~é o qualquer selector irmão subsequenteNo CSS convencional, não há seletor de irmãos anterior .
No entanto, na biblioteca pós-processador CSS de machado , existem 2 seletores de irmãos anteriores :
?é o seletor de irmão anterior imediato (oposto a +)!é o seletor de qualquer irmão anterior (oposto a ~)Exemplo de trabalho:
No exemplo abaixo:
.any-subsequent:hover ~ div seleciona qualquer subseqüente div.immediate-subsequent:hover + div seleciona o subseqüente imediato div.any-previous:hover ! div seleciona qualquer anterior div.immediate-previous:hover ? div seleciona o anterior imediato divdiv {
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;
}
<h2>Hover over any of the blocks below</h2>
<div></div>
<div></div>
<div class="immediate-previous">Hover for <code>?</code> selector</div>
<div class="any-previous">Hover for <code>!</code> selector</div>
<div class="any-subsequent">Hover for <code>~</code> selector</div>
<div class="immediate-subsequent">Hover for <code>+</code> selector</div>
<div></div>
<div></div>
<script src="https://rouninmedia.github.io/axe/axe.js"></script>
Você pode usar a ordem inversa dos elementos em HTML. Além de usar ordercomo 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 i.e. 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%;
}
<div class="flex">
<div class="flex-item">5</div>
<div class="flex-item">4</div>
<div class="flex-item">3</div>
<div class="flex-item">2</div>
<div class="flex-item">1</div>
</div>
Não há uma maneira oficial de fazer isso no momento, mas você pode usar um pequeno truque para conseguir isso! Lembre-se de que é experimental e tem algumas limitações ... (verifique este link se estiver preocupado com a compatibilidade do navegador)
O que você pode fazer é usar um seletor CSS3: a pseudo classe 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;
}
<p>The oranges elements are the previous sibling li selected using li:nth-child(-n+4)</p>
<div id="list">
<span>1</span><!-- this will be selected -->
<p>2</p><!-- this will be selected -->
<p>3</p><!-- this will be selected -->
<div>4</div><!-- this will be selected -->
<div>5</div>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
</div>
:nth-child(-n+4)é uma pseudo classe que precisa ser aplicada a um seletor para funcionar corretamente. Se você não é convencido, tente experimentá-lo usando um garfo do meu violino e verá que ele não funciona
*seletor, mas é uma prática desagradável.
li#someListIteme eu queria o (s) nó (s) logo antes (que é como eu interpreto "anterior") - não vejo como as informações que você forneceu podem me ajudar a expressar isso por meio do CSS. Você está apenas selecionando os primeiros n irmãos e suponha que eu conheça o n. Com base nessa lógica, qualquer seletor pode fazer o truque e selecionar o (s) elemento (s) que eu preciso (como: not ()).
Se você souber a posição exata, uma :nth-child()exclusão baseada em todos os irmãos a seguir funcionaria.
ul li:not(:nth-child(n+3))
O que selecionaria todos os lis antes do 3º (por exemplo, 1º e 2º). Mas, na minha opinião, isso parece feio e tem um caso de uso muito restrito.
Você também pode selecionar o enésimo filho da direita para a esquerda:
ul li:nth-child(-n+2)
O que faz o mesmo.
Não. Não é possível via CSS. Leva o "Cascade" ao coração ;-).
No entanto, se você conseguir adicionar JavaScript à sua página, um pouco de jQuery poderá levá-lo ao seu objetivo final.
Você pode usar o jQuery findpara executar um "olhar em frente" em seu elemento / classe / ID de destino e depois voltar para selecionar seu destino.
Então você usa o jQuery para reescrever o DOM (CSS) para seu elemento.
Com base nesta resposta de Mike Brant , o seguinte trecho de jQuery pode ajudar.
$('p + ul').prev('p')
Isso primeiro seleciona todos os <ul>s que seguem imediatamente a <p>.
Em seguida, "recua" para selecionar todos os <p>s anteriores desse conjunto de <ul>s.
Efetivamente, "irmão anterior" foi selecionado via jQuery.
Agora, use a .cssfunção para passar no seu CSS novos valores para esse elemento.
No meu caso, eu estava procurando uma maneira de selecionar um DIV com o id #full-width, mas SOMENTE se ele tivesse um DIV descendente (indireto) com a classe de .companies.
Eu tinha o controle de todo o HTML abaixo .companies, mas não podia alterar nenhum do HTML acima dele.
E a cascata segue apenas 1 direção: para baixo.
Assim, eu poderia selecionar ALL #full-widths.
Ou eu poderia selecionar .companiesque apenas seguisse a #full-width.
Mas eu poderia não selecionar apenas #full-widths que procedeu .companies .
E, novamente, não consegui adicionar .companies mais no HTML. Essa parte do HTML foi escrita externamente e envolveu nosso código.
Porém, com o jQuery, posso selecionar os #full-widths necessários e atribuir o estilo apropriado:
$("#full-width").find(".companies").parents("#full-width").css( "width", "300px" );
Isso encontra tudo #full-width .companiese seleciona apenas aqueles .companiessemelhantes à maneira como os seletores são usados para direcionar elementos específicos no padrão em CSS.
Em seguida, ele usa .parents"backtrack" e seleciona TODOS os pais de .companies,
mas filtra esses resultados para manter apenas #fill-widthelementos, para que, no final,
selecione apenas um #full-widthelemento se tiver um .companiesdescendente de classe.
Por fim, atribui um novo widthvalor CSS ( ) ao elemento resultante.
$(".parent").find(".change-parent").parents(".parent").css( "background-color", "darkred");
div {
background-color: lightblue;
width: 120px;
height: 40px;
border: 1px solid gray;
padding: 5px;
}
.wrapper {
background-color: blue;
width: 250px;
height: 165px;
}
.parent {
background-color: green;
width: 200px;
height: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div class="wrapper">
<div class="parent">
"parent" turns red
<div class="change-parent">
descendant: "change-parent"
</div>
</div>
<div class="parent">
"parent" stays green
<div class="nope">
descendant: "nope"
</div>
</div>
</div>
Target <b>"<span style="color:darkgreen">parent</span>"</b> to turn <span style="color:red">red</span>.<br>
<b>Only</b> if it <b>has</b> a descendant of "change-parent".<br>
<br>
(reverse cascade, look ahead, parent un-descendant)
</html>
Documentos de referência do jQuery:
$ () ou jQuery () : elemento DOM.
. find : obtenha os descendentes de cada elemento no conjunto atual de elementos correspondentes, filtrados por um seletor, objeto jQuery ou elemento.
. pais : obtenha o irmão imediatamente anterior de cada elemento no conjunto de elementos correspondentes. Se um seletor for fornecido, ele recuperará o irmão anterior apenas se corresponder a esse seletor (filtra os resultados para incluir apenas os elementos / seletores listados).
. css : defina uma ou mais propriedades CSS para o conjunto de elementos correspondentes.
previousElementSibling).
previousElementSibling()para aqueles que estão mais familiarizados com as funções JS DOM nativas, pode fornecer outro caminho não CSS.
+ seletor (inexistente) solicitado pelo OP. Considere esta resposta como um "hack" em JS. Está aqui para poupar o tempo que passei para encontrar uma solução.
Infelizmente, não há seletor de irmãos "anterior", mas é possível ainda obter o mesmo efeito usando posicionamento (por exemplo flutuador direita). Depende do que você está tentando fazer.
No meu caso, eu queria um sistema de classificação CSS de 5 estrelas. Eu precisaria colorir (ou trocar o ícone) das estrelas anteriores. Ao flutuar cada elemento corretamente, estou obtendo essencialmente 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)
+ou ~seletores me parece o trabalho mais limpo.
Dependendo do seu objetivo exato, existe uma maneira de obter a utilidade de um seletor pai sem usar um (mesmo que exista) ...
Digamos que temos:
<div>
<ul>
<li><a>Pants</a></li>
<li><a>Socks</a></li>
<ul>
<li><a>White socks</a></li>
<li><a>Blue socks</a></li>
</ul>
</ul>
</div>
O que podemos fazer para que o bloco Meias (incluindo cores) se destaque visualmente usando espaçamento?
O que seria legal, 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 para 0 para aqueles sem elementos UL (ou outras tags) dentro das LIs.
Eu precisava de uma solução para selecionar o irmão anterior tr. Eu vim com essa solução usando componentes React e Styled. Esta não é a minha solução exata (isso é da memória, horas depois). Eu sei que há uma falha na função setHighlighterRow.
OnMouseOver uma linha definirá o índice da linha para estado e renderizará a linha anterior com uma nova cor de plano de fundo
class ReactClass extends Component {
constructor() {
this.state = {
highlightRowIndex: null
}
}
setHighlightedRow = (index) => {
const highlightRowIndex = index === null ? null : index - 1;
this.setState({highlightRowIndex});
}
render() {
return (
<Table>
<Tbody>
{arr.map((row, index) => {
const isHighlighted = index === this.state.highlightRowIndex
return {
<Trow
isHighlighted={isHighlighted}
onMouseOver={() => this.setHighlightedRow(index)}
onMouseOut={() => this.setHighlightedRow(null)}
>
...
</Trow>
}
})}
</Tbody>
</Table>
)
}
}
const Trow = styled.tr`
& td {
background-color: ${p => p.isHighlighted ? 'red' : 'white'};
}
&:hover {
background-color: red;
}
`;
Não existe, e existe .
Se você deve colocar o rótulo antes da entrada, em vez disso, mantenha o rótulo e a entrada dentro de uma div e denomine a div da seguinte maneira:
.input-box {
display: flex;
flex-direction: column-reverse;
}
<div class="input-box">
<input
id="email"
class="form-item"
/>
<label for="email" class="form-item-header">
E-Mail*
</label>
</div>
Agora você pode aplicar as opções de estilo padrão para o próximo irmão disponíveis em css, e elas aparecerão como se você estivesse usando um estilo anterior para o irmão.
Eu tive um problema semelhante e descobri que todos os problemas dessa natureza podem ser resolvidos da seguinte maneira:
Dessa forma, você poderá estilizar seus itens atuais e anteriores (todos os itens substituídos pelos 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;
}
<ul>
<li>Tea</li>
<li class="milk">Milk</li>
<li>Juice</li>
<li>others</li>
</ul>
Espero que ajude alguém.