A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
<style>.card::before { content:""; display:block; height:3px; }</style><main class="card">Example content</main>
Engineering judgment: Treat pseudo-elements as presentation layers. If a user needs the information independently, give it a real node or attribute relationship.
The useful mental model here is practical: how ::before, ::after, ::marker, and other pseudo-elements add paint or generated content without extra DOM nodes. When a rule looks obvious but the browser produces something else, start by identifying which constraint or rendering phase is actually winning.
| Concern | What to inspect | Typical failure |
|---|---|---|
| Core behavior | Pseudo-Elements and Generated Content | Generated content is not a substitute for semantic content. Critical instructions should exist in the DOM or accessible name, not only inside decorative pseudo-elements. |
| Production test | Real content and constraints | The rule works only for the demo values |
| Maintenance | Scope and override path | A later fix creates another exception |
A good CSS change narrows the problem. Treat pseudo-elements as presentation layers. If a user needs the information independently, give it a real node or attribute relationship. This keeps the rule understandable when content, theme, or viewport conditions change later.
<style>.demo { li::marker { color:tomato; }; }</style><main class="demo">Example content</main>
In production, Generated content is not a substitute for semantic content. Critical instructions should exist in the DOM or accessible name, not only inside decorative pseudo-elements. That is the kind of bug that survives visual spot checks because the stylesheet is syntactically valid while the layout contract is wrong.
<style>.demo { q::before { content:"“"; }; }</style><main class="demo">Example content</main>
Quoted content is useful here because it demonstrates pseudo-elements and generated content under a concrete input rather than as an abstract property list.
<style>.icon::after { content:attr(aria-label); }</style><main class="icon">Example content</main>
Tooltip decoration is useful here because it demonstrates pseudo-elements and generated content under a concrete input rather than as an abstract property list.
Finish the lesson once you have worked through the material. This awards ★ 30 XP.