A CSS selector acts like a template that helps identify elements on a webpage. When you apply style rules to a selector, those rules affect the elements that match that pattern.
Selectors are fundamental in CSS because they enable you to style specific elements on your webpage in different ways.
CSS offers various types of selectors; let's explore them:
The universal selector, represented by an asterisk (*
), matches every single element on the page.
The universal selector can be omitted if other conditions apply to the element. It's often used to quickly reset default margins and paddings from elements for testing purposes.
Let's understand how it works with the following example:
* {
margin: 0;
padding: 0;
}
The style rules within the *
selector will be applied to every element in a document.
Note: It is advisable not to use the universal selector (*
) too often in a production environment. This selector matches every element on a webpage, which can unnecessarily burden browsers. Instead, use element type or class selectors.
An element type selector matches all instances of the specified element type in the document. Let's try an example to see how it works:
p {
color: blue;
}
The style rules within the p
selector will be applied to every <p>
element (or paragraph) in the document, making their text color blue, regardless of their position in the document tree.
The id selector is employed to establish style regulations for a single or unique element.
It's defined with a hash sign (#
) directly trailed by the id value.
#error {
color: red;
}
This style rule renders the text of an element in red, whose id
attribute is set to error
.
Note: It's important to ensure that the value of an id attribute remains unique within a document. This means that no two elements in your HTML document should have the same id value.
Class selectors are employed to target any HTML element with a class
attribute. All elements possessing that class will be styled according to the specified rule.
The syntax for a class selector involves a period sign (.
) followed directly by the class value.
.blue {
color: blue;
}
The above style rules render the text in blue for every element in the document that has class
attribute set to blue
. You can make it more specific. For example:
p.blue {
color: blue;
}
The style rule inside the selector p.blue
renders the text in blue for only those <p>
elements that have class
attribute set to blue
, and has no effect on other paragraphs.
Descendant selectors prove beneficial when you aim to select an element that is nested within another element. For example, if you wish to style only the anchors contained within an unordered list, instead of styling all anchor elements. Let's explore its functionality:
ul.menu li a {
text-decoration: none;
}
h1 em {
color: green;
}
The style rules inside the selector ul.menu li a
are applied only to those <a>
elements that are contained inside a <ul>
element with the class .menu
, and they have no effect on other links in the document.
Similarly, the style rules inside the h1 em
selector will be applied only to those <em>
elements that are contained inside the <h1>
element and have no effect on other <em>
elements.
A child selector targets only those elements that are immediate children of a particular element.
It comprises two or more selectors separated by a greater-than symbol (>
). You can employ this selector, for instance, to style the first level of list elements within a nested list that contains multiple levels. Let's examine an example:
ul > li {
list-style: square;
}
ul > li ol {
list-style: none;
}
The style rule inside the selector ul > li
is applied only to those <li>
elements that are direct children of <ul>
elements and has no effect on other list elements.
Adjacent sibling selectors are used to select sibling elements (i.e., elements at the same level). This selector has the syntax like: E1 + E2, where E2 is the target of the selector.
The selector h1 + p
in the following example will select the <p>
elements only if both the <h1>
and <p>
elements share the same parent in the document tree, and the <h1>
element immediately precedes the <p>
element. That signifies that only those paragraphs which immediately follow each <h1>
heading will adopt the corresponding style rules. Let's see how this selector works:
h1 + p {
color: blue;
font-size: 18px;
}
ul.task + p {
color: #f0f;
text-indent: 30px;
}
The general sibling selector is similar to the adjacent sibling selector (E1 + E2), but it is less strict. It consists of two simple selectors separated by the tilde (∼
) character. It can be expressed like: E1 ∼ E2, where E2 is the target of the selector.
The selector h1 ∼ p
in the example below will select all the <p>
elements that are preceded by the <h1>
element, where all the elements share the same parent in the document tree.
h1 ∼ p {
color: blue;
font-size: 18px;
}
ul.task ∼ p {
color: #f0f;
text-indent: 30px;
}
In subsequent sections, we'll explore more sophisticated selectors such as attribute selectors, pseudo-classes, and pseudo-elements in depth. Stay tuned for detailed discussions on these selectors in the upcoming chapters.
Oftentimes, several selectors in a style sheet share the same style rules declarations. To streamline your style sheet and avoid redundant style rule declarations, you can group selectors into a comma-separated list. This approach minimizes code duplication and ensures cleaner, more efficient style sheets. Let's have a look:
h1 {
font-size: 36px;
font-weight: normal;
}
h2 {
font-size: 28px;
font-weight: normal;
}
h3 {
font-size: 22px;
font-weight: normal;
}
As you can see in the above example, the same style rule font-weight: normal;
is shared by the selectors h1
, h2
, and h3
, so it can be grouped into a comma-separated list, like this:
h1, h2, h3 {
font-weight: normal;
}
h1 {
font-size: 36px;
}
h2 {
font-size: 28px;
}
h3 {
font-size: 22px;
}