In CSS, ::before
creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content
property. It is inline by default.
/* Add a heart before links */ a::before { content: "
♥"; }
Note: The pseudo-elements generated by ::before
and ::after
are contained by the element's formatting box, and thus don't apply to replaced elements such as <img>
, or to <br>
elements.
Syntax
/* CSS3 syntax */ ::before /* CSS2 syntax */ :before
Note: CSS3 introduced the ::before
notation (with two colons) to distinguish pseudo-classes from pseudo-elements. Browsers also accept :before
, introduced in CSS2.
Examples
Adding quotation marks
One simple example of using ::before
pseudo-elements is to provide quotation marks. Here we use both ::before
and
to insert quotation characters.::after
HTML
<q>Some quotes,</q> he said, <q>are better than none.</q>
CSS
q::before { content: "«"; color: blue; } q::after { content: "»"; color: red; }
Result
Decorative example
We can style text or images in the content
property almost any way we want.
HTML
<span class="ribbon">Notice where the orange box is.</span>
CSS
.ribbon { background-color: #5BC8F7; } .ribbon::before { content: "Look at this orange box."; background-color: #FFBA10; border-color: black; border-style: dotted; }
Result
To-do list
In this example we will create a simple to-do list using pseudo-elements. This method can often be used to add small touches to the UI and improve user experience.
HTML
<ul> <li>Buy milk</li> <li>Take the dog for a walk</li> <li>Exercise</li> <li>Write code</li> <li>Play music</li> <li>Relax</li> </ul>
CSS
li { list-style-type: none; position: relative; margin: 2px; padding: 0.5em 0.5em 0.5em 2em; background: lightgrey; font-family: sans-serif; } li.done { background: #CCFF99; } li.done::before { content: ''; position: absolute; border-color: #009933; border-style: solid; border-width: 0 0.3em 0.25em 0; height: 1em; top: 1.3em; left: 0.6em; margin-top: -1em; transform: rotate(45deg); width: 0.5em; }
JavaScript
var list = document.querySelector('ul'); list.addEventListener('click', function(ev) { if( ev.target.tagName === 'LI') { ev.target.classList.toggle('done'); } }, false);
Here is the above code example running live. Note that there are no icons used, and the check-mark is actually the ::before
that has been styled in CSS. Go ahead and get some stuff done.
Result
Notes
Although the positioning fixes in Firefox 3.5 do not allow content to be generated as a separate previous sibling (as per the CSS spec stating "The :before and :after pseudo-elements elements interact with other boxes... as if they were real elements inserted just inside their associated element."), they can be used to provide a slight improvement on tableless layouts (e.g., to achieve centering) in that, as long as the content to be centered is wrapped in a further child, a column before and after the content can be introduced without adding a previous or following sibling (i.e., it is perhaps more semantically correct to add an additional span as below, than it would to add an empty <div/> before and after). (And always remember to add a width to a float, since, otherwise, it will not float!)
HTML
<div class="example"> <span id="floatme">"Floated Before" should be generated on the left of the viewport and not allow overflow in this line to flow under it. Likewise should "Floated After" appear on the right of the viewport and not allow this line to flow under it.</span> </div>
CSS
#floatme { float: left; width: 50%; } /* To get an empty column, just indicate a hex code for a non-breaking space: \a0 as the content (use \0000a0 when following such a space with other characters) */ .example::before { content: "Floated Before"; float: left; width: 25% } .example::after { content: "Floated After"; float: right; width:25% } /* For styling */ .example::before, .example::after, .first { background: yellow; color: red; }
Result
Specifications
Specification | Status | Comment |
---|---|---|
CSS Pseudo-Elements Level 4 The definition of '::before' in that specification. |
Working Draft | No significant changes to the previous specification. |
CSS Transitions | Working Draft | Allows transitions on properties defined on pseudo-elements. |
CSS Animations | Working Draft | Allows animations on properties defined on pseudo-elements. |
Selectors Level 3 The definition of '::before' in that specification. |
Recommendation | Introduces the two-colon syntax. |
CSS Level 2 (Revision 1) The definition of '::before' in that specification. |
Recommendation | Initial definition, using the one-colon syntax |
Browser compatibility
Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|---|
:before support |
(Yes) | (Yes) | 1.0 (1.7 or earlier)[1] | 8.0 | 4 | 4.0 |
::before support |
(Yes) | (Yes) | 1.5 (1.8)[1] | 9.0 | 7 | 4.0 |
Support of animations and transitions | 26 | (Yes) | 4.0 (2.0) | No support | No support | No support |
Feature | Android | Chrome | Edge | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|---|
:before support |
(Yes) | (Yes) | (Yes) | (Yes) | ? | ? | ? |
::before support |
(Yes) | (Yes) | (Yes) | (Yes) | 7.1 | ? | 5.1 |
Support of animations and transitions | 26 | (Yes) | (Yes) | 4.0 (4.0) | No support | No support | No support |
[1] Firefox prior to version 3.5 only implemented the CSS 2.0 version of :before. Not allowed were position
, float
, list-style-*
and some display properties. Firefox 3.5 removed those restrictions.
Quantum CSS notes
- Gecko has a bug whereby the
::before
and::after
pseudo-elements are still generated even if thecontent
property value is set tonormal
ornone
. As per spec, they shouldn't be (bug 1387931). This has been fixed in Firefox's new parallel CSS engine (also known as Quantum CSS or Stylo, planned for release in Firefox 57).