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

+ est pour le frère suivant. Est-il un équivalent pour le précédent frère?

1064
demandé sur Dmitry Gonchar 2009-11-30 07:06:36

14 réponses

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

Sur une note connexe, "151900920 générale successeur de frère (le sens de l'élément qui vient après celui-ci, mais pas nécessairement immédiatement après) et un sélecteur de CSS3. + est pour le frère suivant et est CSS2.1.

voir combinateur pour frères et sœurs Adjacent à partir de sélecteurs Niveau 3 et 5.7 sélecteurs pour frères et sœurs adjacents à partir de Feuilles de Style en Cascade Niveau 2 Révision 1 (CSS 2.1) Spécification .

687
répondu cletus 2012-02-22 19:11:29

j'ai trouvé un moyen de style tous les frères et sœurs précédents (à l'opposé de ~ ) qui peut fonctionner selon ce que vous avez besoin.

disons que vous avez une liste de liens et quand le curseur est sur, tous les précédents devraient devenir rouge. 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>
166
répondu mantish 2015-01-20 15:12:17

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

previous:has(+ next) {}

... mais au moment de l'écriture, il est quelque distance au-delà du bord de saignement pour le soutien du navigateur.

125
répondu Quentin 2018-02-05 05:50:02

réfléchir "à l'151990920" propriété du flex et de la grille de mises en page.

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


avec flexbox, il est possible de simuler un sélecteur jumeau précédent.

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

voici un exemple:

vous voulez que l'élément a devienne rouge quand l'élément B est en vol stationnaire.

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

STEPS

  1. faire le ul un conteneur souple.



    ul { display: flex; }
    

  1. inverser la ordre des frères et sœurs dans la marge.



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

  1. utiliser un sélecteur de fratrie pour cibler L'élément A ( ~ ou + suffira) .



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

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



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

...et voilà!! Un sélecteur de frères et sœurs précédent est né (ou du 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 flexbox:

5.4. Ordre d'affichage: la order propriété

Flex éléments sont, par défaut, affiché et présenté dans le même ordre qu'ils apparaissent dans le document source. Le La propriété order peut être utilisée pour modifier cette commande.

la propriété order contrôle l'ordre dans lequel les articles flex apparaissent dans le conteneur flex, en les assignant à l'ordinal groupes. Il prend une seule valeur <integer> , qui spécifie quel groupe ordinal l'article flex appartenir.

la valeur initiale order pour tous les éléments flex est 0.

voir Aussi order dans le CSS de la Grille de Mise en page spec .


exemples de "frères et sœurs précédents" sélecteurs " créé avec la propriété flex order .

.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 de Côté – Deux Obsolète Croyances à propos de CSS

Flexbox brise les croyances de longue date sur CSS.

L'une de ces croyances est que a il n'est pas possible de sélectionner un frère ou une sœur dans CSS .

dire que cette croyance est répandue serait un euphémisme. Voici un échantillon de questions connexes sur le seul débordement des cheminées:

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

Le z-index Mythe

une autre croyance de longue date est que z-index ne fonctionne que sur des éléments positionnés.

In en fait, la version la plus récente du spec – le W3C Editor's Draft – affirme toujours que c'est vrai:

9.9.1 spécifiant le niveau de la pile: le z-index biens

z-index

  • valeur: auto / / inherit
  • initiale: auto
  • S'applique aux éléments de positionnement
  • hérité: non
  • Pourcentages: N /D
  • Médias: visuel
  • valeur reconstituée: comme spécifié

(italique ajouté)

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

Éléments flex articles ou éléments de la grille peut créer des contextes d'empilement, même quand 1519270920" est static .

4.3. Flex Article Z-Commande

Flex éléments de la peinture exactement la même qu'en ligne de blocs, à l'exception de cet ordre-modification de l'ordre du document est utilisé à la place de raw l'ordre des documents et les valeurs z-index autres que auto créent un contexte de cumul même si position est static .

5.4. Ordre de L'axe Z: la z-index propriété

le 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 du document brut, et les valeurs z-index autres que auto créent un contexte de cumul même si position est static .

voici une démonstration de z-index travaillant sur des articles flex Non positionnés: https://jsfiddle.net/m0wddwxs /

105
répondu Michael_B 2018-03-11 22:30:15

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

x ~ y

écrire

y ~ x

évidemment cela correspond à " x "au lieu de" y", mais il répond au "y a-t-il un match?"question, et DOM simple transversal peut vous amener à l'élément droit plus efficacement que la boucle en javascript.

je me rends compte que la question originale était une question CSS donc cette réponse est probablement complètement non pertinent, mais D'autres utilisateurs de Javascript peuvent tomber sur la question via la recherche comme je l'ai fait.

67
répondu Bryan Larsen 2011-11-30 16:40:40

deux tricks . Essentiellement en inversant L'ordre HTML de vos éléments souhaités en HTML et en utilisant

~ suivant frères et sœurs 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; + inverse l'ordre de éléments intérieurs

.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
répondu Roko C. Buljan 2015-10-29 01:54:32

il n'y a aucune façon officielle de le faire pour le 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 ... (cochez ce lien si vous vous souciez de la compatibilité avec le 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>

Limitations

  • Vous ne pouvez pas sélectionner les éléments précédents basés sur les classes de la prochaine éléments
  • c'est la même chose pour les pseudo classes
13
répondu 0x1gene 2018-05-25 14:24:02

+ est pour le frère suivant. Est-il un équivalent pour la précédente sœur?

vous pouvez utiliser les deux axe sélecteurs: ! et ?

il y a 2

  • + est le immédiat sélecteur de frères et sœurs subséquents
  • ~ est le tout sélecteur de frères

dans le CSS conventionnel, il n'y a aucun autre sélecteur de frères et sœurs .

Toutefois, dans le hache CSS post-processeur de la bibliothèque, il y a 2 frère précédent sélecteurs:

  • ? est le immédiate frère précédent sélecteur (à l'opposé des + )
  • ! est le any sélecteur de frères et sœurs précédent (opposé de ~ )

Exemple Pratique:

dans l'exemple ci-dessous:

  • .any-subsequent:hover ~ div div
  • .immediate-subsequent:hover + div sélectionne la suite immédiate div
  • .any-previous:hover ! div sélectionne une précédente div
  • .immediate-previous:hover ? div sélectionne le précédent immédiat div

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;
}
<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>
12
répondu Rounin 2018-06-20 18:38:18

une autre solution flexbox

vous pouvez utiliser l'ordre inverse des éléments en HTML. Ensuite, en plus d'utiliser order comme dans réponse de Michael_B vous pouvez utiliser flex-direction: row-reverse; ou flex-direction: column-reverse; selon 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
répondu Vadim Ovchinnikov 2017-07-24 18:15:14

si vous connaissez la position exacte, une exclusion basée sur :nth-child() de tous les frères et sœurs suivants fonctionnerait.

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

qui sélectionnerait tous les li s avant le 3ème (par ex. 1er et 2ème). Mais, à mon avis, cela a l'air moche et a un usecase très serré.

vous pouvez également sélectionner le nième enfant de droite à gauche:

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

Qui fait la même chose.

4
répondu kernel 2014-08-29 15:27:40

il n'y a malheureusement pas de sélecteur" précédent", mais vous pouvez peut-être encore obtenir le même effet en utilisant le positionnement (par exemple flotteur à droite). Cela dépend de ce que vous essayez de faire.

dans mon cas, je voulais un système d'évaluation 5 étoiles CSS. J'aurais besoin de colorer (ou d'échanger l'icône de) les étoiles précédentes. En faisant flotter chaque élément à droite, j'obtiens essentiellement le même effet (le html pour les étoiles doit donc être écrit 'en arrière').

J'utilise FontAwesome dans cet exemple et j'échange entre les unicodes de fa-star-o et 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/

2
répondu Andrew Leyva 2014-08-12 19:54:13

selon votre objectif exact, il y a un moyen d'obtenir l'utilité d'un sélecteur parent sans en utiliser un (même s'il en existe un)...

Disons que nous avons:

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

Que pouvons-nous faire pour que les chaussettes (y compris les couleurs des chaussettes) se distinguent visuellement par leur espacement?

Ce serait bien, mais n'existe pas:

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

Ce qui n'existe pas:

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

définit tous les liens d'ancrage pour avoir une marge de 15px sur le dessus et le réinitialise à 0 pour ceux qui n'ont pas D'éléments UL (ou d'autres tags) à l'intérieur de LIs.

1
répondu DynamicDan 2015-07-11 09:23:07

j'ai eu un problème similaire et j'ai découvert que tous les problèmes de cette nature peuvent être résolus comme suit:

  1. donnez à tous vos articles un style.
  2. donnez un style à votre article sélectionné.
  3. donnez aux éléments suivants un style en utilisant + ou ~.

et de cette façon, vous serez en mesure de style vos articles actuels, antérieurs(tous les éléments overridden avec les articles actuels et à venir) et vos prochains articles.

exemple:

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

J'espère que ça aidera quelqu'un.

0
répondu Hejar 2018-02-23 16:38:00

comme il a déjà été dit plusieurs fois - avec div ~ p tous les éléments <p> qui sont précédés d'un élément <div> sont sélectionnés.

vérifier cette liste de tous les sélecteurs CSS.

-4
répondu Nesha Zoric 2018-04-04 12:54:15