Skip to content

The Case for Math

Modern CSS Solutions

I love math. I was that proud nerd on the Math Team in high school. Competing in state meets was the most thrilling thing back then. Those days are long gone, I am no longer doing any competitive math, but I still apply my math skills on a daily basis. Math makes coding CSS fun. I am able to think more creatively and write less code most of the time. Let’s look at some common use cases using calc().

Responsive Text

There are many ways to set responsive and fluid typography nowadays, some are extremely complex and might use lots of media queries. For me, I love to keep things simple, just add a tiny bit of viewport size!

Math!


  html {
  font-size: clamp(110%, calc(100% + 0.5vw), 200%);
}

The viewport size would make sure the text is always scaling with the screen size. By keeping the viewport size small in the formula, the text would scale up a lot better in larger screens while it doesn’t scale down too much in smaller screens.

Sizing System

Sizing options are fundamental in a lot of UI elements (e.g. buttons, icons, grid gutters), and having a system can introduce consistency throughout all the elements you design. You may have something like this in your code:


  --size-xsmall: 0.25rem;
--size-small: 0.5rem;
--size-medium: 1rem;
--size-large: 2rem;
--size-xlarge: 4rem;

Instead of writing out each value manually, why not set up some simple formulas using medium as the base?

Math!


  --size-xsmall: calc(var(--size-medium) * 0.25);
--size-small: calc(var(--size-medium) * 0.5);
--size-medium: 1rem;
--size-large: calc(var(--size-medium) * 2);
--size-xlarge: calc(var(--size-medium) * 4);

This is great if you want to easily scale things proportionally such as having a density toggle switch in your app or website (like the feature in Gmail which the user can switch between default, compact, and comfortable). Instead of redefining the entire system for each density, all you have to do is redefine the base, and everything else will update accordingly.

Content Max-width

If you have been writing CSS for a while, you probably noticed that many frameworks have a wrapper utility. Its purpose is to limit the content to a specific max-width and horizontally center it on the page. The CSS usually looks like this:


  .wrapper {
  max-width: 75ch;
  margin: 0 auto;
  padding: 0 10vw;
}

The max-width constrains the content, the margin centers it, and the padding creates a little bit of white space once the viewport is below the max-width. This method is perfectly fine, however, it does create bloat in the markup when you want to have full bleed regions with background color:


  <body>
  <header class="black-bg">
    <div class="wrapper">...</div>
  </header>
  <main class="white-bg">
    <div class="wrapper">...</div>
  </main>
  <footer class="black-bg">
    <div class="wrapper">...</div>
  </footer>
</body>

Why not use a little bit of math and reduce the code to just padding rules?

Math!


  header, main, footer {
  padding-inline: calc((100vw - min(80vw, 75ch)) / 2);
}

This achieves exactly the same goal but you no longer need to use an extra element. You can take this even further by setting up a var() for the formula so you can use the padding on any top level layout element as needed.

Math + CSS = Awesome

There are many other useful use cases. Explore and try for yourself.