How to fix CSS issues with :before not working
Fixes for :before pseudo elements not working with your CSS. We will go over a checklist on how to do this.
Dec 2, 2022 | Read time 6 minutesπ Table of contents
If you are experiencing issues with the :before
pseudo element in CSS, there are a few potential fixes you should consider.
1. Check the syntax: First and foremost, make sure that you are entering the correct syntax for the :before
pseudo element, as there are slight variations between different browsers. Generally speaking, the syntax should look similar to this:
p::before { /* we are using <p> here, but it can be any element*/
content: '';
}
2. Include a content property: The content
property is essential for the :before
pseudo element to work properly. Without the content property, it may not appear.
3. Check the you are using the right HTML tag: Tags that are classified as replaced elements will not work with :before
. These include - <audio>
,
<canvas>
,
<embed>
,
<iframe>
,
<img>
,
<input>
,
<object>
,
<video>
4. Check for CSS specificity issues: If you are using multiple elements with the :before
pseudo element, you may be encountering specificity issues where the declarations in one block of code are overriding the declarations in another. To avoid this, you can use the !important
declaration to make a style more specific and ensure that it is not overridden.
5. Check the browser support: As mentioned previously, different browsers may have slightly different syntax requirements for the :before
pseudo element. Make sure
to double-check the syntax to ensure that it is supported in the browser that you are using.
Check the syntax
The :before
pseudo element (when combined with the content
property) creates a child element before the elementβs contents.
To use the :before
property, the usual syntax is as as follows.
p::before { /* we are using <p> here, but it can be any element*/
content: '';
}
We can use the two colon version ::before
or the single colon version :before
. The difference is that the double colons (::before
)
was introduced by CSS 3 since it also introduced both pseudo elements and pseudo classes. Therefore it needed away to distiguish
between the two.
Most modern browsers support both versions. Support for the double colon ::before
is not available for IE versions (eg IE11 or less)
Not using the content property
A common reason of why your :before
is not working is that you are not specify the content
property. We need to delare content:""
.
For example, the following will not work:
.my-element::before {
background: red;
width: 100px;
height: 100px;
}
.my-element::before {
content: ""; /* :before will only appear if this content is declared */
background: red;
width: 100px;
height: 100px;
}
Check the you are using the right HTML tags
Another consideration when using the :before
pseudo element is the HTML tag you are applying that for.
According to the HTML specificiation (https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements) - the following elements can be replaced elements:
<audio>
<canvas>
<embed>
<iframe>
<img>
<input>
<object>
<video>
.
Replaced elements are HTML elements in which the browser will replace the content
. Therefore, whatever we have declared with the :before
will be replaced.
Take the following example with <img>
. This will not work since img
is a replaced HTML element.
img::before { /* will not work because its a replaced element */
content: "before";
}
img::after { /* will not work because its a replaced element */
content: "after";
}
More information can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element
Check CSS specifity issues
We need to check to see if the :before
declaration for our element is being overridden by another CSS rule somewhere else further down the CSS file.
As an example, lets take the following
CSS:
p::before {
content: "BB";
}
...
...
p::before { /* This will override the previous declaration */
content: "AA";
}
In the above, our p
will have :before
content of βAAβ (overwritting βBBβ). If two declarations that targat the same element, the style that is further down the CSS file will win.
In these cases we can use the !important
property, but use it carefully.
Check browser support
There are limitations on the use of the :before
pseudo elements - so we need to consider browser combatbility. Some common issues include:
- IE9, IE10, IE11 ignore CSS rem units in the line-height property
- Firefox & Edge do not support :after and :before for input fields
- Animation and transition support limited on IE, Safari and Safari Mobile. Chrome supports this as of version 26.
- IE8 only supports the single-colon CSS 2.1 syntax (i.e. :pseudo-class). It does not support the double-colon CSS3 syntax
Summary
This post went through various reasons why :before
is not working in your CSS and HTML design. The reasons range from:
- Not using the
content
property as intended. - The syntax is not correct (eg using
::before
vs:before
) - Not using valid HTML tags that support the
:before
property. HTML tags that are replaced elements will not work with:before
! - Check for browser support - IE versions will only support the single colon
:before
- since this is part of CSS2. - Check for CSS specifity issues - having two CSS styles that target the same element will cause this issue. The style that is declared lower on the CSS file will take effect over the other!
Hopefully the above checks will fix your CSS :before
problems!