# CSS Selectors

# Basic selectors

At this point, we only know the basic CSS selectors

  • The universal selector (*) which selects all elements on the page
  • Simple selectors, based on (element) name, id and class
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

p {
    text-align: center;
    color: red;
}

h1, h2 {
    text-transform: uppercase;
}

#container {
    max-width: 600px;
    margin: auto;
}

.underline {
    text-decoration: underline;
}
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# Combinator selectors

Combinator selectors allow you to select HTML elements based on their relationships with other elements in the document tree. They provide a powerful way to target specific elements without relying solely on class names or IDs.

The combinators we'll explore here are:

  • Descendant Combinator (space )
  • Child Combinator (>)
  • Adjacent Sibling Combinator (+)
  • General Sibling Combinator (~)

To understand combinators, let's visualize the relationships between HTML elements using the following diagram:

DOM

In this diagram:

  • Ancestor: Any element that is a parent, grandparent, etc. of another element.
  • Parent: An element that directly contains another element.
  • Child: An element that is directly contained within another element.
  • Sibling: Elements that share the same parent.
  • Descendant: Any element that is a child, grandchild, etc. of another element.

WARNING

CSS selectors are designed to work downwards through the DOM (Document Object Model) tree.
They start with a specific element (eg: x) and then apply styles to its descendants, siblings to the right ( not to the left), or the element itself.

# Limitations of CSS Selectors:

  • One-Way Traversal: CSS selectors primarily traverse the DOM tree from parent to child, not vice versa. They operate on a "forward-only" basis.
  • Styling Flow: CSS is designed so that styles are applied in a predictable way. Allowing upward traversal could make the styling cascade unpredictable and difficult to manage.
  • :has(): There is one pseudo-class currently under development for CSS Selectors Level 4, that would enable you to select a parent based on its children. (See later in this section)
Selector Description
div p Selects all <p> elements that are descendants of <div> elements.
div > p Selects all <p> elements that are direct children of <div> elements.
div + p Selects the first <p> element that is placed immediately after a <div> element.
div ~ p Selects all <p> elements that are preceded by a <div> element (they must share the same parent).

Here's a more detailed example of how these combinators work:

# Attribute Selectors

Attribute selectors allow you to target HTML elements based on the presence or value of their attributes. This provides a more flexible way to select elements than simply relying on tag names, classes, or IDs.

Selector Description
[attribute] Selects elements that have a specified attribute, regardless of its value.
[attribute="value"] Selects elements where the attribute has the exact specified value.
[attribute^="value"] Selects elements where the attribute's value starts with the given string.
[attribute$="value"] Selects elements where the attribute's value ends with the given string.
[attribute*="value"] Selects elements where the attribute's value contains the given sub-string.
[attribute~="value"] Selects elements where the attribute's value contains the given word (space-separated).
/* Selects all elements with a "href" attribute */
[href] {
    color: blue;
}

/* Select all images surrounded by an anchor tag with an empty 'alt' attribute */
a img[alt=""] {
    border: 2px solid black;
}

/* Select all links with a 'href' attribute that STARTS WITH 'https://' */
a[href^="https://"] {
    color: green;
}

/* Selects all images with a 'src' attribute where the value ENDS WITH '.jpg' */
img[src$=".jpg"] {
    border: 3px solid red;
}

/* Selects elements with a 'class' attribute where the value CONTAINS the SUBSTRING 'col-'*/
/* Eg: class is 'col', 'col-1', 'col-ms-6', ... */
[class*="col-"] {
    padding: 10px;
    border-radius: 5px;
}

/* Select elements where the class attribute CONTAINS the WORD "highlight" */
/* Eg: class 'btn btn-danger' is selected but the class 'btn-danger' is not */
[class~="btn"] {
    background-color: yellow;
    font-weight: bold;
    padding: 5px;
}
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

For a comprehensive list and more detailed explanations of CSS attribute selectors, refer to the Mozilla Developer Network (MDN): CSS Attribute Selectors - MDN (opens new window)

# Pseudo-Class Selectors

Pseudo-class selectors are used to style elements based on their state, position within the document tree, or other dynamic characteristics. They allow you to target elements that cannot be selected using simple selectors alone.
Pseudo-classes are denoted by a colon : followed by the pseudo-class name.

# Pseudo-classes for user actions

Selector Description
:link Selects elements that are unvisited links.
:visited Selects links that the user has visited.
:focus Selects elements when they have focus (e.g., via keyboard navigation).
:hover Selects elements when the user hovers over them.
:active Selects elements when they're being activated (e.g., clicked, tapped).

Note

The order of pseudo-classes is important.
When using multiple pseudo-classes on the same element, the order should be :link, :visited, (:focus), :hover, :active. For example, :hover must come after :link and :visited because otherwise, it will be overridden. We have covered this in detail in semester1 (Web Essentials).

# Pseudo-classes for element states

Selector Description
:enabled Selects elements that are enabled.
:disabled Selects elements that are disabled.
:checked Selects elements that are checked (e.g., checkboxes, radio buttons).
:required Selects elements that are required (e.g., form input fields).
:optional Selects elements that are optional (e.g., form input fields).
:valid Selects elements that have valid input (e.g., form input fields).
:invalid Selects elements that have invalid input (e.g., form input fields).
:in-range Selects elements that are within the specified range (e.g. form input fields).
:out-of-range Selects elements that are outside the specified range (e.g., form input fields).
:read-only Selects elements that are read-only (e.g., form input fields).
:read-write Selects elements that are read-write (e.g., form input fields).
:placeholder-shown Selects elements that are displaying placeholder text (e.g., form input fields).

Note

Most of these pseudo-classes are used in form elements to style them based on their state.
We'll cover form styling, based on these pseudo-classes, in a later section.

# Structural pseudo-classes

Selector Description
:first-child Selects the first child element of its parent.
:last-child Selects the last child element of its parent.
:nth-child(n) Selects elements based on their position within their parent element (e.g., :nth-child(2), starts at 1).
:nth-child(odd) Selects elements based on their position within their parent element (odd-numbered).
:nth-child(even) Selects elements based on their position within their parent element (even-numbered).
:nth-last-child(n) Selects elements based on their position within their parent element, counting from the end.
:only-child Selects elements that are the only child of their parent.
Selector Description
:first-of-type Selects the first element of a specific type within its parent.
:last-of-type Selects the last element of a specific type within its parent.
:nth-of-type(n) Selects elements of a specific type based on their position within their parent (e.g., :nth-of-type(2), starts at 1).
:nth-of-type(odd) Selects elements of a specific type based on their position within their parent (odd-numbered).
:nth-of-type(even) Selects elements of a specific type based on their position within their parent (even-numbered).
:nth-last-of-type(n) Selects elements of a specific type based on their position within their parent, counting from the end.
:only-of-type Selects elements that are the only element of their type within their parent.
Selector Description
:only-child Selects elements that are the only child of their parent.
:empty Selects elements that have no children.
:target Selects the target element of a URI with a fragment identifier.

# Pseudo-Element Selectors

Pseudo-element selectors are used to style specific parts of an element. Unlike pseudo-classes, which target elements based on their state or position, pseudo-elements allow you to style portions of an element's content, like the first line, the first letter, or inserted content. Pseudo-elements are denoted by double colons :: followed by the pseudo-element name (although, single colons : are often used for legacy reasons but should be avoided for new code).

# Pseudo-Element Selector Details

Selector Description
::before Inserts content before the element's content.
::after Inserts content after the element's content.
::first-line Targets the first line of text in an element.
::first-letter Targets the first letter of text in an element.
::selection Targets the portion of the element that has been selected by the user.
::placeholder Targets the placeholder text within a form input.
::marker Styles list markers.

# Advanced Selectors

These advanced selectors provide more flexibility and precision when selecting elements. They enable more complex logic in your CSS rules, making your stylesheets more efficient and maintainable.

Selector Description
:is(selectors) The :is() pseudo-class allows you to group selectors, applying a set of styles to any element that matches at least one of the selectors within the parentheses.
:not(selector) The :not() pseudo-class is a negation selector. It is used to select all elements that do not match the given selector.
:has(selector) The :has() pseudo-class will allow you to select an element based on whether it has children that matches another selector. It allows you to check if an element has a specific child.

The CSS selectors we discussed here are, are fully supported in modern browsers.

https://caniuse.com/#feat=css-matches-pseudo

# Practice

Improve your CSS selector skills with fun and interactive exercises at CSS Diner (opens new window) or try the Frontend30 CSS selectors cheat sheet (opens new window)

Last Updated: 2/19/2025, 6:43:36 AM