Question Y a-t-il un sélecteur CSS "frère précédent"?


+ est pour le prochain frère. Y a-t-il un équivalent pour le frère précédent?


1031
2017-11-30 04:06


origine


Réponses:


Non, il n'y a pas de sélecteur "frère précédent".

Sur une note connexe, ~ est pour successeur général frère (ce qui signifie que l'élément vient après celui-ci, mais pas nécessairement immédiatement après) et est un sélecteur CSS3. + est pour le prochain frère et est CSS2.1.

Voir Combinateur frère / sœur adjacent de Sélecteurs Niveau 3 et 5.7 Sélecteurs de frères adjacents de Feuilles de style en cascade Niveau 2 Révision 1 (CSS 2.1).


665
2017-11-30 04:08



J'ai trouvé un moyen de styliser tous les frères et soeurs précédents (à l'opposé de ~) qui peut fonctionner selon ce dont vous avez besoin.

Supposons que vous ayez une liste de liens et que, lorsque vous passez la souris sur l'un d'entre eux, tous les liens précédents deviennent rouges. Vous pouvez le faire comme ceci:

/* 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>


160
2018-01-16 22:45



Les sélecteurs de niveau 4 introduisent :has() (auparavant l'indicateur sujet !) qui vous permettra de sélectionner un frère précédent avec:

previous:has(+ next) {}

... mais au moment de l'écriture, il y a une certaine distance au-delà de la limite pour le support du navigateur.


118
2018-03-19 15:19



Prendre en compte order propriété des configurations flex et grid.

Je vais me concentrer sur la flexbox dans les exemples ci-dessous, mais les mêmes concepts s'appliquent à Grid.


Avec flexbox, un sélecteur de frère précédent peut être simulé.

En particulier, le flex order la propriété peut déplacer des éléments autour de l'écran.

Voici un exemple:

Vous voulez que l'élément A devienne rouge lorsque l'élément B est survolé.

<ul>
    <li>A</li>
    <li>B</li>
</ul>

PAS

  1. Faire le ul un conteneur flexible.

    ul { display: flex; }
    

  1. Inverser l'ordre des frères et sœurs dans la marge bénéficiaire.

    <ul>
       <li>B</li>
       <li>A</li>
    </ul>
    

  1. Utilisez un sélecteur de frère pour cibler l'élément A (~ ou + ça ira) .

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

  1. Utilisez le flex order propriété pour restaurer l'ordre des frères et sœurs sur l'affichage visuel.

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

... et voilà! Un sélecteur de fratries précédent est né (ou au moins simulé).

Voici le code complet:

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>

De la spécification de flexbox:

5.4. Afficher la commande: le order propriété

Les éléments Flex sont, par défaut, affichés et disposés dans le même ordre qu'ils apparaissent dans le document source. le    order la propriété peut être utilisée pour changer cette commande.

le order La propriété contrôle l'ordre dans lequel les éléments flex apparaissent dans le conteneur Flex, en les affectant à des groupes ordinaux. Il faut un seul <integer> valeur, qui spécifie quel groupe ordinal l'élément flexible   appartient à.

La première order La valeur pour tous les éléments Flex est 0.

Regarde aussi order dans les spécifications CSS Grid Layout.


Exemples de "sélecteurs de frères précédents" créés avec le flex order propriété.

.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>

jsFiddle


Une note secondaire - Deux croyances périmées sur CSS

Flexbox bouleverse les croyances de longue date sur CSS.

Une telle croyance est que un sélecteur de frère précédent n'est pas possible en CSS.

Dire que cette croyance est répandue serait un euphémisme. Voici un échantillon de questions connexes sur Stack Overflow seul:

Comme décrit ci-dessus, cette croyance n'est pas entièrement vraie. Un sélecteur de frère précédent peut être simulé en CSS en utilisant le flex order propriété.

le z-index Mythe

Une autre croyance de longue date a été que z-index ne fonctionne que sur les éléments positionnés.

En fait, la version la plus récente de la spécification - la Le brouillon de l'éditeur du W3C - affirme toujours ceci pour être vrai:

9.9.1 Spécification du niveau de la pile: le z-index   propriété

z-index

  • Valeur: auto | | hériter
  • Initiale: auto
  • S'applique à: éléments positionnés
  • Héritée: non
  • Pourcentages: N / A
  • Média: visuel
  • Valeur calculée: comme spécifié

(c'est nous qui soulignons)

En réalité, cependant, cette information est obsolète et inexacte.

Les éléments qui sont éléments flexibles ou éléments de la grille peut créer des contextes d'empilement même lorsque position est static.

4.3. Flex Item Z-Commande

Les éléments Flex peignent exactement de la même manière que les blocs en ligne, sauf que l'ordre des documents modifiés par ordre est utilisé à la place des blocs bruts   ordre du document, et z-index valeurs autres que auto créer un contexte d'empilement même si position est static.

5.4. Commande d'axe Z: le z-index propriété

L'ordre de peinture des éléments de la grille est exactement le même que celui des blocs en ligne, sauf que l'ordre des documents modifiés par ordre est   utilisé à la place de l'ordre des documents bruts, et z-index valeurs autres que auto créer un contexte d'empilement même si    position est static.

Voici une démonstration de z-index travailler sur des éléments flex non positionnés: https://jsfiddle.net/m0wddwxs/


99
2018-03-20 18:49



J'ai eu la même question, mais j'ai eu un moment "duh". Au lieu d'écrire

x ~ y

écrire

y ~ x

Évidemment, cela correspond à "x" au lieu de "y", mais il répond à "Y at-il un match?" question, et simple traversée DOM peut vous rendre à l'élément de droite plus efficacement que de boucler en javascript.

Je me rends compte que la question originale était une question de CSS donc cette réponse est probablement complètement hors de propos, mais d'autres utilisateurs de Javascript peuvent trébucher sur la question via la recherche comme je l'ai fait.


65
2017-11-30 16:40



Deux des trucs. Inverser fondamentalement l'ordre HTML de vos éléments souhaités en HTML et en utilisant
~  Prochains frères et soeurs opérateur:

float-right  + inverser l'ordre des éléments 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;
} 
<div>
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>


Parent avec direction: rtl; + inverser l'ordre des éléments internes

.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>


20
2017-08-19 01:52



Une autre solution flexbox

Vous pouvez utiliser inverse l'ordre des éléments en HTML. Ensuite, en plus d'utiliser order un péché La réponse de Michael_B vous pouvez utiliser flex-direction: row-reverse; ou flex-direction: column-reverse; en fonction de votre disposition.

Échantillon de travail:

.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>


11
2018-01-14 17:33



Il n'y a pas de moyen officiel pour le faire en ce moment mais vous pouvez utiliser un petit truc pour y arriver! Rappelez-vous que c'est expérimental et qu'il y a certaines limites ... (vérifier ce lien si vous vous inquiétez de la compatibilité du navigateur)

Ce que vous pouvez faire est d'utiliser un sélecteur CSS3: la pseudo-classe appelée 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>

Limites

  • Vous ne pouvez pas sélectionner les éléments précédents en fonction des classes des éléments suivants
  • C'est la même chose pour les pseudo-classes

11
2017-09-03 16:16