Detailed explanation
The CSS content property defines generated content, most commonly for the ::before and ::after pseudo-elements. These pseudo-elements create boxes that behave like the first and last children of a selected element, without adding actual elements to the DOM. For these pseudo-elements to generate a box, content must have a value other than normal or none. An empty string, content: "", is sufficient: it creates an empty box that you can style as a decorative shape, divider, or icon background. Other rules, such as display: none, can still prevent it from appearing.
The property can generate literal text, attribute values through attr(), formatted counters, quotation marks, or images through url(). For example, .required::after { content: ' *'; color: red; } displays a red asterisk after the element’s existing content. A rule such as content: attr(data-label) reads an attribute from the originating element. Multiple values can be combined, as in content: 'Step ' counter(step) ': ';. Generated content then participates in CSS layout and can receive styles such as color, padding, positioning, and display.
Counters are useful when numbering must follow a custom visual structure. In the supplied example, ol resets the section counter, each li::before increments it, and content: counter(section) '. '; displays the current number followed by punctuation. The content property displays the counter value; counter-reset and counter-increment manage its state. A native ordered list already has numbering, so adding counter-based prefixes without adjusting its default markers can show duplicate numbers. Prefer native list markers or ::marker when they meet the requirement.
Interviewers usually look for the distinction between generated presentation and meaningful document content. Pseudo-elements are convenient for decorative indicators and visual tooltip labels, but they are not DOM nodes and cannot independently receive keyboard focus. Their announcement by assistive technology varies, so essential instructions, accessible labels, and meaningful tooltip text should not depend solely on CSS-generated content. A required-field asterisk should accompany appropriate form semantics rather than replace them.
Key points to remember
- ::before and ::after generate boxes only when content is neither normal nor none.
- content: "" creates an empty box suitable for CSS decorations.
- Supported content includes strings, attr() values, counters, quotes, and url() images.
- Counter properties manage numbering; content displays the resulting value.
- Generated content is not a DOM node and should not be the sole source of essential information.
Common mistakes candidates make
- Setting dimensions or backgrounds on ::before or ::after while forgetting content.
- Using generated text as the only accessible label, required-field instruction, or meaningful tooltip.
- Adding custom counter prefixes to an ordered list without accounting for its existing markers.
Likely follow-up questions
What is the difference between content: "" and content: none?
An empty string generates an empty pseudo-element box that can display borders, backgrounds, and other styling. The value none prevents the ::before or ::after box from being generated.
Can JavaScript select a pseudo-element using querySelector()?
No, a pseudo-element is not an actual DOM element. You can inspect its computed styles with getComputedStyle(element, '::before') and influence its appearance through classes, attributes, or CSS custom properties on the originating element.
How do counter() and counters() differ?
counter(name) displays one counter value. counters(name, '.') combines values from nested counters with the given separator, which is useful for hierarchical numbering such as 1.2.3.
Interview tip: Start with the box-generation requirement, demonstrate the required-field asterisk, and finish with the accessibility limitation.
