Ce que fait calc()
calc() fait de l'arithmétique dans une valeur CSS, et il peut mélanger des unités qui ne prennent une taille qu'au moment de la mise en page. Le cas classique est « toute la largeur moins une barre latérale fixe » :
100% n'est connu qu'une fois la page mise en page, et 180px est fixe : aucune unité seule ne pourrait l'exprimer. calc() fait le calcul : dans un aperçu de 800px de large, la rangée fait 784px et la colonne principale reçoit 604px, et la ligne sous la mise en page affiche les vrais nombres. Aujourd'hui, flexbox ou grid feraient cette mise en page sans calcul, mais la même soustraction revient partout : une hauteur moins un en-tête, une largeur moins un espace.
Les règles de syntaxe
width: calc(100% - 2rem); /* + and - need spaces on both sides */
width: calc(100% / 3); /* divide by a plain number */
margin: calc(var(--space) * 2); /* multiply by a plain number */
height: calc(100vh - (64px + 1rem)); /* parentheses group */
| Règle | Valide | Invalide |
|---|---|---|
Des espaces autour de + et - | calc(100% - 20px) | calc(100%-20px) |
* : au moins un côté est un nombre simple | calc(2 * 1rem) | calc(2px * 3px) |
/ : diviser une longueur par un nombre simple | calc(100% / 3) | width: calc(300px / 3px) (pas une longueur) |
| Les unités doivent être compatibles | calc(1rem + 10px) | calc(1rem + 2s) |
La règle des espaces existe parce que 100% -20px se lirait comme deux valeurs séparées, la seconde étant un nombre négatif. Quand un calc() est invalide, toute la déclaration est jetée et l'élément garde la valeur qu'il avait grâce aux règles précédentes.
Essayez une expression
Tapez n'importe quelle expression pour la largeur de la boîte. Le navigateur indique si elle est valide et la largeur obtenue :
Essayez 100%-200px (invalide, pas d'espaces), 100% / 3, 50% + 4rem, 2 * 120px, 200px * 2px (invalide) et (100% - 40px) / 2.
calc() avec des variables CSS
Les variables et calc() vont ensemble : stockez une valeur de base une fois et dérivez-en le reste. Une variable sans unité devient une longueur quand vous la multipliez par une unité :
Passez --space à 12px ou --cols à 4 et toutes les valeurs dérivées suivent. La page des variables CSS explique comment les déclarer et définir leur portée.
Usages courants
| Besoin | calc() |
|---|---|
| Remplir l'espace à côté d'un élément fixe | width: calc(100% - 240px) |
| Section sous un en-tête fixe | min-height: calc(100vh - 64px) |
| La moitié de la largeur moins la moitié d'un espace | width: calc(50% - 8px) |
| Centrer une boîte de 100px positionnée en absolu | left: calc(50% - 50px) |
| Une taille de police qui grandit un peu avec l'écran | font-size: calc(1rem + 0.5vw) |
| Transformer une variable numérique en longueur | calc(var(--n) * 1px) |
| L'opposé d'une variable | calc(var(--space) * -1) |
Pour une valeur qui doit rester entre des limites, utilisez clamp(), qui accepte les mêmes calculs dans ses arguments sans écrire calc().
Où calc() fonctionne
Partout où une longueur, un pourcentage, un nombre, un angle ou une durée est autorisé : width, margin, padding, top, font-size, line-height, tailles des pistes de grille, transition-delay, et angles dans transform. Il peut être imbriqué, et un calc() imbriqué équivaut à de simples parenthèses.
Les angles en sont un bon exemple. Chaque graduation ci-dessous a sa propre --i (de 0 à 11), et une seule règle la transforme en angle avec calc(var(--i) * 30deg) :
La graduation 3 reçoit rotate(90deg), que Chrome indique sous forme de matrice matrix(0, 1, -1, 0, 0, 0) : un quart de tour. left: calc(50% - 2px) centre chaque graduation en soustrayant la moitié de sa propre largeur de 4px.
Erreurs courantes
- Pas d'espaces autour de
-ou+.calc(100%-20px)est invalide et ignoré. - Multiplier deux longueurs.
calc(10px * 2px)n'a pas de sens en CSS. Un côté de*doit être un nombre simple. - Utiliser calc() pour une hauteur en pourcentage sans hauteur sur le parent.
calc(100% - 20px)pourheightdemande un parent avec une hauteur définie, commeheight: 100%. - Utiliser calc() là où flexbox ou grid suffiraient.
width: calc(33.333% - 10px)pour des colonnes est fragile ;display: grid; grid-template-columns: repeat(3, 1fr); gap: 15pxn'a besoin d'aucun calcul. - Attendre un message d'erreur. Le navigateur ne signale pas un calc() invalide. Inspectez l'élément dans les outils de développement : une déclaration invalide y apparaît barrée.
Questions fréquentes
Que fait calc() en CSS ?
Il calcule une valeur à partir d'une expression avec +, -, * et /, et il peut mélanger des unités que le navigateur ne connaît qu'au moment de la mise en page. width: calc(100% - 200px) vaut toute la largeur du parent moins 200px, quelle que soit la largeur du parent.
Pourquoi mon calc() ne fonctionne-t-il pas ?
La cause la plus fréquente est l'absence d'espaces : + et - doivent être entourés d'espaces, donc calc(100%-20px) est invalide. Autres causes : multiplier deux longueurs (10px * 2px) ou diviser par une longueur, ce qui ne donne pas une longueur. Un calc() invalide rend toute la déclaration invalide, et le navigateur l'ignore.
Peut-on utiliser des variables CSS dans calc() ?
Oui. calc(var(--gap) * 2) double une variable, et calc(var(--columns) * 1px) transforme un nombre sans unité en pixels. La valeur de la variable est d'abord substituée, puis le calcul est effectué.
Faut-il des espaces autour de * et / dans calc() ?
Non. Seuls + et - exigent des espaces, car sans eux -20px serait lu comme un nombre négatif. Les espaces autour de * et / sont facultatifs, mais en mettre partout est la règle la plus simple à retenir.
Quelle est la différence entre calc() et clamp() ?
calc() calcule une valeur à partir d'une expression. clamp(MIN, VAL, MAX) maintient une valeur entre deux limites. Ils se combinent : chaque argument de clamp() peut déjà contenir des calculs à la manière de calc, comme clamp(1rem, 1rem + 2vw, 3rem).