Definition and Usage
The ::before pseudo-element selector generates a child pseudo-element directly before the selected element's actual content, acting as its first child, and allows it to be styled.
The syntax of the ::before pseudo-element selector is as follows:
::before {
content: /* value โ specifies the content of the generated child pseudo-element: Required */;
/* specifies properties to style the generated child pseudo-element: Optional */
}
The content property specifies the content of the child pseudo-element generated by the ::before pseudo-element selector. This property is required.
If the content property is not specified or contains an invalid value (for example, none or normal), the ::before pseudo-element selector does not work.
Note:
The initial display value of the child pseudo-element generated by the ::before pseudo-element selector is inline.
Basic Example
The following example demonstrates how the ::before pseudo-element selector works.
p::before {
content: "๐";
vertical-align: 0.2em;
margin-right: 0.3em;
}
<p>
This is the content of the paragraph.
</p>
This is the content of the paragraph.
The actual applied result is that the ::before pseudo-element selector generates a child pseudo-element directly before the selected <p> element's actual content, acting as its first child, and styles it.
This is equivalent to marking up the HTML as if an additional element were inserted, as shown below:
<p>
<before>๐</before> <!-- There is no <before> tag;
this is a virtual markup for explanatory purposes. -->
This is the content of the paragraph.
</p>
Why Use It
The ::before pseudo-element selector is used to easily generate and style a child pseudo-element using CSS alone, without the hassle of manually marking up an additional child element in the HTML document.
Things to Keep in Mind
There are a few points to keep in mind when using the ::before pseudo-element selector.
Accessibility Considerations
The pseudo-element generates by the ::before pseudo-element selector is generated via CSS and is not part of the HTML structure. Therefore, it is only visible on the screen and does not exist in the actual DOM. Because of this, placing essential information within the content of a pseudo-element can hinder web accessibility for users relying on screen readers. When considering accessibility, the core principle is to ensure that necessary information is appropriately provided to all users.
The following is an example of a "Like!" button written without considering accessibility:
button::before {
content: "๐งก";
}
<button> tag.
<button type="button"></button>
In this case, because the <button> element does not include the actual text "Like!" in the HTML, users relying on screen readers may receive no information at all. Most screen readers do not interpret CSS-generated content.
Therefore, it is recommended to provide the information in another accessible way, such as adding an aria-label:
<button type="button" aria-label="Like!"></button>
The aria-label property is used to provide alternative text for web elements. Its value is a text string that screen readers use to read the element aloud to users.
Specifying the content Property Is Required
The ::before pseudo-element selector requires the content property to be specified.
All the examples so far have styled pseudo-elements generated with the ::before selector by providing content via the content property. However, what if you want to use a ::before pseudo-element purely for styling, without adding any actual content?
For instance, you might want to create simple shapes like a circle or rectangle using a ::before pseudo-element. The following example uses the ::before pseudo-element selector to style a short bar as a decorative element for a heading.
Pseudo-Element Selector
h2::before {
content: ""; /* <= Note this part */
display: block;
width: 2em;
height: 0.3em;
background-color: #000;
margin-bottom: 0.3em;
}
<h2>Pseudo-Element Selector</h2>
In this example, the pseudo-element generated with the ::before selector does not need any content. It is styled purely as a short bar decoration for the heading. However, if you look at the CSS, the content property of the ::before pseudo-element is set to an empty string ("").
Most Common Mistake!
The ::before pseudo-element selector requires the content property to be specified. If it is not specified, the ::before pseudo-element will not be applied.
As shown in the example above, when no actual content is needed for a ::before pseudo-element, simply set the content property to an empty string ("" or '').
Pointer Events Do Not Apply
The child pseudo-element generated by the ::before pseudo-element selector is, by definition, a virtual element. Therefore, pointer events that apply to actual elements do not apply to it.
- click
- hover
- active
- focus
- selection
- drag
- ...
Because pointer events such as those in the list above do not occur on this pseudo-element, pseudo-class selectors like :hover, :active, and :focus, or pseudo-element selectors like ::selection cannot be used on it.
Cannot Be Used on Elements That Cannot Have Actual Content
There are void elements that have only a start tag and cannot contain text nodes or nested elements (for example, <input>, <hr>, <img>). Among these elements, the <input> element has replacement content generated by the browser, and the <img> element has a resource linked via src as its replacement content.
The ::before pseudo-element selector generates a child pseudo-element directly before the actual content of the selected element. The <input> and <img> elements are not the target of application for the ::before pseudo-element selector. On the other hand, although the <hr> element is a void element, it has a rendered result that is considered actual content in CSS rather than replacement content, so it is the target of application for the ::before pseudo-element selector.
<input>, <img>).
input::before {
content: "๐งก";
}
img::before {
content: "๐งก";
}
<hr>.
hr::before {
content: "๐งก";
}
Practical Examples
The ::before pseudo-element selector is used to easily generate and style a child pseudo-element using CSS alone, without the hassle of manually marking up an additional child element before the content in the HTML document. Let's look at a few examples of its practical use.
Dividers for Navigation Items Used in Global Footers
<nav>
<ul>
<li><a href="">View Products</a></li>
<li><a href="">Privacy Policy</a></li>
<li><a href="">Customer Service</a></li>
</ul>
</nav>
Code Explanation
The <nav> tag represents a section of a page that contains links for navigation to other web pages or to sections within the current web page. Common examples include menus, tables of contents, and indexes.
ul {
display: flex;
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
color: inherit;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
li:not(:first-child)::before {
content: "";
display: inline-block;
width: 1px;
height: 0.8em;
background-color: rgba(0, 0, 0, .6);
margin: 0 1.1em;
vertical-align: -0.06em;
white-space: nowrap;
}
Arrows for 'Back' Buttons
<a href="">Back</a>
a {
color: inherit;
text-decoration: none;
padding: 0.5em 1em;
background-color: #fff;
border: 1px solid #777;
border-radius: 0.5em;
display: inline-flex;
align-items: center;
}
a::before {
content: "";
display: inline-flex;
width: 0.5em;
height: 0.5em;
border-left: 1px solid black;
border-bottom: 1px solid black;
transform: rotateZ(45deg);
margin-right: 0.2em;
}
Browser Compatibility
| Selector |
Desktop Chrome
|
Desktop Edge
|
Desktop Firefox
|
Safari
|
|---|---|---|---|---|
::before
|
1 | 12 | 1.5 | 4 |
Animation and transition support |
26 | 12 | 4 | 10.1 |
Specifications
| Specification | |
|---|---|
::before
|
CSS Pseudo-Elements Module Level 4 #generated-content |