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 ::after to insert quotation characters.

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 {
  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

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidiOS SafariSamsung Internet
Basic supportChrome Full support Yes
Full support Yes
Full support Yes
Alternate Name
Alternate Name Uses the non-standard name: :before
Edge Full support Yes
Full support Yes
Full support Yes
Alternate Name
Alternate Name Uses the non-standard name: :before
Firefox Full support 1.5
Notes
Full support 1.5
Notes
Notes Before Firefox 57, Firefox had a bug where ::before pseudo-elements were still generated, even if the content property value were set to normal or none.
Notes Before Firefox 3.5, only the CSS level 2 behavior of :before was supported, which disallowed position, float, list-style-* and some display properties.
Full support 1
Alternate Name
Alternate Name Uses the non-standard name: :before
IE Full support 9
Full support 9
Full support 8
Alternate Name
Alternate Name Uses the non-standard name: :before
Opera Full support 7
Full support 7
Full support 4
Alternate Name
Alternate Name Uses the non-standard name: :before
Safari Full support 4
Full support 4
Full support 4
Alternate Name
Alternate Name Uses the non-standard name: :before
WebView Android Full support Yes
Full support Yes
Full support Yes
Alternate Name
Alternate Name Uses the non-standard name: :before
Chrome Android Full support Yes
Full support Yes
Full support Yes
Alternate Name
Alternate Name Uses the non-standard name: :before
Edge Mobile Full support Yes
Full support Yes
Full support Yes
Alternate Name
Alternate Name Uses the non-standard name: :before
Firefox Android Full support Yes
Full support Yes
Full support Yes
Alternate Name
Alternate Name Uses the non-standard name: :before
Opera Android ? Safari iOS Full support 5.1Samsung Internet Android Full support Yes
Animation and transition supportChrome Full support 26Edge Full support YesFirefox Full support 4IE No support NoOpera No support NoSafari No support NoWebView Android Full support YesChrome Android Full support YesEdge Mobile Full support YesFirefox Android Full support 4Opera Android No support NoSafari iOS No support NoSamsung Internet Android Full support Yes

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
See implementation notes.
See implementation notes.
Uses a non-standard name.
Uses a non-standard name.

See also