<< Home

Chapter 12: Selectors, Pseudo-Classes, and Pseudo-Elements

Selectors are the language you use to point at parts of a page. They decide which elements receive which rules, forming the bridge between structure and design. Once you understand how selectors read the document and how pseudo-classes and pseudo-elements extend that reach, you gain a level of precision that makes your CSS feel almost conversational. This chapter explores the most common selectors, the flexible world of attribute targeting and the expressive tools that let you style states, highlights and tiny details without changing your HTML.

Common selectors

Basic selectors form the foundation of most stylesheets. They include element selectors such as p and nav, class selectors such as .card and ID selectors such as #intro. These three types appear constantly because they map directly to the structure of the HTML. When combined, they let you narrow or broaden your reach with ease.

p {
  margin: 1rem 0;
}

.card {
  padding: 1rem;
  border: 1px solid #ccc;
}

#intro {
  font-size: 1.25rem;
}

Descendant selectors target elements that sit somewhere inside other elements. They use spaces to show each step in the path. A space means “contained within”, not “listed alongside”. If you used commas instead, the selector would simply become a list of separate targets rather than a chain. Reading a descendant selector feels like walking through nested boxes until you reach the element you want.

nav ul li a {
  text-decoration: none;
  color: #0044aa;
}

Attribute selectors

Attribute selectors allow you to style elements based on the presence or value of their attributes. This can be especially helpful for forms, links, data tables and custom structures where classes alone might not explain the purpose of each element. By matching attributes, your CSS gains a little more insight into what an element represents.

a[target="_blank"] {
  color: #cc0000;
}

input[type="email"] {
  border-color: #4488cc;
}

[data-level="warning"] {
  background-color: #fff4e0;
}
💡 Attribute selectors work well when styling content generated from external sources because you can rely on standard attributes even when classes are uncertain.

Pseudo-classes and pseudo-elements

Pseudo-classes describe temporary or structural states such as hovering, focusing, selecting or visiting a link. They behave almost like small conditionals inside your stylesheet. When a user interacts with an element or when an element sits in a particular situation, the browser applies the matching rule.

a:visited {
  color: purple;
}

input:focus {
  outline: 2px solid #0057cc;
}

Pseudo-elements reach into parts of an element that do not exist as separate nodes in the HTML. They let you style the first letter of a paragraph, add decorative content or mark the beginning of sections with small symbols. This makes it possible to enrich a design without adding extra markup.

p::first-line {
  font-weight: bold;
}

.article-title::after {
  content: " ✦";
  color: #888;
}

Common pseudo-classes

Pseudo-classes describe conditions or states that an element can be in. Some relate to user interaction, some to document structure and others to form behaviour or link history. This list gathers the most commonly used pseudo-classes so you can see the landscape at a glance. It is not every pseudo-class ever created, yet it covers the ones you will meet in everyday work.

Interaction and user input

Link history

Form and validation states

Structural pseudo-classes

State and logic

Content and media

These pseudo-classes give you a vocabulary for states that HTML cannot express alone. Combined with pseudo-elements, they let your styles react to structure, interactivity and user behaviour without adding a single extra element to your markup.

Hover and focus states that feel natural

Interactions should feel steady and reassuring. A good hover state lets readers know which elements respond to clicks or taps. A good focus state supports keyboard navigation and helps assistive technologies reveal where attention currently sits. These states work best when they are clear but not abrupt. Soft color changes, gentle underlines or subtle shadows guide the user without startling them.

a:hover {
  text-decoration: underline;
}

button:hover {
  background-color: #e8e8e8;
}

button:focus {
  outline: 3px solid #2a7fff;
  outline-offset: 2px;
}
⚠️ Avoid removing focus outlines without very good reason. They are essential for accessibility and help everyone understand where they are while navigating the page.