Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I want to set a width of ::before pseudo-element to 80%. If I use positioning then everything works, but if I don't use it then everything fails.

Could you explain me why percentage width doesn't work without positioning? If you can please add some references to the specification

.positioned {
    position: relative;
    height: 15px;
    background-color: aquamarine;
    margin-bottom: 10px;
}
.positioned::before {
    position: absolute;
    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>
like image 444
Roman Roman Avatar asked Dec 07 '25 18:12

Roman Roman


1 Answers

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>
like image 106
Temani Afif Avatar answered Dec 09 '25 14:12

Temani Afif