Combining CSS Selectors

Published: This article describes all current techniques for combining CSS selectors. Some widely used, other seldom, but also few new, from CSS Level 4 Specification (currently unstable working draft) that are not yet supported in any modern browser. This article gives you a vague idea about how to combine CSS selectors and how this is going to be possible in the future.

There are different methods for combining CSS selectors:

The following three are rather well known, they go way back to the beginning and until CSS Level 2.

Descendant Combinator

Pattern: E F
Matches any F element that is a descendant (inside) of an E element.

Example CSS: h1 em { color: blue; }
Example HTML: <h1>This will be <em>blue</em></h1>
Matches an an EM element that is contained within an H1 element.

Basic technique and probably the most widely used, which was already present in CSS Level 1, back in 1996.


Child Combinator

Pattern: E > F
Matches any F element that is a child of an element E.

Example CSS: body > p { color: blue; }
Working example HTML:

<body>
    <p>Blue paragraph.</p>
</body>

Example where it does not match the element <p>:

<body>
    <div>
    	<p>Not a blue paragraph.</p>
    </div>
</body>
Element <p> is a child of an element <div>, therefore the CSS rules does not apply.

You can also combine descendant combinators and child combinators, for example: div ul > li span.


Next sibling combinator

Pattern: E + F
The selector matches if E and F share the same parent and E immediately precedes F.
Meaning it selects all F elements that are placed immediately after E elements.
Note: Style rule is applied to an element that is matched by the selector F.

Example CSS: h1 + h2 { opacity: 0.8; }
Working example HTML:

<h1>Title</h1>
<h2>Subtitle with lowered transpareny</h2>
<p>Paragraph</p>

Example where it does not match:

<h1>Title</h1>
<p>Paragraph</p>
<h2>Subtitle is not transparent</h2>
That is because <h2> isn't immediatelly followed after an element <h1>

Very useful, but seldom used.


Compounding multiple class or ID selectors

Pattern: .class1.class2(.classN) / #id.class1(.classN) / .class1(.classN)#id

Example CSS: .modal.modal-red { border-color: red; }
Working example HTML:

<div class='modal modal-red'>
    This modal has a red border
</div>

NOT working example:

<div class='modal'>
    <p class='modal-red'>
        No red border
    </p>
</div>
That is because an element that is matched by .modal-red is a .modal's child element and not an element with two compound classes.

This is rather tricky but very useful if you follow SMACSS (Scalable and Modular Architecture for CSS) recommendations. You can either compound:

  • multiple classes,
  • ID selector plus multiple classes,
  • multiple classes plus ID selector,
  • multiple classes plus ID selector plus multiple classes.
(The latter case is rather silly, but it works)

We can combine as many classes and IDs into a single selector as we want. Chris Coyer published an article on CSS-Tricks titled Multiple Class / ID and Class Selectors and he explains it in a detailed way.


In CSS Selectors Level 3 there were not much new regarding combining selectors, just the Following Sibling Combinator:

Following Sibling Combinator

Pattern: E ~ F
The selector matches when an F element is preceded by an E element (not necessarily immediately, as in case of E > F).

Example CSS: h1 ~ p { color: grey; }
Example HTML:

<h1>Title</h1>
<span>Recently published</span>
<p>This paragraph is in color grey.</p>

Once again, Chris Coyer already covered this combination in general sibling.


If you are worried about browser support, you need not be. All mentioned above are supported in every modern browsers and Intern Explorer 7+.

So let’s see what there’s up to in CSS Selectors Level 4 (which is a draft at the time of writing). Keep in mind that the following examples are NOT YET supported in any modern browser.

Reference combinator

Pattern: E /foo/ F
Matches an F element ID-referenced by an E element's foo attribute.

Example CSS: label:hover /for/ input { border: 1px solid red; }
The example above matches and an INPUT element (and will add red border to it) when its LABEL is hovered-over. It is referenced by its label.

In case of curiosity, you can read reference combinator's specification. This example is also the first to incorporate slashes (/) to the CSS, but personally, apart from some edge cases I don’t find much use of it.


Determining the subject of a selector ("parent selector")

Pattern: !E > F
Matches an E element that is parent of an F element.

The subject of the selector can be explicitly identified by prepending an exclamation mark (!) to one of the compound selectors in a selector. It might also be explained as a "parent selector".

If you have experience with programming languages, then the presence of an exclamation mark might mislead you. The specs are still in draft and I kind of hope the syntax will change to avoid avoid this "! = not" issue.

Example CSS:
!ul > li { border: 1px solid green; } matches element ul, unordered list gets a green border.
ul > li { border: 1px solid green; } matches element li, list items get a green border.


Keep an eye on W3C Working Draft on Selectors Level 4 to be informed about the forthcoming possibilities, or follow it's editors Tab Atkins Jr. and Elika J. Etemad on Twitter.

blog comments powered by Disqus