Why doesn’t width/height work with non positioned pseudo elements?

First, it’s not about percentage values. You will have the same result even with pixel values and both width and height aren’t working.

Pseudo elements are inline elements and their width/height is only defined by their content and the width/height set with CSS will be ignored.

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. ref

width

This property does not apply to non-replaced inline elements. The content width of a non-replaced inline element’s boxes is that of the rendered content within them ref

The ‘height’ property does not apply. The height of the content area should be based on the font … ref


By making the pseudo element position:absolute you will now consider the rules that applies to Absolutely positioned element in order to calculate width and height. You will also notice that the element will have a computed value of block within display.

enter image description here

You should also pay attention to the use of positioned element which means either relative, absolute, fixed or sticky BUT making the element position:relative will keep it an inline level element and you still cannot use width/height.

.positioned {
    position: relative;
    height: 15px;
    background-color: aquamarine;
    margin-bottom: 10px;
}
.positioned::before {
    position: relative;
    content: "";
    background: red;
    width: 80%;
    height: 100%;
}

.not-positioned {
    height: 15px;
    background-color: aquamarine;
    margin-bottom: 10px;
}
.not-positioned::before {
    content: "";
    background: red;
    width: 80%;
    height: 100%;
}
<div class="positioned"></div>
<div class="not-positioned"></div>

This said, you can simplify you code by considering gradient if you want to achieve the same visual:

.positioned {
  position: relative;
  height: 15px;
  background:
   linear-gradient(red,red) left/80% 100% no-repeat,
   aquamarine;
  margin-bottom: 10px;
}
<div class="positioned"></div>

Leave a Comment