CSS Reference Pseudo-class

content 58661p

The content property is used with the ::after pseudo-elements to generate content that is to be inserted into an element in the page. 255s2f

The value of the content property is the content inserted into that element via the pseudo-elements.

The content inserted using the content property can be string(s) of text, glyphs, images, counters (for styling lists), or quotes. Combining multiple values into one is also possible. See the list of values below and the examples for details.

Note that the content property must be included in the set of rules for the ::after in their respective entries.

Accessibility 553zt

Content inserted into a page using pseudo-elements is not inserted into the DOM—it is only visually displayed. Hence, screen readers won’t be able to access and read the content generated using pseudo-elements. So, it is recommended that you don’t use pseudo-elements to insert vital content into a page (such as footer notes that are relevant to the article, for example).

Pseudo-elements are mostly used to insert and style cosmetic content, and should not be relied on to insert content that is relevant to the meaning and completeness of the content on the page.

Also, since the content inserted using pseudo-elements is not inserted into the DOM, this means that you cannot attach any event handlers to it using JavaScript.

Official Syntax 55184y

  • Syntax:

    content: normal | none | [ <string> | <uri> | <counter> | attr(<identifier>) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit 
                           
  • Initial: normal
  • Applies To: ::after pseudo-elements
  • Animatable: no

Values 584j31

none
No content is inserted. The pseudo-element is not generated.
normal
Computes to none for the ::after pseudo-elements.
<string>
A string of text. The string of text is wrapped in quotation marks. See the <string> data type entry for a list of possible values.

Example: The following add a “New!” note after elements (such as items in a list of products) that have the class new.

.new::after {
    content: "New!";
    color: green;
}
                            

You may also include newlines in the generated content by writing the “\A” escape sequence in one of the strings after the content property. This inserted line break is still subject to the white-space property.

<uri>
The URI is specified using the url() function. It points to an external resource such as an image. If the resource or image can’t be displayed, the browser must either leave it out as if it were not specified or display some indication that the resource cannot be displayed.

For example, the following adds an icon to buttons with a class in a page.

button.::before {
    content: url(path/to/.png);
}
                            

<counter>
A counters().
See the CSS Counters entry for examples and more information.

Example:

li {
    content: counter(my-counter-name);
}
                            

Counters are a fairly long topic and are outside the scope of this entry. For more information, please refer to the the CSS Counters entry.

open-quote | close-quote
These values are replaced by the appropriate string from the quotes property. Example:

q, blockquote {
  quotes: "“" "”" "‘" "’";
}
q:before, blockquote:before {
    content: open-quote;
}
q:after, blockquote:after {
    content: close-quote;
}
                        

For a detailed explanation and more examples refer to the quotes property entry.

no-open-quote | no-close-quote
Stops the quotes.
attr(X)
This function (abbreviation for ‘attribute’) returns as a string the value of attribute X of an element. If the element does not have an attribute X, an empty string is returned.

For example, links <a> have an href attribute which determines the location to which the link points. Using the content property with the attr() function you can retrieve the value of the URL in the href attribute, which is pretty powerful. This can be used in print style sheets to print the URL to which a link points, right after the content of that link (using the ::after pseudo-element). For example:

@media print {
    a[href]::after {
        content: attr(href);
    }
}
                        

The above rule selects all links that have an href attribute (using the ::after pseudo-element, which will be inserted into the links after the link’s content.

The attr() function can retrieve the value of any attribute of an element, including custom HTML5 data-* attributes. For example:

<li data-label="todo">Buy Milk</li>
                        
li::before {
    content: attr(data-label);
    color: grey;
}
                        

In CSS3, the attr() expression gets a new syntax. The new syntax is not stable, not ed in any browser yet, and there are no examples of use cases anywhere. The specification also says that the new syntax is at risk and may be dropped during the Candidate Recommendation stage. If the new syntax is not dropped, this entry will be updated with the new values. The syntax looks like the following:

attr( <attr-name> <type-or-unit>? [ , <attr-fallback> ]? )
                        

where <attr-name> is the attribute name, <type-or-unit> is an optional argument which tells the agent how to interpret the attribute value, and defines a type for the attr() expression. If omitted, ‘string’ is implied. The <attr-fallback> argument represents a fallback value, which is used if the named attribute is missing, or its value cannot be parsed into the given type or is invalid/out-of-range for the property. If it’s absent, the default value for the given <type-or-unit< (from the list below) is implied.

The type or unit argument can be one of the following: ‘string’, ‘color’, ‘url’, ‘integer’, ‘number’, ‘length’, ‘angle’, ‘time’, or ‘frequency’.

As mentioned above, this entry will be updated with an elaborated description and examples if the new expression syntax is not dropped in the future.

Notes z5jo

It is possible to combine different content values in the content property. The values are then concatenated into one. For example, the following will retrieve the value of the custom data attribute from the example above, and add a colon after it:

li::before {
    content: attr(data-label) ":";
    color: grey;
}
                

The following example improves the above example where the href value of a link is retrieved and printed in print style sheets. Printing the URl right after the link content without some visual separators may confuse the reader, so wrapping the URL value in parenthesis is useful and preferred. This can be done by combining the attr() function with two strings of text for the two parenthesis like so:

@media print {
    a[href]::after {
        content: " (" attr(href) ")";
    }
}
                

The ::after are displayed inline by default.

Separation of Concerns—Content and Design 5zj71

In addition to the accessibility issue, some people may argue that adding content via CSS is against the concept of separation of concerns—design and content should be separated to help maintain code better. This may be true in most cases, but it still allows for modular style sheets. For example, the above example where the generated content is used to style links on print style sheets is very useful and can be used in any website by just pasting the snippet into the style sheet.

Other examples such as inserting an “external link” icon to all links in a web page that refer to external pages are also veru useful and modular, and maintaining these styles and content is fairly easy, so the concept of adding content via CSS may be frowned upon by some purists, but it is still useful, and it is up to CSS authors and developers to decide what kind of content to add without affecting the maintainability of their code.

Live Demo 2x4j2k

The following live demo shows different content added using the content property in combination with the ::after pseudo-elements.

View this demo on the Codrops Playground

You can see these demos and more in the ::after entries.

Browser k5t66

The content property is ed in all major browsers: Chrome, Firefox, Safari, Opera, Internet Explorer, and on Android and iOS.

Written by

Last updated June 3, 2020 at 12:33 pm by Mary Lou

Do you have a suggestion, question or want to contribute? Submit an issue.