Last updated: 28 November 2025

Tailwind CSS Content

The content utility class in Tailwind CSS allows you to manipulate the content of pseudo-elements, such as ::before and ::after, and control the generated content in your HTML elements.


Tailwind Content

The content-* utilities in Tailwind let you inject content into ::before and ::after pseudo-elements without writing custom CSS. If you've ever needed to add decorative quotes, icons, badges, or visual flourishes to elements, this is how you do it in Tailwind.

Why This Matters

Pseudo-elements are incredibly useful for adding decorative content that shouldn't be in your HTML. Think:

  • Quotation marks around blockquotes
  • Icons before links or headings
  • Decorative separators
  • Custom bullets for lists
  • Visual indicators (required field asterisks, external link icons)

Before Tailwind's content utilities, you had to write custom CSS for every pseudo-element. Now you can do it inline.

html
<div class="w-full">
To check out a Google link, follow these simple steps. Firstly, open your
preferred web browser and click on this
<a href="www.google.com" class="before:content-['!']">Google link</a> the
address bar. Press Enter or click on the search button.
</div>

Preview

To check out a Google link, follow these simple steps. Firstly, open your preferred web browser and click on this

Google link

the address bar. Press Enter or click on the search button.

Adding Text Content

The simplest use case is adding text:

html
<blockquote class="before:content-['"'] after:content-['"']">
This quote will have proper quotation marks around it.
</blockquote>

Important: Notice the nested quotes? You need to escape them properly:

  • Outer quotes are single: content-['...']
  • Inner quotes are double: content-['"']

Here's a more practical example

adding "New" badges to links:

html
<a href="/blog/latest-post"
class="before:content-['New'] before:bg-red-500 before:text-white before:text-xs before:px-2 before:py-1 before:rounded before:mr-2">
Check out our latest article
</a>

Preview

This creates a little red "New" badge before the link text. You style the pseudo-element just like any other element in Tailwind.

Using Icons and Special Characters

You can insert Unicode characters directly:

html
<a href="https://example.com"
class="after:content-['_↗'] after:text-blue-500">
External Link
</a>
<!-- Star ratings -->
<div class="before:content-['★★★★☆'] before:text-yellow-400">
4 out of 5 stars
</div>
<!-- Checkmark for completed items -->
<li class="before:content-['✓'] before:text-green-500 before:mr-2">
Task completed
</li>

Preview

External Link

4 out of 5 stars

  • Task completed

  • Pro tip: For more complex icons, use an icon font or SVG background images instead. Pseudo-elements work best for simple decorative content.

    Pulling Content from Attributes

    This is where things get interesting. You can use attr() to pull content from HTML attributes:

    html
    <a href="/docs"
    data-label="Documentation"
    class="after:content-[attr(data-label)] after:ml-2 after:text-sm after:text-gray-500">
    Read the
    </a>

    This renders as: "Read the Documentation" where "Documentation" comes from the data-label attribute. Why is this useful? Dynamic content. If you're generating HTML from a backend, you can change the pseudo-element content without touching CSS:

    html
    <!-- Different tooltips for different elements -->
    <button data-tooltip="Save changes"
    class="after:content-[attr(data-tooltip)] after:absolute after:bottom-full after:left-1/2 after:-translate-x-1/2 after:bg-black after:text-white after:px-2 after:py-1 after:rounded after:text-xs after:whitespace-nowrap after:opacity-0 hover:after:opacity-100">
    Save
    </button>
    <button data-tooltip="Delete permanently"
    class="after:content-[attr(data-tooltip)] after:absolute after:bottom-full after:left-1/2 after:-translate-x-1/2 after:bg-black after:text-white after:px-2 after:py-1 after:rounded after:text-xs after:whitespace-nowrap after:opacity-0 hover:after:opacity-100">
    Delete
    </button>

    Same classes, different tooltip text. Efficient.

    Real-World Examples

    Custom Blockquote Styling

    html
    <blockquote class="relative pl-6 italic text-gray-700 before:content-['"'] before:absolute before:left-0 before:text-6xl before:text-blue-500 before:font-serif before:-top-4">
    The only way to do great work is to love what you do.
    </blockquote>

    Preview

    The only way to do great work is to love what you do.

    This creates a large decorative opening quote before the blockquote text. Required Field Indicators

    html
    <label class="block text-sm font-medium text-gray-700 after:content-['*'] after:ml-1 after:text-red-500">
    Email Address
    </label>
    <input type="email" required class="mt-1 block w-full rounded border-gray-300" />

    Preview

    The asterisk appears automatically from the after: pseudo-element. Change one class and all required fields update.

    Step Numbers in Instructions

    html
    <ol class="space-y-4">
    <li class="before:content-['1.'] before:inline-block before:w-8 before:h-8 before:bg-blue-500 before:text-white before:rounded-full before:text-center before:leading-8 before:mr-3">
    Create a new project
    </li>
    <li class="before:content-['2.'] before:inline-block before:w-8 before:h-8 before:bg-blue-500 before:text-white before:rounded-full before:text-center before:leading-8 before:mr-3">
    Install dependencies
    </li>
    <li class="before:content-['3.'] before:inline-block before:w-8 before:h-8 before:bg-blue-500 before:text-white before:rounded-full before:text-center before:leading-8 before:mr-3">
    Run the development server
    </li>
    </ol>

    Each list item gets a styled number badge via the before: pseudo-element.

    The Bottom Line

    The content-* utilities are perfect for decorative flourishes that would clutter your HTML. Use them for visual enhancements, not core content. And remember: if it's important enough for a user to read or interact with, it belongs in your HTML, not a pseudo-element. Start simple, add some icons or decorative elements, then experiment with the attr() technique for dynamic content. Once you get comfortable, you'll find dozens of use cases where pseudo-elements clean up your markup significantly.

    Tailwind Content Class Table

    ClassProperties
    content-nonecontent: none;

    External Resources

    Windframe Tailwind blocks

    Content

    Windframe is an AI visual editor for rapidly building stunning web UIs & websites

    Start building stunning web UIs & websites!

    Build from scratch or select prebuilt tailwind templates