The logical next step from the :empty
and :only-child
CSS selectors, only-of-type
selects single instances of particular elements in a particular context.
Whereas :only-child
cares only if the targeted element is by itself inside its container, :only-of-type
actually looks at the element to determine if it is the only one of its kind in its context. That is, given this markup:
<div>
<h1>Major heading</h1>
<p>Body text…</p>
</div>
The following test will fail to change the paragraph:
div p:only-child { color: red; }
…since the paragraph is not the only child of its <div>
parent. But using :only-of-type
will turn the paragraph red:
div p:only-of-type { color: red; }
… since the paragraph is the only one of its kind inside the <div>
. Naturally, this can be extended by using classes and other selectors:
div.wolf span.cub { … }
… which would select a <span>
element with a class of cub
only if it is the sole span
with a class of cub
inside a <div>
with a class of wolf
.
Uses for :only-of-type
:only-of-type
is especially useful for styling images inside of <figure>
elements. Since those elements will almost always contain a <figcaption>
in addition to an <img>
, :only-child
will not apply to the image… but only-of-type
will. If we know that the image is the only one inside its container, we can responsively scale it to be 100% the width of it’s containing element:
figure img:only-of-type {
width: 100%;
height: auto;
}
If there was more than one image within the <figure>
, you could apply flexbox or another solution to evenly distribute the elements. You can also use the inverse, with the :not
selector, to determine that there is more than one image in the <figure>
:
figure img:not(:only-of-type) {
flex: 1;
}
If there is no ancestor selector defined in the selector, it is assumed that :only-of-type
will eliminate from selection any matching elements that have siblings of the same type, at the same level. That is, given the following markup:
<article></article>
<article></article>
<div>
<article></article>
</div>
And the following CSS:
article:only-of-type {
border: 1px solid red;
}
… only the third article will have a border applied to it.
Support
:only-of-type
is supported in every modern browser, including IE9+, far backwards in terms of versions (Safari 3.1+ supports the selector, for example); it is not supported in IE8.
Photograph by Alexey Kljatov, licensed under a Creative Commons Attribution-NonCommercial 2.0 Generic license
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.