CSS pseudo-classes for targeting element states (:hover, :focus, :nth-child) and pseudo-elements for creating virtual content (::before, ::after).
Pseudo-classes & Pseudo-elements
Pseudo-classes target elements based on their state or position. Pseudo-elements create virtual elements that do not exist in the HTML. Together, they give you styling power that goes far beyond simple selectors.
Pseudo-classes
A pseudo-class starts with a single colon (:) and targets an element based on a condition.
User interaction states
These pseudo-classes respond to how the user interacts with an element:
Tip: When styling links, use the "LVHA" order:
:link,:visited,:hover,:active. This ensures each state correctly overrides the previous one.
:focus vs :focus-visible
:focus applies whenever an element has focus - including mouse clicks. :focus-visible only applies when the focus
was triggered by keyboard navigation (Tab key). This is better for most cases because you avoid showing focus rings on
mouse-clicked buttons:
Structural pseudo-classes
These target elements based on their position among siblings:
:nth-child patterns
:nth-child() accepts numbers, keywords, and formulas:
The An+B formula: A is the cycle size, B is the offset. 3n+2 means items 2, 5, 8, 11...
Practical example: striped table
Form pseudo-classes
Target form elements based on their state:
Negation and matching pseudo-classes
:not()
Excludes elements that match a selector:
:is()
Matches any element in a list of selectors. Reduces repetition:
:is() takes the highest specificity of its arguments.
:where()
Same as :is() but with zero specificity:
This is useful in base styles that should be easy to override.
The :empty pseudo-class
Targets elements with no children (no text, no elements, no whitespace):
Useful for hiding containers that have no content.
Pseudo-elements
Pseudo-elements create virtual elements that do not exist in the HTML. They use double colons (::) to distinguish
them from pseudo-classes.
::before and ::after
Insert content before or after an element's actual content:
The content property is required. Without it, the pseudo-element does not appear. Set content: "" for purely
decorative elements.
Decorative uses
Decorative shapes
::before and ::after are fully styleable boxes. You can use them for decorative elements:
Note:
::beforeand::afterare children of the element, positioned inside it. They do not work on replaced elements like<img>,<input>, and<br>because those elements do not have content to insert before or after.
::placeholder
Styles the placeholder text in form inputs:
::selection
Styles the text that the user highlights:
::first-line and ::first-letter
Style the first line or first letter of a block of text:
This creates a classic "drop cap" effect for the first letter of a paragraph.
::marker
Styles list item markers (bullets, numbers):
Combining pseudo-classes and pseudo-elements
You can chain them together:
Practical example: custom checkbox
A fully CSS-styled checkbox using pseudo-elements:
What you learned
- Pseudo-classes (
:hover,:focus,:nth-child) target elements based on state or position :focus-visibleis better than:focusfor keyboard-only focus rings:nth-child(An+B)uses a formula for repeating patterns:is()reduces selector repetition;:where()does the same with zero specificity:not()excludes elements matching a selector- Pseudo-elements (
::before,::after) create virtual elements with thecontentproperty ::placeholder,::selection,::first-letter, and::markerstyle specific parts of elements- Pseudo-classes and pseudo-elements can be combined
Next step
Now that you know all the selector powers CSS offers, the next chapter covers CSS Custom Properties - variables that make your stylesheets dynamic and maintainable.