I’m trying to display a ::before
pseudo-element on a <progress>
bar like a label with the value
attribute. Currently, I have a solution that display the ::before
in Brave (v1.61.109), while it doesn’t appear in Safari(17.1.2) and Firefox (121.0). However, I still encounter an issue regarding the consideration of the height of the pseudo-element. I think that naturally the pseudo-element itself has no direct impact on the flow. However, I would like to find an effective workaround.
In addition to displaying the element, I’d like it to be considered in the height of the parent box, specifically .card
. I’m looking for a dynamic solution.
Here is the HTML code:
<div class="card">
<p>Item 1</p>
<p>Item 2</p>
<progress max="100" value="100"></progress>
</div>
And here is the associated CSS:
.card {
display: flex;
flex-direction: column;
width: 300px;
background: beige;
}
progress[value] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: none;
width: 100%;
}
progress {
position: relative;
}
progress:before {
content: attr(value) '% some text here';
font-size: 2rem;
color: black;
text-align: center;
height: 2rem;
line-height: normal;
}
progress[value]::-webkit-progress-value {
background-color: green;
border-radius: .2rem;
}
progress[value]::-moz-progress-bar {
background-color: green;
border-radius: .2rem;
}
Does anyone have ideas on how to solve this display ?
2
Answers
Issue with the Use of Pseudo-elements in CSS
before
pseudo-element is positioned before the content inside the tag, but not before the tag's opening. As a result, the flex rule never applies correctly, as it targets the direct children of.car
but the:befoer
pseudo-element is the first child of<progress>
.The solution, therefore, involves modifying the HTML code as follows:
A bit of JavaScript like this:
I came across your question and the so far the only thing i can think of as a workaround is to use a pinch of javascript to update the progress % instead of the attr() in CSS.
There are 2 reasons why I chose JS,
Now, using a div,
<div id="progress-label"></div>
, to contain the progress %, we can ensure that the progress % sits within the parent (.card) element since it’s a block-level element and statically positioned. The JS snippet will just update the text content within the div in the DOM upon execution.You can try using this template and edit it to meet your needs.
Do check out the codepen here for a demo.
https://codepen.io/Jun-Wen-Soh/pen/ZEPQgGR
HTML
CSS
JS