Tailwind CSS Content
When working with CSS, the content property plays a crucial role in defining content for pseudo-elements like ::before and ::after. Tailwind CSS provides content utility that can be used with the before and after modifiers to style and control the display of pseudo-elements.
| Class | Properties | Example |
|---|---|---|
content-none | content: none; | <div className="content-none"></div> |
Overview of Content
Adding the Pseudo-elements Content
To add content to ::before or ::after pseudo-element, use the before:content-['*'] or after:content-['*'] variants. The text inside brackets defines the content to be displayed.
export default function App() { return <h1>Hello world</h1> }
Linking Attributes with Content
To allow pseudo-elements to reference an attribute value, use the content-[attr(attribute-name)] syntax to dynamically populate the pseudo-element:
export default function App() { return <h1>Hello world</h1> }
Adding Spaces and Underscores
To add a space inside the content, use underscores(_), e.g, content-["Spaced_Content"]. When you have to actually add an underscore, escape it with a backslash, e.g., content-["Underscored\_Content"].
export default function App() { return <h1>Hello world</h1> }
States and Responsiveness
Hover and Focus States
Tailwind CSS allows you to conditionally apply content styles. By prepending state modifiers like hover: or focus:, you can change pseudo-element content based on user interaction:
export default function App() { return <h1>Hello world</h1> }
Breakpoint Modifiers
Tailwind’s breakpoint modifiers allow you to modify the content of pseudo-elements based on screen size. This approach provides responsive designs by appending breakpoint prefixes such as sm:, md:, or lg:.
export default function App() { return <h1>Hello world</h1> }
Custom Content
Extending the Theme
Tailwind, by-default, only provides the content-none utility. However, it lets you define custom content values.
To add a new content utility, extend the content property in the theme section of your tailwind.config.js. Once added, use the custom values via their class names:
export default function App() { return <h1>Hello world</h1> }
Using Arbitrary Values
Arbitrary values allow you to use one-off values without extending the theme. To use an arbitrary content value, surround the desired value with square brackets [] in the utility class.
export default function App() { return <h1>Hello world</h1> }
Real World Examples
Product Card with Sale Badge
A product card component that displays a "SALE" badge in the top-right corner using content-['SALE'] before pseudo-element.
export default function App() { return <h1>Hello world</h1> }
Required Form Fields Indicator
A form component that shows required fields with an asterisk using content-['*'] before pseudo-element.
export default function App() { return <h1>Hello world</h1> }
Feature List with Checkmarks
A feature list component that adds checkmark icons using content-['✓'] before pseudo-element.
export default function App() { return <h1>Hello world</h1> }
Social Links with Icons
A social media links component that adds icons using content-['→'] before pseudo-element with hover effects.
export default function App() { return <h1>Hello world</h1> }
Breadcrumb Navigation
A breadcrumb component that adds custom arrow separator using content-['→'] after pseudo-element.
export default function App() { return <h1>Hello world</h1> }
Customization Examples
Animated Progress Steps
An animated progress indicator with custom step markers and transitions.
export default function App() { return <h1>Hello world</h1> }
Social Card with Icon Decorators
A social card with custom icon decorators using content utility.
export default function App() { return <h1>Hello world</h1> }
File Card with Status Icons
A file card using content utility for status and action icons
export default function App() { return <h1>Hello world</h1> }
Best Practices
Maintain Design Consistency
Using content-* utilities in Tailwind CSS effectively requires a structured approach to maintain design consistency. These utilities allow for inserting generated content before or after elements using before:content-[''] or after:content-[''].
Ensuring a uniform look across a project involves adhering to predefined design patterns and avoiding inconsistent use of content insertion. For example, when using the content utility to add icons, indicators, helper text, etc., it is best to follow a uniform typography, size, and color scheme to avoid discrepancies.
Optimize for Reusability
Reusability is critical when working with content-* utilities, especially in component-driven development. By default, Tailwind only provides content-none, so custom content utilities must be defined in the Tailwind configuration. Using the extend property within the theme section of tailwind.config.js, developers can add custom content utilities for frequent use.
For instance, defining custom utilities such as before:content-['✓'] or after:content-['→'] ensures that commonly used pseudo-elements are standardized across the project. This eliminates the need for inline styles, reducing redundancy and improving maintainability.
Accessibility Considerations
Enhance Readability and Navigability
Readability is a critical factor when using content-* utilities. Dynamically inserted content should always complement, rather than obscure, surrounding text. Using appropriate contrast, spacing, and font sizes ensures that the added content remains legible for all users.
For navigability, content insertion should not disrupt logical content flow. If before:content-[''] is applied to headings or paragraphs, ensuring appropriate margin spacing with before:mr-2 prevents visual distractions.
Keyboard navigation should also be factored in. Since pseudo-elements are not focusable by default, they should be used only for decorative purposes rather than essential interactive elements.
Support Accessible Interactive Elements
Interactive elements should not rely solely on content-* utilities for functionality. Since pseudo-elements (::before and ::after) are not part of the DOM in a way that allows user interaction, they cannot receive focus or click. This means that any critical functionality—such as navigation, form actions, or buttons—should not be dependent on content-* for essential behavior. Instead, pseudo-elements should be treated as visual enhancements to improve aesthetics without affecting usability.
For example, a breadcrumb navigation can use before:content-['→'] to add a separator, but the actual clickable links should still be standard <a> elements for proper focusability and accessibility. Similarly, a list styled with after:content-['✓'] should still contain real text.