Combining CSS Selectors
Published:There are different methods for combining CSS selectors:
- Descendant (whitespace) combinator, (Level 1)
- Child combinator, (Level 2)
- Next sibling combinator, (Level 2)
- Compounding multiple class or ID selectors,
- Following Sibling Combinator, (Level 3)
- Reference combinator, (Level 4)
- Determining the subject of a selector ("parent selector") (Level 4).
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>
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>
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>
.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.
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.