Content updated
By the end, you can…
- A pseudo-class selects a condition or position. A pseudo-element selects a part. Keep essential words in HTML.
- Explain the example, change one value, and check the result in your own page.
One idea at a time
A normal class is a label you add to HTML. A pseudo-class is a selector condition the browser evaluates, such as whether a control is focused or which sibling position it occupies. You do not add class="hover" to make :hover work. States can overlap: a button can be hovered and focused at the same time.
Pseudo-elements describe parts associated with an element, such as its first letter or generated content before it. They use two colons in the modern syntax. Decorative accents are appropriate; required instructions and meaningful labels belong in the HTML. A real button remains a button because of its HTML, not because a CSS state changes its color.
What to remember first
A pseudo-class selects a condition or position. A pseudo-element selects a part. Keep essential words in HTML.
Read the CSS before trying it
:hover / :activePointer over and activation- Hover tracks a pointing device. Active commonly lasts while a button is being pressed; it is not a persistent selected state.
:focus / :focus-visibleFocus and its visible indicator- Focus matches the focused element. focus-visible lets the browser decide when an explicit focus indicator is needed, commonly for keyboard use.
:first-child / :nth-child(2)Sibling position- p:first-child matches a p only when it is its parent's first element child, not simply the first paragraph anywhere.
::before / ::afterGenerated decoration- An empty string in content creates an empty generated box that can be styled as a shape. content: none removes it. Keep meaningful words in HTML instead.
::first-letter / ::first-lineParts of text- Their scope depends on the text layout. A first line can change when the viewport or font changes.
Walk through an example
<h2>Practice notes</h2>
<button class="action" type="button">Try the states</button>
<p>
Tab to the button, then press it. This demo does not submit or save
anything.
</p>.action {
background-color: #1e3a8a;
color: white;
padding: 12px;
border: 2px solid transparent;
}
.action:hover {
background-color: #166534;
}
.action:focus-visible {
outline: 3px solid #0f172a;
outline-offset: 3px;
}
.action:active {
background-color: #312e81;
}
h2::before {
content: "";
display: inline-block;
width: 0.5rem;
height: 0.5rem;
margin-right: 8px;
background-color: #1e3a8a;
}The base rule keeps the button readable without any interaction. Hover changes the surface to green; holding it active uses purple. Keyboard focus adds an offset outline. The h2 has a small decorative square generated before its text. The words Practice notes remain real HTML and still communicate the section when the decoration is removed.
See it happen: try a small change
Predict what will change, choose a version, and compare the live result with the CSS. Use the real controls when the example includes them.
Code to notice
.action {
background-color: #1e3a8a;
color: white;
padding: 12px;
border: 2px solid transparent;
}
.action:hover {
background-color: #166534;
}
.action:focus-visible {
outline: 3px solid #0f172a;
outline-offset: 3px;
}
.action:active {
background-color: #312e81;
}
h2::before {
content: "";
display: inline-block;
width: 0.5rem;
height: 0.5rem;
margin-right: 8px;
background-color: #1e3a8a;
}Live result
What changed: Try hover, press, and keyboard focus. The square is decorative generated content.
Look a little closer
The decorative square uses content: "", display: inline-block, a half-rem width and height, and a small right margin. These are the box and display ideas from earlier lessons applied to a pseudo-element. A visited link can use :visited for limited color styling, but browsers restrict it to protect browsing history. Do not build essential state logic around visited-link appearance.
Organize CSS by component or purpose, keep selectors understandable, and reuse custom properties where values are genuinely shared. Comments use /* and */ in CSS. Test keyboard focus, touch, narrow screens, and longer content. Avoid !important as a routine repair tool, and remove unused rules only after understanding where they are used. Maintainable CSS explains its intention as well as producing a result.
Try it in your own project
Copy the heading and real button with the state rules. Compare pointer hover, holding the button pressed, and Tab focus. Remove only h2::before to confirm the decoration is optional. The button is a styling example and deliberately performs no action.
The preview uses a small set of readable starting styles for its font, spacing, and controls. The code to notice shows the lesson's own rules. Your local browser defaults may look different before you add those rules; focus on the relationship being demonstrated rather than matching every pixel of the preview.
A common wrong turn
Removing outlines and adding only a hover effect leaves keyboard users without a reliable position indicator. Generated content is also an unreliable place for essential instructions. Keep a visible focus treatment and the important text in the document.
Your turn: style states and parts with clear CSS
Finish a small button-and-heading component with pointer and keyboard states, plus a decorative heading accent.
Try this in your own HTML and CSS files, then open the page in a browser. There is no separate checked practice for this task yet.
- Start with a readable base rule and a real button whose type is explicit.
- Add hover, active, and focus-visible rules. Use both a pointer and the keyboard to observe the difference.
- Add a decorative ::before shape, then remove it temporarily. The heading and button must still make sense. Review the stylesheet for repeated values and unclear selectors.
Go to the source
Examples are authored for Tuklas and checked with code and reference documentation. This is not a claim of independent human review. Suggest a correction.