blog post

The Complete Guide to Building Responsive UI with CSS calc

Introduction

Responsive design ensures that web content looks good and functions well, no matter the screen size. Such design is a must-have in modern web applications.

In today's post we will learn how to dynamically calculate values for various CSS properties, enhancing the responsiveness and flexibility of your web designs.

What is the calc() CSS Function

The calc() function in CSS allows developers to perform calculations to determine CSS property values. It can perform basic mathematical operations: addition (+), subtraction (-), multiplication (*), and division (/).

Its syntax is straightforward:

css
element { property: calc(expression); }

Here, expression parameter represents a calculation and its result is used for a CSS property value. Expression can be used with number, integer, percentage, length, frequency, angle, or time values.

In most cases unit like pixels (px), percentages (%), viewport units (vw, vh), em, rem are used in expressions. Expression inside calc() function can use a mix of any of these units, for example:

css
.content { width: calc(100% - 100px); height: calc(100vh - 100px); font-size: calc(2vw + 5px); margin: calc(2rem + 10px); }

Let's explore a realistic use case where we create a main content that takes all of screen's height except the header size:

html
<style> body { font-size: clamp(1.5rem, 2vw, 2rem); text-align: center; margin: 0; padding: 0; } header { width: 100%; height: 4rem; background-color: darkseagreen; } main { width: 100%; height: calc(100vh - 4rem); background-color: #d1d5db; } </style> <body> <header>Header here</header> <main>Content here</main> </body>

Using calc() function to calculate a part of a CSS property

The calc() function can be used to calculate a result for a part of the CSS property. For example you can create a flexible background position:

css
.content { background-position: calc(100% - 500px) center; }

This style adds a margin for background image horizontally while keeping it centered vertically.

The same way you can dynamically calculate parts of margin or padding:

css
.content { margin: 20px calc(2rem + 10px); padding: 10px calc(2rem + 10px) 10px calc(1rem + 5px); }

Using calc() inside other functions

A very cool feature of calc() function is that it can be nested within other functions for more complex calculations. We can use calc() inside a clamp() function to create a responsive font size for different screen sizes:

css
body { font-size: clamp(16px, calc(1vw + 1em), 24px); }

In this example, clamp() is used to ensure the font size never goes below 16px or above 24px. The middle value uses calc() to add 1em to 1vw, offering a flexible scaling effect on different screen sizes.

clamp() used together with calc() allows to create a really complex calculations for a more responsive design.

Interesting fact: calc() can be nested inside another calc() function.

Using calc() to perform math calculations

A calc() function can be used as a more elegant way to express math calculations:

css
.content { width: calc(100% / 9); }

This is much more readable than expressing the width like: 11,11111111111111%;

Using calc() CSS Function for Custom Properties

Custom CSS properties, also called CSS variables, are a powerful tool for building web designs. Great news, that we can use calc() function for custom properties.

Typically custom CSS properties are declared at the root level for global accessibility but can be scoped to individual selectors as needed. They are defined as follows:

css
:root { --main-color: #374151; --padding: 16px; }

These properties can then be reused throughout the stylesheet. For example, we can define a color as a variable in one place and reuse it in different CSS styles throughout different pages.

We can use calc() function for custom CSS properties:

css
:root { --base-font-size: 18px; } .content { font-size: calc(var(--base-font-size) + 1vw); }

Here we define a property with base font-size and adjust it based on the viewport width. To access a CSS variable's name - the var function is used, that accepts a single parameter - name of the variable.

Limitations When Using calc() CSS Function

The Importance of Whitespaces

One of the most common pitfalls when using calc() is the handling of whitespace around operators. In calc() expressions, the addition (+) and subtraction (-) operators must be surrounded by whitespace to be recognized as operators. Without proper whitespaces, these operators could be interpreted as part of a number (e.g., positive or negative numbers) and result in a syntax error.

Correct Whitespace Usage:

css
.content { width: calc(100% - 50px); }

Incorrect Whitespace Usage:

css
.content { width: calc(100%-50px); }

Also a negative number can be used for numbers in the expression:

css
.content { width: calc(100% - -50px); }

For the multiplication (*), and division (/) operators it is not necessary to use whitespaces. But it is considered a good practice to include whitespace around all arithmetic operators to improve code readability.

Addition (+) and Subtraction (-) Requirements

Both addition (+) and subtraction (-) operators require all numbers in the expression to have CSS units (px, vw, vh, %, em, rem, etc) specified.

Correct usage:

css
.content { width: calc(100% - 50px); font-size: calc(2vw + 5px); margin: calc(2rem + 10px); }

Incorrect usage:

css
.content { width: calc(100% - 5); font-size: calc(2vw + 10); margin: calc(2rem + 10px + 5); }

Multiplication (*) and Division (/) Requirements

Multiplication (*) operator requires one of the numbers in the expression to be unitless. Division (/) operator requires the second number in the expression to be unitless.

Correct usage:

css
.content { font-size: calc(1.5 * 16px); width: calc(100% / 9); }

Incorrect usage:

css
.content { font-size: calc(1.5% * 16px); width: calc(100% / 9px); height: calc(100 / 9px); }

Usage in Media Queries

Unfortunately, calc() CSS functions can't be used in media queries, for example:

css
@media (min-width: calc(500px + 10vw)) { /* This will not work */ }

Summary

calc() CSS function allows to perform calculations to determine CSS property values. It supports basic arithmetic operations: addition, subtraction, multiplication, and division - across different CSS units, such as pixels, percentages, viewport dimensions, em, rem, etc.

This function really helps in creating flexible responsive designs by dynamically adjusting needed properties.

Despite its power, it's essential to use calc with an understanding of its limitations:

  • mandatory whitespace around arithmetic operators
  • nuances with CSS units and unitless numbers for different arithmetic operators
  • calc can't be used in media queries

This feature is highly supported by all modern web browsers:

Hope you find this blog post useful. Happy coding!

Improve Your .NET and Architecture Skills

Join my community of 1800+ developers and architects.

Each week you will get 2 practical tips with best practises and architecture advice.