# 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!
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:
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!
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.
# 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)