Advertisement
  1. Web Design
  2. CSS
Webdesign

Getting Started With CSS Math Functions Level 4

by
Length:LongLanguages:

Functional notations are part of the CSS Values and Units Module, which is also the home to useful math functions such as calc(), and as of level 4 min() and max(). These powerful functions open up incredible doorways for CSS authors that require math logic abilities within CSS. In this article we’ll discuss calc(), min() and max() and how all three can be useful in your work right now. Let’s get started!

What the Heck Are Functional Notations?

Functional Notations is one of nine parent sections (section eight to be exact) of the W3C CSS Values and Units Module. As of Level 4 Editor's Draft, Functional Notations now harbors further subsections such as toggle() that allows toggling between values, and attribute references through the use of attr(). There’s also another interesting subsection called “Mathematical Expressions” which encompasses our friendly math functions calc()min() and max()

Let’s turn to the W3C definition to help us understand what Functional Notations are:

“A functional notation is a type of component value that can represent more complex types or invoke special processing. The syntax starts with the name of the function immediately followed by a left parenthesis, followed by the argument(s) to the notation followed by a right parenthesis.”

In layperson’s terms they’re saying it’s a “function name”, such as calc, followed by opening ( and closing ) parentheses. But what goes between them?

Introducing Mathematical Expressions

As mentioned, “Mathematical Expressions” is a subsection of “Functional Notations”, but what are they and what do they do? Again, let’s turn to the W3C, where they’re defined as:

“The math functions, calc()min(), and max(), allow mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) to be used as component values.”

That means calc(), min() and max() are “math functions” that allow “expressions” within parentheses in order to “calculate values”. Okay, that’s clear now. The term “expressions” is just a fancy way of saying “math logic is totally allowed within the parentheses”.

Introduced in level 4 is a newly updated definition to complement what we know thus far:

“Components of a math function can be literal values, other math functions, or other expressions, such as attr(), that evaluate to a valid argument type (like <length>).” 

To further clarify, the “other math functions” referenced here are calc()min() and max(), but they also state these functions can be nested inside one another. You could write calc(min())min(calc())calc(max(min()))calc(min(attr())) and so on. However, my suggestion is to do your best and avoid the nesting vortex, even with the ability to do so as the spec suggests.

Now let’s say “hello” once again to a couple of outstanding math functions which nearly lost their chance to shake hands with the CSS Working Group.

Welcome Back min() and max()

The functions min() and max() are two math functions making their mark, but only after they were nearly removed from the Values and Units Level 4 Editor's Draft. Thanks to Lea Verou, the winds of change forced their way in and I couldn't be happier.

“Perhaps now that Values 3 has gone to CR it's time to reconsider adding min() and max() back into Values 4?

Authors are doing extremely weird hacks with calc() to emulate them in font-size and line-height, which they call "CSS locks". If you google CSS locks you will see how widespread these hacks are becoming, indicating a clear author need.

Furthermore, as CSS variables become more widely used, the need for min() and max() will become even greater. I recall some of the issues that made us drop them 6 years ago can now be solved with the invalid at computed value time concept that Variables introduced.” – Lea Verou

Since Lea’s suggestion on GitHub, min() and max() have officially been inserted back into the Editor's Draft of CSS level 4 Values and Units including an early adoption by WebKit. Developers can personally experiment and explore using WebKit Nightly (as of 10/24/17). Here’s the single WebKit commit for the strangely curious where support was magically granted for min() and max().

A Cursory Glance at clamp()

Another intriguing piece of gossip in that very same GitHub thread started by Lea Verou was the comment where Tab Atkins suggests an actual clamp() function. clamp() would literally “clamp” a value between boundary values.

“…I do agree that clamp(), while technically superfluous, is useful often enough that it probably deserves to exist.”

Oh my! This would be quite the addition to mathematical expressions. A function such as clamp() is a definite win for the responsive needs of today and would certainly be a welcomed friend to the language.

Current discussions revolve around this type of syntax above and I happen to be one that agrees with the suggestion; it makes sense and reads in a logical manner. I just wonder what will happen to the usage of min() and max() if clamp() actually makes an appearance in the future.

With our water cooler chatter out of the way lets focus on the actual math functions we came here to discuss; calc(), min() and max().

Now Meet calc()

This is one of my favorite math functions to grace CSS and can do all sorts of wizardry. The syntax isn’t too rough either, once you get the hang of it, and support is stellar.

In this sample above we have the function name (calc) followed by our parentheses that contain “expressions”, or in other words…math logic.

“The calc() function allows mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) to be used as component values.” – W3C

Again, this is fancy speak for saying “you can do math in the parentheses”.

With regards to expressions, authors can pass generic values such as 50%, 2em, 40, and can use calc() wherever <length><frequency><angle><time><percentage><number>, or <integer> values are allowed. My favorite units to use and examine in the wild are viewport units (vh,vwvminvmax). These are the screen dimension values that are especially handy with typography and layout as we’re about to see.

calc() In the Wild

The example above is just one way to handle responsive typography. Using a combination of media queries, Sass, calc() and viewport units, Mike proves to us how responsive typography can scale perfectly between specific pixel values.

Here’s another jaw dropping typography demo using calc() and viewport units by Tim Brown. This demo was used for his article discussing CSS Locks that I encourage you to read if typography is something you care about.

Viewport units and calc() can also help to create some of our most favorite layout patterns. In the demo above, calc() is used to subtract the height of the footer from the height of the viewport (vh). A clever solution by Chris Coyier for our old friend “The Sticky Footer” so often requested. This demo also works great when combined with CSS variables as well.

There are certainly other cases when it comes to applications and dynamic states in this demo by David Khourshid. David uses calc() for backgrounds, offset values, transforms, filters, opacity and even width. This is also a great demo for those looking to dive into React along with CSS variables.

Now let’s take a look at two additional math functions you’ll certainly enjoy, currently known as min() and max().

min() and max(): Defining Constraints

As mentioned prior, these functions are still in their infancy, so demos showcasing use cases is bleak, but don’t let that scare you from experimenting. In order to investigate min() and max() you’ll need to download WebKit nightly. Once downloaded, you’re free to open up Nightly (black icon) and get to work.

Remember when we learned what expressions were? It was just a fancy way of saying “math logic”. For example:

Each expression is comma separated with an additional expression that follows. We can also turn to the spec that explicitly states this same rule:

“The computed value of a min() or max() function is the comma-separated list of expressions” – W3C

In case you missed that very important part of the explanation, the spec just stated a comma-separated list of expressions just like we did in the code snippet earlier.

“a min() or max() function represents the smallest (most negative) or largest (most positive), respectively, comma-separated calculation it contains.” – W3C

Did you catch all that? They just said smallest (most negative) or largest (most positive). The W3C just gave us permission to write negative numbers as part of our expressions.

Let’s take this time now to see how min() and max() prove themselves in a working demo; hold on to your hats.

min() and max() In Real Life

Here’s a demo that showcases a couple of use cases for min() and max() using a components width and font-size. The width has a minimum constraint and a maximum constraint while our component’s font-size is also clamped with a minimum and maximum value. Remember this will only work in WebKit Nightly as of this writing; if you’d like to see an animation of it in action take a look at this GIF (frankly too heavy to be embedded into the page).

In the example above I’m starting things off by constraining the width and doing so in one line.

Using the approach above I’m able to include a middle constraint vs. just a minimum and maximum. This line of code tells the browser “Try to set the width to 70vw, but don’t let it go any lower than 200px (100px * 2), or higher than 500px.” There is also another road you can go down to achieve a similar result.

To explain in more detail this equates to a minimum, a middle and finally a maximum constraint value. Nesting max() within min() helps clamp between the desired constraints.

If we used min-width and max-width we’d arrive at an equivalent destination we were achieving by way of min() and max(). I’m curious if properties such as min-width will become obsolete in favor of math functions like min() and max() in the coming years.

In regards to font-size I use the same min/max approach to create responsive and locking typography.

I’m telling the browser “Try to set the font-size to 4vw, but don’t let it go any lower than 1rem, or higher than 2rem.” Unfortunately there is no equivalent such as min-font-size and max-font-size like we had for width, but as of the CSS Fonts Module Level 4 spec that could become a reality.

This is certainly exciting news and authors are just as excited when it comes to constraining values in CSS.

Just Search “CSS Locks”

If you use a search engine to hunt down CSS Locks you’ll find heaps of articles and demos. CodePen also displays a variety of pens under another CSS Locks search. For those that are new to the idea of CSS Locks let me explain in more detail.

The locking technique allows the ability to transition smoothly between two values, depending on the current viewport size. Tim Brown dubbed it as ”CSS Locks” in his article “Flexible typography with CSS locks” however this technique was first introduced by Mike Riethmuller in his article “Precise control over responsive typography.” 

This can be useful when using calc() and viewport units for headings and body copy that scale up or down depending on the dimensions of the screen. This type of constraining is what we’ve come to know as “CSS Locks”.

There are many articles regarding CSS Locks, so here are some of my favorite ones to read over in your personal time.

Locking With EQCSS

In the demo above by Tommy Hodgins, EQCSS is used in order to clamp font-size with JavaScript at the helm, while CSS is in the back seat. I’ll let you decide for yourselves how you feel about JavaScript mixing itself with CSS.

Locking With CSS Variables and JavaScript

I’ve written a JavaScript helper that uses CSS Variables along with the help of JavaScript to “lock” the font size of headings, body copy and line height as the screen dimensions vary on resize and page load events without the use of media queries.

These properties targeted “lock” at the values defined, but this isn’t something that comes without caveats. When it comes to development there are some pros and cons to every approach. Due to the events that take place, and the CSS properties altered, you’ll most likely encounter painting and layout on resize so it’s best to use sparingly, or in other words; don’t use it for everything on your page.

Here are a few bits of wisdom when it comes to JS styling.

  1. Any time you’re using JavaScript to help apply styles it will be slower than CSS alone. Do everything in CSS that can be done in CSS.
  2. When using JavaScript to apply styles, performance is determined by how complex the tests are to perform and how many elements on the page need to be tested. Try to write your styles in a way that limits the number of JS-powered tests being performed to determine what styles to apply and try to limit the number of elements in your HTML being probed or tested by a JS-powered stylesheet.
  3. Understand what events trigger recalculations of the styles. You want styles to stay current with things happening in the browser, but you also want to limit the number of event listeners running at any given time. This is where it’s really important that you limit the number of elements these tests are applying to. If you’re using a UI library there might be events and callbacks built right in to your framework that you’d want to trigger recalculations in your JS-powered styles. Be aware of what event listeners will be present in your browser on the page where the JS-powered styles you’re writing will be running and try to find ways to limit the number of event listeners needed; limit the number of elements you’re listening to, hook similar listeners into global events, use framework-specific events for tighter integration, and consider using new browser APIs like Resize Observer and Mutation Observer if they can help for your needs.

Conclusion

Now that you’ve had a taste of CSS math functions I hope they inspire you, or convince you to start using stable properties and experiment with the bleeding edge ones. If you’re using calc() or have experimented with min() and max() please let us know in the comments. Happy coding!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.