I want to control linear-gradient based on an attribute value. My HTML:

<div class="percentage" data-percentage="50%"></div>

My css:

.percentage { width: 100px; border: .1px solid; border-radius: 2px; font-size: 1rem; padding: 1px; background-clip: content-box; background-image: linear-gradient( to right, #cccc 50%, transparent 0% ); } .percentage::before { content: attr(data-percentage); }

This works. What doesn't work is to control the linear-gradient with the attribute value:

background-image: linear-gradient( to right, #cccc attr(data-percentage), transparent 0% );

So it seems accessing an attr() inside linear-gradient() isn't possible? How can I control the linear gradient based on the attribute value?

https://jsfiddle.net/07gd82oe/

Michi's user avatar

This is possible but, unfortunately, it's not yet fully supported in Firefox or Safari as neither yet support the CSS type() function (compatibility, Can I Use):

let range = document.querySelector('input[type=range]'); range.addEventListener('input', (e)=>{ let {value} = e.target, percentageBar = document.querySelector('.percentage'); percentageBar.dataset.percentage = `${value}%`; }) .percentage { /* because we're using this property-value in two places I'm using a custom CSS property. Here we use the type() css function as the second argument to the attr() function, this allows us to tell the browser information about the value retrieved from the named attribute: */ --stop: attr(data-percentage type(<percentage>)); border: .1px solid; border-radius: 2px; font-size: 1rem; padding: 1px; background-clip: content-box; background-image: linear-gradient( to right, /* here we use the custom property within the gradient: */ #cccc var(--stop), transparent 0 ); } .percentage::before { /* here we can use the custom property and display it: */ content: attr(data-percentage); } /* the following is irrelevant, and just for demo purposes: */ main { inline-size: clamp(20ch, 80%, 1000px); margin-inline: auto; } form { margin-block-end: 1lh; label { display: grid; & .labelText { text-transform: capitalize; } & .labelText::after { content: ':'; } } } <main> <form action="#"> <fieldset> <label ><span class="labelText">adjust percentage</span ><input type="range" min="0" max="100" step="1" value="50" /></label> </fieldset> </form> <div class="percentage" data-percentage="30%"></div> </main>

JS Fiddle demo.

References:

attr(). type().

David Thomas's user avatar

You can but only in limited browsers as of the time of writing (1/26) with the advanced attr() function. (CSS Units Level 5)

Chrome/Edge

.percentage { width: 100px; height: 50px; border: .1px solid; border-radius: 2px; font-size: 1rem; margin-bottom: 1em; padding: 1px; background-clip: content-box; background-image: linear-gradient( to right, #f00 attr(data-percentage %), transparent 0% ); } <div class="percentage" data-percentage="50"></div> <div class="percentage" data-percentage="75"></div>

Chrome blog with details

MDN Reference

Paulie_D's user avatar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.