CSS math isn’t nearly how issues look! It may also be used to work out helpful numeric info. As an illustration, you possibly can calculate and present the share of duties accomplished in a to-do checklist with CSS, serving to customers preserve observe of their progress. No want for script or server computation. No latency. No use of further browser assets.
Working with math has develop into a lot less complicated and extra versatile. I’m going to present you an instance utilizing CSS to calculate and show a reduced worth everytime you want it, utilizing the bottom worth and {discount} offered. It’s the type of factor you see typically on e-commerce websites the place heavy JavaScript is used to point out a product’s full worth, its {discount} quantity, and its sale worth.
We will completely do this in CSS:
It does depend on some bleeding-edge options which can be ready to achieve extra browser help, however I believe it’s nonetheless a very good train to dig into how we’ll finally have the ability to put these items in apply and finally use them in our on a regular basis work.
Right here’s how I put it collectively.
The preliminary markup
The interface on this particular demo shows an inventory of streaming providers for the person to select from — Netflix, Disney+, HBO, HBO Now, HBO Go, HBO Max, and so forth. There’s a pupil {discount} provide on every subscription that takes a sure proportion quantity off the total worth.
The bottom worth and {discount} are included as data-* attributes within the component displaying the value. Simply keep in mind, the {discount} solely kicks in when you choose “Apply Scholar Low cost,” and you then’ll see how a lot the value is after the {discount} is utilized.
Calculating the value lower
When the {discount} kicks in, step one is to slash the bottom worth with a line throughout it.
/* When the {discount} toggle is checked contained in the .ott container */
.ott:has(.is-ott-discounted:checked) {
/* Strike by means of the unique worth */
.ott-price {
text-decoration: line-through;
}
}
Subsequent, let’s work out the brand new discounted worth utilizing the data-price and data-discount values.
.ott:has(.is-ott-discounted:checked) {
.ott-price {
text-decoration: line-through;
/*
Calculate the brand new worth from the data-* attributes:
Unique Worth * (1 - Low cost Utilized)
*/
--n: calc(attr(data-price quantity) * (1 - attr(data-discount quantity)));
}
}
The attr( syntax is comparatively new. The perform used to solely work with the content material property, however now helps any CSS property… and parses values into a spread of information sorts, whereas earlier than they had been all the time parsed as strings.
These arguments:
: That is the identify of the HTML attribute we need to have a look at (likehref,data-count, ortitle).: This tells CSS easy methods to “learn” the worth (like acolour, aquantity, or asize). It’s the newer superpower that makes the work we’re doing right here potential.
In our case, we’re utilizing the perform to parse each data-price and data-discount into numbers, after which we subtract the {discount} from the value with CSS math-iness.
The upgraded attr() is tremendous cool, however not Baseline as I’m scripting this, so keep watch over it.
Displaying the discounted worth
Right here’s how we show the up to date worth as soon as the {discount} is utilized:
.ott:has(.is-ott-discounted:checked) {
.ott-price {
text-decoration: line-through;
--n: calc(attr(data-price quantity) * (1 - attr(data-discount quantity)));
&::after {
show: inline-block;
/* Splits the variable --n into two counters:
'a' for the entire quantity (in {dollars}) and 'b' for the decimals (in cents) */
counter-set: a calc(spherical(down, var(--n))) b calc((mod(var(--n), 1)) * 100);
/* Output: two areas (2000), a greenback signal ($), the quantity, a dot, and the decimals */
content material: "20002000$" counter(a) "." counter(b, decimal-leading-zero);
}
}
}
The counter() perform helps us flip the numeric worth of the --n varable right into a content material string. Since CSS counters can’t deal with decimals (they spherical the worth by default), we deal with the numbers earlier than and after the decimal as separate counters after which mix them as strings, including a dot between them.
calc(spherical(down, var(--n)))takes the variable--nand rounds it all the way down to get the entire greenback quantity (saved ascounter(a)).calc((mod(var(--n), 1)) * 100)makes use of the modulomod()perform to isolate the fraction, then multiplies it by100to get the cents (saved ascounter(b)).- The
content materialproperty inserts a greenback signal earlier than the 2 counters after which joins them with a dot.
We all know that calc() has loads of browser help. And guess what? The mod() perform is newly Baseline!
That’s provided that you want decimals and all that. In case you’re rounding costs, this could be a lot sufficient:
counter-set: worth calc(var(--n));
content material: counter(worth);
Right here’s the demo as soon as once more:
Wrapping up
So, there we’ve it, a working mixture of newer CSS options (the upgraded attr() perform), CSS math features (mod(), spherical()), and customized counters to nail down one thing that we see in so many web sites, solely with out scripts. When attr()‘s help for information sorts turns into a factor in all browsers, that is one thing you should utilize in your on a regular basis work.
