Categories
css css-selectors siblings

Is there a “previous sibling” selector?

1677

The plus sign (+) is for selecting the next sibling.

Is there an equivalent for the previous sibling?

4

  • you don’t need it because you can do everything with the combination of the general selector plus the next sibling selector.

    Jan 14, 2021 at 18:23

  • 5

    I’m not sure you can in all cases, and even if so – it’s very hard to read and reason about and therefore should be added as a convenience imo

    May 13, 2021 at 10:36

  • which combinator can use for parent selector ?, @GabrielLinassi

    – vishal

    Feb 23 at 11:52

  • This can be achieved using: display: flex; flex-direction: row-reverse;

    – Scott

    Mar 11 at 21:31


972

No, there is no “previous sibling” selector.

On a related note, ~ is for general successor sibling (meaning the element comes after this one, but not necessarily immediately after) and is a CSS3 selector. + is for next sibling and is CSS2.1.

See Adjacent sibling combinator from Selectors Level 3 and 5.7 Adjacent sibling selectors from Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification.

4

  • 20

    From the CSS3 standard: The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.

    – Lie Ryan

    Feb 26, 2011 at 16:34


  • 31

    @Lie Ryan: Yeah, but the point cletus is making in his answer is that you don’t select the preceding element.

    – BoltClock

    Mar 29, 2011 at 21:05


  • 53

    Here’s an example I made to see what this can, and can’t, do. jsfiddle.net/NuuHy/1

    – Abacus

    Jul 17, 2013 at 18:26

  • 11

    The jquery function useful for this is prev(). For example $(“#the_element”).prev().css(“background-color”, “red”)

    May 18, 2015 at 21:11

328

I found a way to style all previous siblings (opposite of ~) that may work depending on what you need.

Let’s say you have a list of links and when hovering on one, all the previous ones should turn red. You can do it like this:

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

6

  • 23

    You can add an explanation of how it works. (it seems that you apply an style to all the items and to the following items but it can de described explicitly)

    – A.L

    Apr 24, 2015 at 17:04

  • 13

    yea, but a single previous is needed most of the time NOT ALL the previous ones!

    – azerafati

    May 1, 2016 at 15:15

  • 70

    The links all turn red if I hover over the space between them, for me.

    – Lynn

    Aug 1, 2016 at 8:19

  • All tags turn red when hovering over the parent–but at the same time not hovering over any of the child a tags–due to the .parent:hover a style.

    Nov 10, 2021 at 17:35

  • @Lynn @JoeVanLeeuwen yes, this example only includes the minimum amount of rules to target previous siblings. To remove spacing you’d need to add more rules, probably changing the display of the contender

    – mantish

    Nov 12, 2021 at 10:30

229

Selectors level 4 proposes :has() (previously the subject indicator !) which will, one day, allow you to select a previous sibling with:

previous:has(+ next) {}

… but at the time of writing browser support is practically non-existent.


Over the years this answer has attracted dozens of “It’s still not supported” comments (now deleted). Please don’t add any more. There’s a link to an up to date browser support chart in the answer.

0