Intro
You might need used the attr()
perform in CSS earlier than to get the textual content content material for a pseudo-element.
<p data-title="This textual content is earlier than the title">Hiya World</p>
.title:earlier than {
content material: attr(data-title);
}
The result’s as follows:
There’s nothing new or groundbreaking right here, it’s helpful for some circumstances.
Nevertheless, once we need to use a price apart from textual content, it won’t work. Within the following HTML, I added data-color
attribute to the p
ingredient.
<p data-color="purple">CSS is superior</p>
After which used the attribute in CSS.
.title:earlier than {
coloration: attr(data-color);
}
It’s not working as a result of the attr()
perform solely helps textual content values.
Fashionable attr()
attr()
Restricted availability
Supported in Chrome: no.
Supported in Edge: no.
Supported in Firefox: no.
Supported in Safari: no.
Restricted availability
Supported in Chrome: no.
Supported in Edge: no.
Supported in Firefox: no.
Supported in Safari: no.
This function shouldn’t be Baseline as a result of it doesn’t work in among the most widely-used browsers.
Now, we are able to use attr()
and outline the kind of worth we need to use.
For instance, on this case, we have to get the colour worth.
<p data-color="purple">CSS is superior</p>
.title:earlier than {
coloration: attr(data-color sort(<coloration>));
}
In line with MDN, the brand new information sort can take completely different worth sorts:
The
sort()
perform takes a<syntax>
as its argument that specifies what information sort to parse the worth into. The<syntax>
might be<angle>
,<coloration>
,<custom-ident>
,<picture>
,<integer>
,<size>
,<length-percentage>
,<quantity>
,<share>
,<decision>
,<string>
,<time>
,<transform-function>
, or a mixture thereof.
That offers us a whole lot of new flexibility that we didn’t have earlier than. The place that is perhaps helpful? That’s what I’ll discover on this article.
Characteristic detection
We are able to test for the fashionable attr() help with CSS @helps
. Right here is an instance:
@helps (x: attr(x sort(*))) {
}
In case you are utilizing Sass, the above received’t be parsed. I escaped it to make it work in .scss
recordsdata:
@helps (#{"x: attr(x sort(*))"}) {
}
Use circumstances for the fashionable attr()
Assign column numbers
When utilizing a CSS grid, we are able to assign column numbers to every baby of the grid.
On this instance, I outlined data-col-start
and data-col-end
on a grid merchandise to set the beginning and finish of the column.
In CSS, I can retrieve the numbers like so:
.format {
> * {
grid-column-start: attr(data-col-start sort(<quantity>), 2);
grid-column-end: attr(data-col-end sort(<quantity>), 3);
}
}
If the attribute isn’t set, it is going to fall again to 2
and 3
as I specified. Play with the next demo and see the way it works:
<div data-col-start="1" data-col-end="-1">
<img src="desk.jpg" alt="" />
</div>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quam deleniti officia aut nulla vero cumqu.
Veritatis, tempore itaque accusamus alias voluptate illum cupiditate eius incidunt et laudantium?
If the attributes aren’t set, the grid-column-start
and grid-column-end
will default to the fallback values.
See the next demo:
<div data-col-start="1" data-col-end="-1">
<img src="desk.jpg" alt="" />
</div>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quam deleniti officia aut nulla vero cumqu.
Veritatis, tempore itaque accusamus alias voluptate illum cupiditate eius incidunt et laudantium?
Entry textarea rows
We are able to use the rows
attribute and multiply it by a threshold quantity.
textarea {
min-height: calc(attr(rows sort(<quantity>)) * 50px);
}
Try the demo under:
<textarea rows="3"></textarea>
Write a short description about your product concept:
Animation delay
One other nice utilization of contemporary attr() is to delay an animation. Since attr()
works with the <time>
sort, we are able to take this to our benefit.
Within the following HTML, we’ve got a listing of things. Every merchandise has a data-delay
attribute. We are able to take this and use it in CSS.
<div class="itemsWrapper">
<div class="merchandise" data-delay="0.3s"></div>
<div class="merchandise" data-delay="0.6s"></div>
<div class="merchandise" data-delay="0.9s"></div>
<div class="merchandise" data-delay="1.2s"></div>
</div>
To make use of the worth, we have to name the attribute after which outline its sort. If not outlined, it is going to fall again to a default delay of 0.5s
.
See the next CSS:
.merchandise {
animation-delay: attr(data-delay sort(<time>), 0.5s);
}
Right here is an interactive demo that exhibits the way it works:
<div class="itemsWrapper">
<div class="merchandise" data-delay="0.3s"></div>
<div class="merchandise" data-delay="0.6s"></div>
<div class="merchandise" data-delay="0.9s"></div>
<div class="merchandise" data-delay="1.2s"></div>
</div>
Shade tint
By having a novel quantity for every html ingredient, we are able to use it to vary the colour lightness as per its index.
On this instance, I’m utilizing the data-index
attribute to get the worth for lightness whereas utilizing CSS relative colours.
.merchandise {
background-color: oklch(
from #ab4ef8 calc(l + calc(attr(data-index sort(<quantity>)) / 20)) c h
);
}
Test the demo under:
<div class="itemsWrapper">
<div class="merchandise" data-index="1"></div>
<div class="merchandise" data-index="2"></div>
<div class="merchandise" data-index="3"></div>
<div class="merchandise" data-index="4"></div>
<div class="merchandise" data-index="5"></div>
<div class="merchandise" data-index="6"></div>
<div class="merchandise" data-index="7"></div>
</div>
In that regard, we now have sibling-index within the works! Thrilling instances.
Grid hole
I used attr()
to outline the worth of grid-gap
. What’s good right here is that we are able to outline a number of choices for the worth. On this case, I outlined the kinds <size>
or <share>
.
.format <share>));
Attempt to change the size values within the under demo:
<div class="format" data-gap="1rem"></div>
Grid template areas
One of many highly effective options of CSS grid is utilizing grid named areas. I thought of why not attempting to outline the grid template space with information attributes?
At first, I attempted the next:
<div
class="format"
data-areas="'featured item-1' 'featured item-2' 'item-3 item-4'"
></div>
Although it didn’t work. I believe it’s invalid CSS (Please right me if I’m flawed). To make it work, I’ve to outline every row individually as the next:
<div
class="format"
data-row-1="featured item-1"
data-row-2="featured item-2"
data-row-3="item-3 item-4"
></div>
Then, I used that in CSS like so. Discover that I didn’t outline the sort
because the default is <string>
.
.format {
grid-template-areas:
attr(data-row-1)
attr(data-row-2)
attr(data-row-3);
}
Here’s a demo that exhibits it in motion:
Featured
Merchandise 1
Merchandise 2
Merchandise 3
Merchandise 4
<div class="format"
data-row-1="featured item-1"
data-row-2="featured item-2"
data-row-3="item-3 item-4">
</div>
Background pictures
An instance of the place we are able to use attr()
is with background pictures. Often, when we’ve got a dynamic background that’s set through JavaScript, we are inclined to set background-image
on every ingredient or use a CSS variable.
We are able to set an attribute and use that in CSS. It provides the identical consequence as utilizing the inline CSS variable, nevertheless it feels cleaner to me.
<div type="--bg: linear-gradient(45deg, #9c3ce7,#3d53cc)"></div>
<div data-bg="linear-gradient(45deg, #9c3ce7,#3d53cc)"></div>
In CSS, we are able to use it like so:
.ingredient {
background: attr(data-image sort(<picture>)) no-repeat;
}
<div data-bg="linear-gradient(45deg, #9c3ce7, #3d53cc)"></div>
Progress bar
On this demo, I wished to see how the attr()
will work when utilized in a CSS variable. I outlined data-color
and data-progress
on the principle container.
<div class="bar" data-color="#a548e3" data-progress="55">
<div class="bar__current"></div>
</div>
Then, in CSS, I:
- outlined a progress variable to get the unitless worth.
- outlined a coloration variable to retailer the colour. I
.bar {
--progress: attr(data-progress sort(<quantity>));
--color: attr(data-color sort(<coloration>));
background-color: oklch(from var(--color) calc(l + 0.35) c h);
}
.bar__current {
width: calc(var(--progress) * 1%);
background-color: oklch(from var(--color) l c h);
}
It really works! Here’s a demo:
<div class="bar" data-color="#a548e3" data-progress="55"></div>
<div class="bar" data-color="#afe348" data-progress="75"></div>
<div class="bar" data-color="#e38148" data-progress="40"></div>
If we examine this to the method of utilizing an inline CSS variable, it is going to shortly grow to be tougher to learn/scan.
<div class="bar" type="--color: #a548e3; --progress: 55"></div>
<div class="bar" data-color="#a548e3" data-progress="55"></div>
A Mini CSS framework?
I had an concept in thoughts once I first began exploring attr()
and I’m glad it’s not simply me.
What if we are able to use attr()
to have a mini CSS framework or utility courses for use inside a system? Within the following snippet, I added px
which stands for the padding on the horizontal sides.
<div px="1rem"></div>
In CSS, I have to outline this solely as soon as:
[px] {
padding-inline: attr(mx sort(<size));
}
And I can apply it to many components as wanted:
<div px="1rem"></div>
<div px="10px"></div>
<div px="0"></div>
I outlined the CSS as soon as and reused the utility attribute a number of instances. Isn’t that cool? I took this additional and constructed a bit extra attributes:
Some content material in right here
Some content material in right here
<div
max-w="500px"
px="1rem"
py="1rem"
bg-color="#fff"
coloration="#222">
</div>
<div
max-w="300px"
px="2rem"
py="2rem"
bg-color="var(--brand-1)"
coloration="#fff">
</div>
Multi worth attr is beneficial
After I revealed this text, I had the understanding that we are able to’t use key phrases like auto
. Turned out, it’s doable to do that with the sort <custom-ident>
. Due to Temani Afif, I realized that it’s doable.
I want that there was a strategy to have a “key phrase” sort. For instance, If I’ve an attribute that could possibly be a size worth or an auto
, I want to permit a number of values.
[mx] <custom-ident>));
<div mx="auto"></div>
Or we are able to use a size worth:
<div mx="2rem"></div>
Additionally, we are able to use the common selector to make it settle for any worth.
[mx] {
margin-inline: attr(mx sort(*));
}
One other concept is to permit both a size sort or the auto
key phrase. Due to Bramus and Dannie Vinther
for suggesting this.
[mx] auto));
Why use trendy attr() over inline CSS?
Javascript utilization
When utilizing data-*
for an attribute title, we are able to entry it by utilizing dataset
. If we’ve got an attribute data-color
, we are able to do the next:
ingredient.dataset.coloration = "blue";
Separation of considerations
When utilizing trendy attr(), we are able to separate the content material from the styling and so making the HTML simpler to scan.
<div class="bar" type="--color: #a548e3; --progress: 55"></div>
<div class="bar" data-color="#a548e3" data-progress="55"></div>
Reduces CSS conflicts
When utilizing information attributes, it’s not doable to mess up with CSS. We are able to have an API-like strategy to type our pages. In a design system, utilizing attr() can forestall the builders from by accident overwriting types and it makes the CSS extra predictable.
Conculsion
Fashionable attr() present us with a robust method write CSS primarily based on information attributes. On the time of writing, it’s Chrome solely and I want extra browsers will observe quickly.