5

The New CSS Math: round()

 1 year ago
source link: https://danielcwilson.com/posts/mathematicss-round/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

The New CSS Math: round()

Aug 17, 2023

CSS added many new Math functions to supplement the old favorites (think calc() and the more recent clamp()). They all ultimately represent a numeric value, but the nuance in how they work is not always clear from the start. This series aims to look at each function with common use cases... and the less common as well.

The basics of CSS round() #

In JavaScript we have Math.round() which takes one numeric parameter, and the result will be the nearest integer. So 1.4 rounds down to 1 because it is closer to 1 than 2. Similarly, 3.9 rounds up to 4 since that is the nearest integer.

console.log(Math.round(2.2)); // 2
console.log(Math.round(14.82)); // 15
console.log(Math.round(5.5)); // 6

With CSS, round() behaves similarly by default, except it takes two parameters. The first is the value you want to round, and the second is the precision number.

When you are thinking general math or JavaScript, the precision number would be 1 because we are always looking at integers, and we are expecting our answer to be a multiple of 1. For CSS to have the straight equivalent of JavaScript’s Math.round(), we’d say round(3.9, 1).

line-height: round(2.2, 1); /* 2 */
line-height: round(14.82, 1); /* 15 */
line-height: round(5.5, 1); /* 6 */

But... why do I need two parameters?

Since we are working with a variety of CSS units with various scales, the specification allows us to work in a manner that is most appropriate for our need.

Keeping it unitless for a bit longer, think about opacity. Its reasonable range is from 0 to 1. Rounding here to an integer would always lead to a zero or one. This may be what you want, but maybe you want it with a different interval like the tenths place, such that your opacity is always one of 11 values: 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. CSS rounding allows this, and you can specify it with precision of 0.1. So instead of counting up by one, you count up by one tenth.

opacity: round(.56, 0.1); /* 0.6 */
opacity: round(.54, 0.1); /* 0.5 */

We follow the same logic when considering units. Perhaps I want to always rotate an object at intervals of 45 degrees. I can set 45deg as my precision unit to make sure my rotation is always a multiple of 45 degrees.

rotate: round(20deg, 45deg); /* 0deg */
rotate: round(30deg, 45deg); /* 45deg */
rotate: round(80deg, 45deg); /* 90deg */

You can even mix units if they are of the same syntax. Other angle options exist beyond deg such as turn and rad, so we can use any of these in our function.

rotate: round(20deg, .125turn); /* 0deg */
rotate: round(80deg, .125turn); /* 90deg */

But what if I really want more than two parameters? #

CSS round() takes a third (optional) parameter at the start which allows you to specify a rounding strategy. The earlier examples are all using the default value of nearest. If you want this strategy, you can either leave out the strategy parameter or specify nearest explicitly.

/* the following two both use the nearest strategy */
rotate: round(22.8deg, 1deg); /* 23deg */
rotate: round(nearest, 22.8deg, 1deg); /* 23deg */

If we instead want to always round up, we add a starting parameter to specify our rounding strategy as up. This will be similar to JavaScript’s Math.ceil().

font-size: round(up, 20.01rem, 1rem); /* 21rem */
rotate: round(up, 83deg, 5deg); /* 85deg */
rotate: round(up, -83deg, 5deg); /* -80deg */

Similary, we can round down by specifying round(down, ...), just as JavaScript allows with Math.floor().

font-size: round(down, 20.999rem, 1rem); /* 20rem */
rotate: round(down, 83deg, 5deg); /* 80deg */
rotate: round(down, -83deg, 5deg); /* -85deg */

Finally, there is the round(to-zero, ...) strategy. This one behaves similar to down when working with positive numbers, but behaves as up for negative numbers. It will select the interval number that is closest to zero.

rotate: round(to-zero, 83deg, 5deg); /* 80deg */
rotate: round(to-zero, -83deg, 5deg); /* -80deg */

rotate: round(down, 83deg, 5deg); /* 80deg */
rotate: round(down, -83deg, 5deg); /* 85deg */
rotate: round(up, -83deg, 5deg); /* 80deg */

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK