- CSS selectors
- What is a selector?
- Selector lists
- Types of selectors
- Type, class, and ID selectors
- Pseudo-classes and pseudo-elements
- What is a pseudo-class?
- Simple pseudo-class example
- User-action pseudo classes
- What is a pseudo-element?
- Combining pseudo-classes and pseudo-elements
- Generating content with ::before and ::after
- Summary
- See also
- Found a content problem with this page?
- Difference Between Pseudo-Class and Pseudo-Element in CSS
- Pseudo-Class
- Pseudo-Element
CSS selectors
In CSS, selectors are used to target the HTML elements on our web pages that we want to style. There are a wide variety of CSS selectors available, allowing for fine-grained precision when selecting elements to style. In this article and its sub-articles we’ll run through the different types in great detail, seeing how they work.
Prerequisites: | Basic computer literacy, basic software installed, basic knowledge of working with files, HTML basics (study Introduction to HTML), and an idea of how CSS works (study CSS first steps.) |
---|---|
Objective: | To learn how CSS selectors work in detail. |
What is a selector?
A CSS selector is the first part of a CSS Rule. It is a pattern of elements and other terms that tell the browser which HTML elements should be selected to have the CSS property values inside the rule applied to them. The element or elements which are selected by the selector are referred to as the subject of the selector.
In other articles you may have met some different selectors, and learned that there are selectors that target the document in different ways — for example by selecting an element such as h1 , or a class such as .special .
In CSS, selectors are defined in the CSS Selectors specification; like any other part of CSS they need to have support in browsers for them to work. The majority of selectors that you will come across are defined in the Level 3 Selectors specification and Level 4 Selectors specification, which are both mature specifications, therefore you will find excellent browser support for these selectors.
Selector lists
If you have more than one thing which uses the same CSS then the individual selectors can be combined into a selector list so that the rule is applied to all of the individual selectors. For example, if I have the same CSS for an h1 and also a class of .special , I could write this as two separate rules.
h1 color: blue; > .special color: blue; >
I could also combine these into a selector list, by adding a comma between them.
White space is valid before or after the comma. You may also find the selectors more readable if each is on a new line.
In the live example below try combining the two selectors which have identical declarations. The visual display should be the same after combining them.
When you group selectors in this way, if any selector is syntactically invalid, the whole rule will be ignored.
In the following example, the invalid class selector rule will be ignored, whereas the h1 would still be styled.
h1 color: blue; > ..special color: blue; >
When combined however, neither the h1 nor the class will be styled as the entire rule is deemed invalid.
Types of selectors
There are a few different groupings of selectors, and knowing which type of selector you might need will help you to find the right tool for the job. In this article’s subarticles we will look at the different groups of selectors in more detail.
Type, class, and ID selectors
This group includes selectors that target an HTML element such as an .
It also includes selectors which target a class:
Pseudo-classes and pseudo-elements
The next set of selectors we will look at are referred to as pseudo-classes and pseudo-elements. There are a large number of these, and they often serve quite specific purposes. Once you know how to use them, you can look at the list to see if there is something which works for the task you are trying to achieve. Once again the relevant MDN page for each selector is helpful in explaining browser support.
Prerequisites: | Basic computer literacy, basic software installed, basic knowledge of working with files, HTML basics (study Introduction to HTML), and an idea of how CSS works (study CSS first steps). |
---|---|
Objective: | To learn about the pseudo-class and pseudo-element selectors. |
What is a pseudo-class?
A pseudo-class is a selector that selects elements that are in a specific state, e.g. they are the first element of their type, or they are being hovered over by the mouse pointer. They tend to act as if you had applied a class to some part of your document, often helping you cut down on excess classes in your markup, and giving you more flexible, maintainable code.
Pseudo-classes are keywords that start with a colon. For example, :hover is a pseudo-class.
Simple pseudo-class example
Let’s look at a simple example. If we wanted to make the first paragraph in an article larger and bold, we could add a class to that paragraph and then add CSS to that class, as shown in the first example below:
However, this could be annoying to maintain — what if a new paragraph got added to the top of the document? We’d need to move the class over to the new paragraph. Instead of adding the class, we could use the :first-child pseudo-class selector — this will always target the first child element in the article, and we will no longer need to edit the HTML (this may not always be possible anyway, maybe due to it being generated by a CMS).
All pseudo-classes behave in this same kind of way. They target some bit of your document that is in a certain state, behaving as if you had added a class into your HTML. Take a look at some other examples on MDN:
Note: It is valid to write pseudo-classes and elements without any element selector preceding them. In the example above, you could write :first-child and the rule would apply to any element that is the first child of an element, not just a paragraph first child — :first-child is equivalent to *:first-child . However, usually you want more control than that, so you need to be more specific.
User-action pseudo classes
Some pseudo-classes only apply when the user interacts with the document in some way. These user-action pseudo-classes, sometimes referred to as dynamic pseudo-classes, act as if a class had been added to the element when the user interacts with it. Examples include:
- :hover — mentioned above; this only applies if the user moves their pointer over an element, typically a link.
- :focus — only applies if the user focuses the element by clicking or using keyboard controls.
What is a pseudo-element?
Pseudo-elements behave in a similar way. However, they act as if you had added a whole new HTML element into the markup, rather than applying a class to existing elements.
Pseudo-elements start with a double colon :: . ::before is an example of a pseudo-element.
Note: Some early pseudo-elements used the single colon syntax, so you may sometimes see this in code or examples. Modern browsers support the early pseudo-elements with single- or double-colon syntax for backwards compatibility.
For example, if you wanted to select the first line of a paragraph you could wrap it in a element and use an element selector; however, that would fail if the number of words you had wrapped were longer or shorter than the parent element’s width. As we tend not to know how many words will fit on a line — as that will change if the screen width or font-size changes — it is impossible to robustly do this by adding HTML.
The ::first-line pseudo-element selector will do this for you reliably — if the number of words increases or decreases it will still only select the first line.
It acts as if a was magically wrapped around that first formatted line, and updated each time the line length changed.
You can see that this selects the first line of both paragraphs.
Combining pseudo-classes and pseudo-elements
If you wanted to make the first line of the first paragraph bold you could chain the :first-child and ::first-line selectors together. Try editing the previous live example so it uses the following CSS. We are saying that we want to select the first line, of the first
element, which is inside an element.
article p:first-child::first-line font-size: 120%; font-weight: bold; >
Generating content with ::before and ::after
There are a couple of special pseudo-elements, which are used along with the content property to insert content into your document using CSS.
You could use these to insert a string of text, such as in the live example below. Try changing the text value of the content property and see it change in the output. You could also change the ::before pseudo-element to ::after and see the text inserted at the end of the element instead of the beginning.
Inserting strings of text from CSS isn’t really something we do very often on the web however, as that text is inaccessible to some screen readers and might be hard for someone to find and edit in the future.
A more valid use of these pseudo-elements is to insert an icon, for example the little arrow added in the example below, which is a visual indicator that we wouldn’t want read out by a screen reader:
These pseudo-elements are also frequently used to insert an empty string, which can then be styled just like any element on the page.
In this next example, we have added an empty string using the ::before pseudo-element. We have set this to display: block in order that we can style it with a width and height. We then use CSS to style it just like any element. You can play around with the CSS and change how it looks and behaves.
The use of the ::before and ::after pseudo-elements along with the content property is referred to as «Generated Content» in CSS, and you will often see this technique being used for various tasks. A great example is the site CSS Arrow Please, which helps you to generate an arrow with CSS. Look at the CSS as you create your arrow and you will see the ::before and ::after pseudo-elements in use. Whenever you see these selectors, look at the content property to see what is being added to the HTML element.
Summary
In this article we’ve introduced CSS pseudo-classes and pseudo-elements, which are special types of selectors.
Pseudo-classes enable you to target an element when it’s in a particular state, as if you had added a class for that state to the DOM. Pseudo-elements act as if you had added a whole new element to the DOM, and enable you to style that. The ::before and ::after pseudo-elements enable you to insert content into the document using CSS.
In the next article, we’ll learn about combinators.
See also
Found a content problem with this page?
This page was last modified on Jun 30, 2023 by MDN contributors.
Difference Between Pseudo-Class and Pseudo-Element in CSS
Pseudo-class and pseudo-element are both CSS selectors, however pseudo-class represents a virtual CSS class, whereas pseudo-element represents a virtual HTML element.
Pseudo-Class
Pseudo-class selector helps in selecting different «states» of the same element. However pseudo-classes represent states based on information that lies outside the HTML source tree. Pseudo-classes are also used when it becomes difficult to select a particular state of the element using simple selectors (based on id, class, type and attribute).
CSS classes also represent various states of an element. Pseudo-class on the other hand represents an «artificial» CSS class of the element.
For example, consider an element in disabled state. The HTML tree does not hold information whether the element is in a disabled state or not — browser saves this information somewhere else. To select the element in this state, the :disabled pseudo-class is used.
Again consider that we need to select the first child of an element. The first child is present in the DOM tree, however selecting that would not be possible using simple CSS selectors. To do this, there is the :first-child pseudo-class selector.
Some of the pseudo-class selectors defined are :
- Dynamic pseudo-classes that select elements based on features that are not saved in the DOM tree — :hover :visted :focus etc.
- Language pseudo-classes that represent the same element, however in a different language — :lang
- UI states that represent the same element, however in a different state — :disabled :checked etc
- Structural pseudo-classes, where information is present in the DOM tree, however these are difficult to select via simple selectors — :first-child :nth-child() etc
- Negation pseudo-class that represents an element not having a certain state — :not()
Pseudo-Element
- Pseudo-element representing the first line of the element — ::first-line
- Pseudo-element representing generated content after or before an element’s content — ::after ::before
A pseudo-element’s name is always prepended by double colon :: characters.