CSS Module 2 – Selectors
Pseudo-elements, generated content and counters
Add content with ::before and ::after and give it alternative text, style list markers, first letters and placeholders, and number sections with CSS counters.
What you will learn
- Add decorative content with ::before and ::after, with alternative text where it carries meaning
- Change the look of list markers, placeholders, selections and the first line or letter of text
- Generate section and figure numbers with counter-reset, counter-increment and counters()
Before you start
What you’ll learn · Before you start
What you will learn
- Add decorative content with ::before and ::after, with alternative text where it carries meaning
- Change the look of list markers, placeholders, selections and the first line or letter of text
- Generate section and figure numbers with counter-reset, counter-increment and counters()
Before you start
On this page
A missing content declaration can prevent a decorative bar from appearing, while a reset on every heading can make every subsection number repeat. pseudo-element: A CSS-selected part associated with an originating element, such as a text part, marker or generated before or after box. identify generated boxes or parts associated with an element: ::before, ::after, ::marker and ::first-line use two colons. Pseudo-elements can supply generated content for decoration; counters can calculate displayed numbering.
Choose what must survive without the stylesheet before adding either. A delivery status, required instruction or cited clause number belongs in the HTML when readers need that information independently. The complete decoration, counter and text-styling examples below distinguish those requirements from the appearance CSS supplies.
Generated boxes need content and a suitable originating element
CSS ::before generates a child box before the originating element’s own content. CSS ::before needs a content value to create that box, even when the chosen string is empty.
::after generates a child box after the originating element’s own content. The ::after box also needs a content value; content: none creates no such box. A decorative bar can use content: "" with its dimensions and background. These boxes are inline unless another display value is specified.
Replaced content such as an image is not an ordinary container for these generated children. A wrapper provides a suitable place for decoration around it. Pseudo-element chaining is also restricted by the specification rather than universally forbidden: ::before::marker is explicitly permitted when the generated box is a list item, while ::before::before is not.
Other pseudo-elements select different parts. ::marker selects a list item’s bullet or number. Its restricted properties and browser support affect which marker styles work. ::first-letter selects the initial typographic character unit and associated punctuation. That unit can contain several code points, so a drop cap must respect the script’s initial boundary. ::first-line follows the laid-out first line. Changing width can change which text belongs to that line. ::placeholder selects the hint displayed by an input or textarea. Keep a real label and readable hint contrast because the placeholder disappears as the user types. Selecting a part does not create a new semantic HTML element.
The marker sits outside the item; ::before and ::after sit inside it, around its content
Text description of the diagram
The diagram shows one list item, li, and the boxes CSS can generate for it, from top to bottom. It uses outside marker placement; list-style-position: inside would place the marker within the item's contents.
- First, drawn with a dashed border, is ::marker: the number or bullet of the item. It sits outside the item's content box, to its left in left-to-right text.
- Below it is the item's content box, which holds three boxes in order: ::before, the first child box of the element; the item's own text and child elements; and ::after, the last child box.
- So ::before and ::after are inside the element, part of its content. They need the content property and are suppressed for a replaced originating element, such as img. Control rendering depends on its type and appearance, so this rule does not categorize every input as replaced; use a suitable wrapper for the intended decoration boundary.
The drawing shows the whole scene; its 3 steps are listed below.
Every step as text
- Origin. Before and after represent generated children around an ordinary element’s content. The original list-item diagram keeps the marker and content regions distinct.
- Content. An empty content string is enough for the decorative bar. Dimensions and background alone do not create the after box in the original question.
- Wrapper. An image is not an ordinary generated-child container. Decorate a suitable wrapper and keep the image itself unchanged.
Checkpoint
Check: Generated boxes and originating elements
Meaningful text and decorative marks have different jobs
Generated content such as a status tick does not put the word “Delivered” into the document. Keep necessary text in the HTML so that it survives missing styles, copying and tools that read document content. Let a generated mark decorate that text instead of being its only source.
Generated content can have alternative text supplied after a slash in the content value. An empty alternative string identifies a decorative mark; a text alternative can explain the intended meaning of a symbol. Browser accessibility-tree observations and actual screen-reader announcements are separate evidence, so test the supported combination rather than assuming every reader announces a glyph identically.
Older browsers can drop a declaration whose slash syntax they do not understand. A preceding plain declaration can retain its mark, while the meaningful HTML text remains available either way. Quotes and attr() can also contribute generated text, but neither makes stylesheet-only information part of the original HTML.
The drawing shows the whole scene; its 3 steps are listed below.
Every step as text
- Information. Delivered must remain document text when readers need the status independently of the stylesheet. A tick alone supplies only its character, not that document text.
- Decoration. The icon may decorate the status. It must not make missing styles, copying or HTML-only reading lose the required meaning.
- Alternative. An empty slash alternative marks decoration; a meaningful alternative explains a symbol where the target combination supports it. Actual announcements still need target testing.
Checkpoint
Check: Required information and decorative marks
A reset starts a counter and an increment advances it
CSS counter: A named numbering value created, advanced or assigned by counter properties and displayed by counter functions. store named numbering values as the document is processed. Counters are created by counter-reset, advanced by counter-increment and assigned a value by counter-set. counter() reads the innermost counter with that name; counters() joins levels of the same name for nested numbering.
Resetting a subsection counter to zero at a section heading and incrementing at each subsection yields one and then two. Resetting again on every subsection instead repeatedly produces one. The complete original program below compares nested outlines, that faulty reset and flat headings, preserving every displayed number.
Keep counter scope distinct from DOM parentage: a counter created by a preceding sibling can reach a later heading. Decide whether the numbering is decorative or must be cited and copied. A clause number needed by document text should exist in the HTML even if CSS also supplies its visual styling. Counter styles can change displayed digits or letters without changing that information requirement.
The drawing shows the whole scene; its 3 steps are listed below.
Every step as text
- Start. Reset creates the counter at its starting value, zero in the original default case.
- Advance. Increment advances that counter to one and then two when the same run continues. Resetting every counted item instead keeps starting the run again.
- Read. Counter reads one named level; counters joins levels for nested numbering. Required cited numbers still need to exist as document information.
Checkpoint
Check: Reset, increment and numbering information
Complete decoration, alternative-text and marker cases Pro: opens with a Pro, Premium or Ultimate pass
The complete page separates a decorative mark from information readers need. Compare its generated boxes and recorded accessibility-tree observations before choosing the content declaration.
In this part:
- Generated boxes surround the originating content
- Alternative text changes the recorded accessible name
- Quotes and attributes remain generated presentation
- Marker styling must respect the stated browser evidence
4 diagrams · 3 runnable examples (CSS, HTML) · about 9 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; nothing renews unless you choose to. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Complete counter pairings and text/control measurements Pro: opens with a Pro, Premium or Ultimate pass
The three original counter pairings and the text/control observations are complete cases. Preserve their inputs while accounting for every displayed number or measured colour.
In this part:
- Reset scope determines the complete numbering sequence
- Text parts and controls have their own measurements
- The original outline task preserves every counter level
2 diagrams · 3 runnable examples (CSS, JavaScript, headings.css, headings.html, outline.css, outline.html, reset-on-item.css) · about 8 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; nothing renews unless you choose to. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Practise: choose what belongs in the document
Practice that adapts to you
Practise this lesson
6 questions about 9 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Why does ::before not work on an img element?
::before and ::after create boxes that are children of their element, placed before and after its content. An
img is a replaced element: what it shows comes from an outside resource, the image file, not from content that CSS
lays out, so it has no content box for the generated boxes to go into, and the browser does not create them. The same suppression applies to other replaced originating content, such as video; a form control’s rendering also depends on its type and appearance. To decorate one, wrap it in an element such as a figure or
a span and put the ::before or ::after on the wrapper, which is an ordinary element.
-
Fresher to mid
A long policy page numbers its h2 and h3 headings with CSS counters, but every h3 shows the same number and the count never moves on. Explain what is wrong, and write rules that number the headings 1, 1.1, 1.2, 2, 2.1.
-
Mid to senior
An orders page shows each order's status only as an icon added with ::before: a tick for delivered, a cross for cancelled. A screen-reader user hears "check mark" for some rows and nothing for others. What is wrong, and how do you fix it in the HTML and the CSS?
-
Fresher to senior
A policy uses CSS counters for clause numbers that other paragraphs cite. A copied plain-text version loses those numbers. Decide where the authoritative numbers must live, how references stay consistent, and what role counters can still play.
Key takeaways
- A generated before or after box needs a content value and a suitable originating element.
- Required information belongs in the HTML; generated decoration must not be its only source.
- The alternative after a slash explains or silences a generated mark, subject to the target browser and assistive technology.
- Reset starts a named counter while increment advances it; repeated resets can repeat the same displayed number.
Terms in this lesson
- CSS counter
- A named numbering value created, advanced or assigned by counter properties and displayed by counter functions.
- pseudo-element
- A CSS-selected part associated with an originating element, such as a text part, marker or generated before or after box.
References
- CSS Pseudo-Elements Module Level 4 (W3C CSS Working Group)
- CSS Generated Content Module Level 3 (W3C CSS Working Group)
- CSS Lists and Counters Module Level 3 (W3C CSS Working Group)
- CSS Counter Styles Level 3 (W3C CSS Working Group)
- CSS Basic User Interface Module Level 4 (appearance) (W3C CSS Working Group)
- Unicode Text Segmentation (Unicode 14) (Unicode Consortium)
- Unicode Text Segmentation (Unicode 15.1) (Unicode Consortium)
- Indic Layout Requirements (initial letters) (W3C Internationalization Working Group)
- ::before (MDN Web Docs) (Mozilla)
- content: alternative text (MDN browser-compat-data) (Mozilla)
- ::marker (MDN browser-compat-data) (Mozilla)
- web-features: counter-set (W3C WebDX Community Group)
- F87: inserting non-decorative content with ::before and ::after (WCAG technique, obsolete) (W3C Web Accessibility Initiative)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress