Logo

Is there a "previous sibling" selector in CSS?

CSS does not provide a direct “previous sibling” selector. You can only select siblings after an element (e.g., + for adjacent sibling or ~ for general siblings). You cannot natively traverse backward in standard CSS. However, emerging CSS features and certain workarounds may partially emulate this in some cases.

1. Why There’s No Previous Sibling Selector

Classic CSS has always been designed to match elements in a top-down flow—selectors proceed from a parent to its children or from left to right among siblings. This means you can select:

  • A child or descendant (> or space)
  • Following sibling(s) (+ for the very next sibling, ~ for all subsequent siblings)

But no official “previous sibling” combinator exists to style an element based on what comes before it.

2. Can We Emulate “Previous Sibling” Selection?

A) Using :has() in CSS Selectors Level 4

The CSS :has() pseudo-class can, in some scenarios, emulate parent or previous-sibling-like logic—if the browser supports it. For example, you can style an element if it contains or follows a certain child. However, selecting a “previous sibling” directly is still tricky.

Example: Using :has() to style an element if the next sibling meets a certain condition:

li:has(+ li.special) { /* This is effectively “if the next sibling is .special” */ font-weight: bold; }

But this doesn’t truly select the “previous sibling” in a straightforward way. It’s more like “style this element if it has a next sibling with .special.” Full cross-browser support is also incomplete (notably, older Safari and Firefox versions may not fully support :has() at the time of writing).

B) Structural/HTML Rearrangement

If you have control over your HTML structure, you can reorder elements or wrap them in containers so that the element you want to style is after the trigger element, making the standard sibling combinators possible.

Example:

<!-- Instead of: <div class="trigger"></div> <div class="target"></div> --> <!-- You could reorder them: <div class="target"></div> <div class="trigger"></div> -->

Now you can use the + or ~ combinator from .trigger forward to .target. Of course, this might not always be feasible for your layout.

C) Using JavaScript or Preprocessing

If you absolutely need to style a previous sibling and can’t reorder the HTML, JavaScript can programmatically identify the previous sibling and add a class:

const special = document.querySelector('.special'); const prev = special?.previousElementSibling; if (prev) { prev.classList.add('highlight'); }

Then in CSS:

.highlight { background-color: yellow; }

This approach uses the DOM directly rather than pure CSS.

3. Takeaway

  • No direct previous sibling selector in standard CSS: You can’t just do something like .target ~ .previous or some hypothetical .target <- .previous.
  • :has() can partially solve “reverse” targeting in some modern browsers, but not in a simple “select previous sibling” manner.
  • Rearranging HTML or using JavaScript (adding classes dynamically) can achieve the effect if you need to style a previous element based on what follows.

Conclusion: In pure CSS, you can’t directly select a previous sibling. You either rely on forward combinators (+, ~), reorder your elements, or use a script-driven solution if reordering is impossible.

CONTRIBUTOR
TechGrind