One step above the :empty
selector, :only-child
selects elements that are entirely alone within their containers. You might wonder where this could possibly be employed in your CSS, but use-cases are actually surprisingly common:
Using only-child to treat hero images
There’s a good use for :only-child
right on this blog, where the majority of articles have an illustration in the <header>
. Most of these images are full flush, edge-to-edge, but only if they are the sole occupant of the <header>
. The traditional solution is to write and apply a class
, or style each image inline:
<article>
<header>
<img src="sad-kid.jpg" alt style="width: 100%; height: auto">
</header>
…
</article>
Thinking about the layout logic, the need to attach any styles to the images could be avoided entirely by using :only-child
:
header img:only-child {
width: 100%; height: auto;
}
This translates to: “if an image is the only element inside a <header>
, set it to the full width of its parent.”
Note that this will still work even if the image is wrapped inside a <figure>
element within the <header>
. With this selector, the <figure>
element is skipped, as it’s not specified in the selector: the image is still regarded as being an “only child”. However, if we added <figcaption>
as a sibiling to the image (i.e. immediately above or below it), the selector would no longer apply. To achieve the same result in that case we could use the :only-of-type
selector, which I will cover in a future article.
Checking If An Element Has A Sibling
While CSS doesn’t have a real understanding of the number of elements on a page (that power belongs to JavaScript) it’s possible to ensure that a style is applied to an element under the conditions that it is not the only element inside its parent.
For example, let’s say we want to style the last paragraph in a <div>
a certain way, but only if it is not the only element in the <div>
. Our content is generated dynamically: there’s no way to tell in advance how many paragraphs a <div>
might contain.
But if we use the :only-child
selector in combination with :not
, we can determine that the paragraph is not alone before styling it:
div p:last-child:not(:only-child) {
font-weight: bolder;
}
Using this selection, the last paragraph will be bolded, but only if it is not the only element in the <div>
. To be even more specific, we could use :last-of-type
and :only-of-type
in the same selector pattern.
Support
Support for :only-child
is excellent: every modern browser supports it completely, including IE9+.
Alternatives
Alternative selectors that accomplish the same thing include :first-child:last-child
(meaning: “the first child of the element is also the last child of the element”) and :nth-child(1):nth-last-child(1)
(the same), albeit with a higher specificity.
Photograph by Nesim Kurnaz, licensed under Creative Commons.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.