Cascading Style Sheets, abbreviated as CSS, is a rule-based language for styling HTML documents.
With CSS, you can select DOM elements or groups of DOM elements in your HTML document and apply styles to them.
A single instance of this is called a rule. It consists of a selector with one or multiple declarations in the form of property/value pairs wrapped in curly brackets ({}).
For example, the CSS rule:
h1 {
font-size: 42px;
}
Gives the inner text of all <h1>
headings a font-size of 42 pixels.
It’s also an example of a rule with simple selectors. It targets one type of DOM element—headings with the <h1>
tag—in a generic way and assumes a simple implementation context.
CSS selectors, however, can be much more sophisticated and specific than that. Especially since the introduction of CSS3, the most recent specification of the CSS standard, you can do complex CSS selection which previously was only possible with JavaScript and/or jQuery.
Table of Contents
This tutorial will teach you some of the most common complex CSS selectors—and how to make the most of them, including:
- CSS selectors for descendants
- CSS selectors for children
- CSS selectors for siblings
- CSS selectors for custom attributes
Descendant Selectors
In CSS, you can select one, multiple, or all descendant elements of an ancestor element.
Let’s suppose you’re working on a web page that has the following HTML markup:
<nav id="nav-menu">
<ul class="nav-links">
<li class="link">Link 1</li>
<li class="link">Link 2</li>
<li class="link">Link 3</li>
<li class="link">Link 4</li>
</ul>
<ul class="nav-icons">
<li class="icon">Icon 1</li>
<li class="icon">Icon 2</li>
<li class="icon">Icon 3</li>
</ul>
<div id="nav-toggle">
<button id="button-toggle">Show more</button>
<ul class="nav-toggle-links">
<li class="link">Link 1</li>
<li class="link">Link 2</li>
<li class="link">Link 3</li>
</ul>
</div>
</nav>
With complex CSS selectors, you can create a number of patterns to target the DOM elements in this HTML markup differently depending on your needs.
Select All Descendants
You can select all descendants of an ancestor element with the ancestor descendant
CSS combinator.
The CSS rule:
/* Selects all descendants of #nav-menu */
#nav-menu ul {
}
Will select all three <ul>
elements (ul.nav-links
, ul.nav-icons
, and ul.nav-toggle-links
) under #nav-menu
.
Notice that, with this CSS combinator, the nesting of the descendant elements doesn’t matter. They can be nested directly under the ancestor or wrapped in any number of DOM elements. Either way, they will be selected.
Select Direct Descendants
You can select only direct descendants of an ancestor element with the ancestor > descendant
CSS combinator.
The CSS rule:
/* Selects only direct descendants of #nav-menu */
#nav-menu > ul {
}
Will select only the first two <ul>
elements (ul.nav-links
and ul.nav-icons
) in the HTML markup above.
With this CSS combinator, the nesting matters. Your selection will only include direct descendants of the ancestor and will exclude any DOM elements wrapped in other DOM elements.
Since ul.nav-toggle-links
is not a direct descendant of the #nav-menu
ancestor—it’s wrapped in a <div>
element with an id of nav-toggle
—it will be excluded.
Key Takeaways
Selector | Target | Result |
---|---|---|
ancestor descendants | All descendants of ancestor, no matter the DOM nesting. | Multiple elements |
ancestor > descendants | Only descendants of ancestor nested directly under it, not wrapped in other DOM elements. | Multiple elements |
Child Selectors
In CSS, you can select one, multiple, or all child elements of a parent element. This is done with the nth-child
pseudo-class.
Suppose you’re working on a CSS style for the following HTML markup:
<section id="blog">
<article id="article-1">Article 1</article>
<article id="article-2">Article 2</article>
<article id="article-3">Article 3</article>
</section>
Select First Child
With the :first-child
CSS pseudo-class, you can select the first child of a parent element.
The CSS rule:
/* Selects only the <article> that's the first child of #blog */
#blog article:first-child {
}
Selects the <article>
element with an id of article-1
because it’s the first child of #blog
. It also omits its peers with ids of article-2
and article-3
because they are, respectively, the second and the third child elements.
Select Last Child
With the :last-child
CSS pseudo-class, you can select the last child of a parent element.
The CSS rule:
/* Selects only the <article> that's the last child of #blog */
#blog article:last-child {
}
Selects the <article>
element with an id of article-3
because it’s the last child of #blog
. It also omits its peers with ids of article-1
and article-2
because they are, respectively, the first and the third child elements.
Select Odd Children
With the :nth-child(odd)
CSS pseudo-class, you can select the odd child elements of a parent element.
The CSS rule:
/* Selects only the odd <article> child elements of #blog */
#blog article:nth-child(odd) {
}
Selects the first, third, fifth, (…), n-th odd child elements of the #blog
element.
Select Even Children
With the :nth-child(even) CSS pseudo-class, you can select the even child elements of a parent element.
The CSS rule:
/* Selects only the even <article> child elements of #blog */
#blog article:nth-child(even) {
}
Selects the second, fourth, sixth, (…), n-th even child elements of the #blog
element.
Select nth Child
With the :nth-child(number)
CSS pseudo-class, you can select the even child elements of a parent element.
The CSS rule:
/* Selects only the third <article> child elements of #blog */
#blog article:nth-child(3) {
}
Selects the third <article>
that’s a child element of the DOM element with an id of blog
.
Key Takeaways
Selector | Target | Result |
---|---|---|
:first-child | The first child element of a parent element. | Single element |
:last-child | The last child element of a parent element. | Single element |
:nth-child(even) | The even child elements of a parent element. | Multiple elements |
:nth-child(odd) | The odd child elements of a parent element. | Multiple elements |
:nth-child(number) | The nth child element of a parent element. | Single element |
Sibling Selectors
In CSS, you can select one, multiple, or all sibling elements of a given element.
Suppose you’re styling the following HTML markup:
<article id="article-1">
<p class="intro">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>bi facilisis nulla dolor, scelerisque faucibus ex dapibus id.</p>
<p>Interdum et malesuada fames ac ante ipsum primis in faucibus.</p>
</article>
All Siblings
With the element ~ siblings
selector, you can select all siblings of a given DOM element.
The first element in the selector is for the main element and the second element/group of elements is/are its siblings under the same parent.
The CSS rule:
/* Select all sibling paragraphs of p.intro */
p.intro ~ p {
}
Selects the two sibling paragraphs of p.intro
, meaning the second and third paragraphs at lines three and four.
Adjacent Sibling
With the element + siblings
selector, you can select only the adjacent sibling of a given DOM element.
The first element in the selector is for the main element and the second element is the sibling under the same parent element that immediately follows it.
The CSS rule:
/* Select the adjacent sibling paragraph immediately after p.intro */
p.intro + p {
}
Selects the adjacent sibling paragraph of p.intro
, meaning the second paragraphs at line three that immediately follows it in the HTML markup.
Key Takeaways
Selector | Target | Result |
---|---|---|
| All siblings of a given element within a parent element in the DOM. | Multiple elements |
| The adjacent sibling of a given element within a parent element in the DOM. | Single element |
Attribute Selectors
In CSS, you can select one, multiple, or all elements based on their HTML attributes. This includes default attributes, such as the href
attribute of <a>
elements, as well as any custom attributes specific to your HTML document’s markup.
Presence of Attribute
To select one or multiple DOM elements based on whether they have an HTML attribute or not, use the [name]
selector, where name
is the name of the attribute.
For example, in the CSS stylesheet:
/* Select all DOM elements with an "href" attribute */
[href] {
}
/* Select only <a> elements with an "href" attribute */
a[href] {
}
The [href]
rule selects all DOM elements with an href
attribute, whereas the a[href]
rule selects all <a>
elements with an href
attribute.
Value of Attribute
With attribute selectors, you can get really specific about which DOM elements to target.
Not long ago, I wrote about this in detail in a post called “The Guide to Custom Attribute Selectors in CSS.” Check out that post if you want to learn the nuts and bolts of these CSS selectors, or read on for an overview.
Exact Match
To select one or multiple DOM elements based on the presence and the exact value of an HTML attribute, use the [name="value"]
selector, where name
is the name of the attribute and value
is its value.
For example, the CSS rule:
/* Select links set to open in a new window */
a[target="_blank"] {
}
Selects only <a>
elements whose target
attribute is set to “_blank.”
Containing a Value
The [name*="value"]
selector lets you select DOM elements that have the given custom attribute and whose value contains a given value, whether by itself or within a word or number.
For example, the CSS rule:
/* Select internal links only */
a[href*="makersaid.com"] {
}
Selects only <a>
hyperlinks whose href
attribute contains “makersaid.com.”
Starting With a Value
The [name^="value"]
selector lets you select DOM elements that have the given custom attribute and whose value starts with a given value.
For example, in the CSS stylesheet:
/* Select anchor links only */
a[href^="#"] {
}
/* Select external links only */
a[href^="http"] {
}
The first CSS selector is for anchor links since the value of their href
attributes starts with a hash (#), and the second CSS selector is for external links since their href attributes always start with “http.”
Ending With a Value
The [name$="value"]
selector lets you select DOM elements that have the given custom attribute and whose value ends with a given word.
For example, the CSS selector:
/* Select links to .org domain names only */
a[href$=".org"] {
}
Selects all <a>
hyperlinks whose href
attributes contain .org domain names.
Key Takeaways
Selector | Target | Result |
---|---|---|
| All DOM elements that have a given attribute. | Multiple elements |
| All DOM elements that have a given attribute with this exact value. | Multiple elements |
| All DOM elements that have a given attribute that starts with this value. | Multiple elements |
| All DOM elements that have a given attribute that ends with this value. | Multiple elements |