CSS functions
In CSS you can not only write ready numbers but also calculate them. A function is written as name(arguments) and returns a value. You have already met rgb(), repeat() and linear-gradient(). This lesson is about functions for sizes: they calculate widths, spacing and fonts right in the browser.
calc() — a calculation
calc() does arithmetic: addition, subtraction, multiplication and division. Its main strength is mixing different units that cannot be added up in your head:
<style>
.box { width: calc(100% - 80px); padding: 12px; background: lavender; }
</style>
<div class="box">Width: the whole line minus 80 pixels</div>Percentages depend on the parent, pixels are fixed — only the browser knows the result at drawing time.
min() and max()
min() picks the smallest of the values, max() the largest. The form width: min(100%, 400px) means "full width, but no more than 400 pixels":
<style>
.card { width: min(100%, 400px); padding: 12px; margin-bottom: 8px; background: honeydew; }
.side { padding: max(2vw, 12px); background: lightyellow; }
</style>
<div class="card">No wider than 400 pixels</div>
<div class="side">The padding grows with the window, but is at least 12 pixels</div>The logic seems reversed: min() sets the upper limit, max() the lower one.
clamp() — a value within bounds
clamp(minimum, preferred, maximum) takes the preferred value but does not let it out of the bounds. Most often it sets a fluid font size that grows with the window:
<style>
.title { font-size: clamp(1.25rem, 5vw, 2.5rem); margin: 0; }
</style>
<p class="title">The heading changes size smoothly</p>The vw unit is a percent of the window width. Change the width of the browser window: the heading grows and shrinks without media queries, but never gets smaller than 1.25rem or bigger than 2.5rem.
Functions and variables
Functions go well with custom properties — CSS variables. calc() multiplies a variable by a number, and one value turns into a whole scale:
<style>
.scale { --step: 8px; }
.scale div { background: lightskyblue; margin-bottom: 4px; height: 16px; }
.s1 { width: calc(var(--step) * 5); }
.s2 { width: calc(var(--step) * 10); }
.s3 { width: calc(var(--step) * 20); }
</style>
<div class="scale">
<div class="s1"></div><div class="s2"></div><div class="s3"></div>
</div>Change --step — all three bars change at once.
Cheat sheet
| Function | What it returns | Example |
|---|---|---|
calc() | The result of a calculation | calc(100% - 2rem) |
min() | The smallest value | min(100%, 600px) |
max() | The largest value | max(50%, 300px) |
clamp() | A value within bounds | clamp(16px, 2vw, 22px) |
Functions can be nested, and inside min(), max() and clamp() you can calculate without calc(): min(100% - 32px, 600px).
Common mistake
In calc() the + and - signs must be surrounded by spaces. Without them 100%-80px reads as one strange word, and the browser throws the whole rule away:
<style>
.box { padding: 12px; margin-bottom: 8px; background: mistyrose; }
.bad { width: calc(100%-80px); }
.good { width: calc(100% - 80px); }
</style>
<div class="box bad">No spaces: the rule did not work</div>
<div class="box good">With spaces: 80px narrower</div>For * and / spaces are not required, but they make reading easier.