You can check directly at the CSS grammar.
Basically1, a name must begin with an underscore (_
), a hyphen (-
), or a letter(a
–z
), followed by any number of hyphens, underscores, letters, or numbers. There is a catch: if the first character is a hyphen, the second character must2 be a letter or underscore, and the name must be at least 2 characters long.
-?[_a-zA-Z]+[_a-zA-Z0-9-]*
In short, the previous rule translates to the following, extracted from the W3C spec.:
In CSS, identifiers (including element names, classes, and IDs in
selectors) can contain only the characters [a-z0-9] and ISO 10646
characters U+00A0 and higher, plus the hyphen (-) and the underscore
(_); they cannot start with a digit, or a hyphen followed by a digit.
Identifiers can also contain escaped characters and any ISO 10646
character as a numeric code (see next item). For instance, the
identifier "B&W?" may be written as "B&W?" or "B\26 W\3F".
Identifiers beginning with a hyphen or underscore are typically reserved for browser-specific extensions, as in -moz-opacity
.
1 It's all made a bit more complicated by the inclusion of escaped unicode characters (that no one really uses).
2 Note that, according to the grammar I linked, a rule starting with TWO hyphens, e.g. --indent1
, is invalid. However, I'm pretty sure I've seen this in practice.
There is currently no way to select the parent of an element in CSS.
If there was a way to do it, it would be in either of the current CSS selectors specs:
That said, the Selectors Level 4 Working Draft includes a :has()
pseudo-class that will provide this capability. It will be similar to the jQuery implementation.
li:has(> a.active) { /* styles to apply to the li tag */ }
However, as of 2021, this is still not supported by any browser.
In the meantime, you'll have to resort to JavaScript if you need to select a parent element.
Best Solution
This is one of the most well-known examples of authors misunderstanding how
:first-child
works. Introduced in CSS2, the:first-child
pseudo-class represents the very first child of its parent. That's it. There's a very common misconception that it picks up whichever child element is the first to match the conditions specified by the rest of the compound selector. Due to the way selectors work (see here for an explanation), that is simply not true.Selectors level 3 introduces a
:first-of-type
pseudo-class, which represents the first element among siblings of its element type. This answer explains, with illustrations, the difference between:first-child
and:first-of-type
. However, as with:first-child
, it does not look at any other conditions or attributes. In HTML, the element type is represented by the tag name. In the question, that type isp
.Unfortunately, there is no similar
:first-of-class
pseudo-class for matching the first child element of a given class. At the time this answer was first posted, the newly published FPWD of Selectors level 4 introduced an:nth-match()
pseudo-class, designed around existing selector mechanics as I mentioned in the first paragraph by adding a selector-list argument, through which you can supply the rest of the compound selector to get the desired filtering behavior. In recent years this functionality was subsumed into:nth-child()
itself, with the selector list appearing as an optional second argument, to simplify things as well as averting the false impression that:nth-match()
matched across the entire document (see the final note below).While we await cross-browser support (seriously, it's been nearly 10 years, and there has only been a single implementation for the last 5 of those years), one workaround that Lea Verou and I developed independently (she did it first!) is to first apply your desired styles to all your elements with that class:
... then "undo" the styles for elements with the class that come after the first one, using the general sibling combinator
~
in an overriding rule:Now only the first element with
class="red"
will have a border.Here's an illustration of how the rules are applied:
No rules are applied; no border is rendered.
This element does not have the class
red
, so it's skipped.Only the first rule is applied; a red border is rendered.
This element has the class
red
, but it's not preceded by any elements with the classred
in its parent. Thus the second rule is not applied, only the first, and the element keeps its border.Both rules are applied; no border is rendered.
This element has the class
red
. It is also preceded by at least one other element with the classred
. Thus both rules are applied, and the secondborder
declaration overrides the first, thereby "undoing" it, so to speak.As a bonus, although it was introduced in Selectors 3, the general sibling combinator is actually pretty well-supported by IE7 and newer, unlike
:first-of-type
and:nth-of-type()
which are only supported by IE9 onward. If you need good browser support, you're in luck.In fact, the fact that the sibling combinator is the only important component in this technique, and it has such amazing browser support, makes this technique very versatile — you can adapt it for filtering elements by other things, besides class selectors:
You can use this to work around
:first-of-type
in IE7 and IE8, by simply supplying a type selector instead of a class selector (again, more on its incorrect usage in the question in a later section):You can filter by attribute selectors or any other simple selectors instead of classes.
You can also combine this overriding technique with pseudo-elements even though pseudo-elements technically aren't simple selectors.
Note that in order for this to work, you will need to know in advance what the default styles will be for your other sibling elements so you can override the first rule. Additionally, since this involves overriding rules in CSS, you can't achieve the same thing with a single selector for use with the Selectors API, or Selenium's CSS locators.
On a final note, keep in mind that this answer assumes that the question is looking for any number of first child elements having a given class. There is neither a pseudo-class nor even a generic CSS solution for the nth match of a complex selector across the entire document — whether a solution exists depends heavily on the document structure. jQuery provides
:eq()
,:first
,:last
and more for this purpose, but note again that they function very differently from:nth-child()
et al. Using the Selectors API, you can either usedocument.querySelector()
to obtain the very first match:Or use
document.querySelectorAll()
with an indexer to pick any specific match:Although the
.red:nth-of-type(1)
solution in the original accepted answer by Philip Daubmeier works (which was originally written by Martyn but deleted since), it does not behave the way you'd expect it to.For example, if you only wanted to select the
p
here:... then you can't use
.red:first-of-type
(equivalent to.red:nth-of-type(1)
), because each element is the first (and only) one of its type (p
anddiv
respectively), so both will be matched by the selector.When the first element of a certain class is also the first of its type, the pseudo-class will work, but this happens only by coincidence. This behavior is demonstrated in Philip's answer. The moment you stick in an element of the same type before this element, the selector will fail. Taking the markup from the question:
Applying a rule with
.red:first-of-type
will work, but once you add anotherp
without the class:... the selector will immediately fail, because the first
.red
element is now the secondp
element.