calc()
est une fonction CSS3 offrant la possibilité de réaliser des opérations mathématiques en CSS (addition, soustraction, division et multiplication).
Compatibilité
La compatibilité de cette fonction est encore un peu limitée aux navigateurs récents. Les gros écueils étant les versions Internet Explorer antérieures à IE9, et les anciens Android (avant 4.4).
Navigateurs | Versions | Détails |
---|---|---|
![]() |
Internet Explorer 9+ | |
![]() |
Firefox 4+ Firefox Mobile |
préfixe -moz- jusqu'à Firefox 15 |
![]() |
Chrome 19+ Chrome Mobile |
préfixe -webkit- jusqu'à Chrome 25 |
![]() |
Opera 15+ Opera Mobile 21+ |
|
![]() |
Safari 6+ |
préfixe -webkit- jusqu'à Safari 6.1 |
![]() |
Android Browser 4.4+ |
Et ma calculatrice ? Mon Préprocesseur ?
Le navigateur peint la page, connaît l'interaction entre les éléments, calcule et interprête toutes les valeurs au sein de leur contexte, qu'il s'agisse de pixels, de pourcentages, de em
, rem
, pt
, etc. Concrètement, seul un navigateur est capable de savoir ce que donne l'expression "100px + 2em"
. Aucune machine à calculer ni aucun préprocesseur ne peut exécuter ce calcul en amont avant que la page ne soit lue par le navigateur, car ils ne connaissent pas le contexte de rendu.
Bref, avec calc()
, on laisse faire le navigateur faire son boulot, et c'est tant mieux.
Petit exemple pratique
Prenons une boîte à qui l'on a eu le malheur d'appliquer un width: 100%
:
div {
width: 100%;
padding: 10px;
}
Bien sûr, la boîte déborde à présent de son parent puisque sa taille réelle n'est pas de 100%
, mais de 100% + 20px
(la valeur du padding s'ajoute).
Fort heureusement, box-sizing
est là pour nous sauver, mais sachez qu'il est également possible de procéder différemment, grâce à l'emploi de calc()
:
div {
width: calc(100% - 20px);
padding: 10px;
}
Note : attention, l'espace est nécessaire autour du signe d'opération, sans quoi calc()
n'aura pas d'effet.
Autres exemples
calc()
permet bien évidemment de réaliser des opérations simples et des mélanges d'unités, mais d'autres calculs plus complexes sont envisageables également : ainsi il est par exemple possible d'imbriquer des fonctions calc()
au sein des fonctions calc()
, et même d'utiliser la fonction attr()
pour récupérer la valeur d'un attribut HTML et s'en servir dans des calculs.
Calculs simples
Opérations simples concernant les longueurs et tailles :
.content {
width: calc(100% / 3);
}
Voir le résultat :
See the Pen calc(100% / 3) by Alsacreations (@alsacreations) on CodePen.
Ou encore :
.content {
border-width: calc(10px - 1em);
}
Positionnements
Toutes les opérations destinées à définir une position ou un décalage :
.content {
background-position: calc(100% - 50px) calc(100% - 20px);
}
Ou encore :
.content {
position: relative;
top: calc(100px - 5rem);
}
Constructions de grilles et gouttières
Calculs savant pour établir les largeurs de colonnes en tenant compte des gouttières. Ici 5 colonnes espacées d'une gouttière de 1em :
.truc > div {
width: calc((100% / 5) - (1em - 1em / 5));
float: left;
}
Associé à un préprocesseur (ici LESS) :
.grid (@number) {
float: left;
width: calc((100% - (@gutter*(@number - 1))) / @number);
}
Combinaisons avec d'autres propriétés
Centrer verticalement une image :
img {
top: calc(50% - attr(height) / 2);
}
À l'heure actuelle, cette combinaison n'est reconnue par aucun navigateur.
Combinaisons avec des variables CSS
Pour récupérer et exploiter la variable --small-value
:
img {
top: calc(var(--small-value) / 2);
}
À l'heure actuelle, cette combinaison n'est reconnue que par Firefox 30+.
Corrections de bugs de navigateurs
calc()
permet également de pallier les déficiences navigateurs :
html {
font-size: 62.5%;
/* équivalent 10 pixels, sauf sous IE à partir de la version 9 (qui pense que la taille est de 9.93px) */
font-size: calc(1em * 0.625);
/* L'astuce pour corriger le calcul sous IE 9 à 11 */
}
Plus d'informations à propos de ce bug, sur le forum de Microsoft.
(merci @victorbritopro)
Application en responsive
Intégré à certains éléments ou attributs HTML :
sizes="(min-width: 36em) calc(.333 * (100vw - 12em)), 100vw"
Source et explications au sein d'un article sur SmashingMagazine. (et en version française sur La Cascade).
Comme ces divers exemples le montrent aisément, les possibilités d'usage de calc()
sont extrêmement vastes. Dès lors que des nombres sont impliqués : les longueurs, les fréquences, les angles, les durées, les nombres et les entiers. En d'autres termes, vous pouvez l'utiliser partout sauf dans les chaines de caractères.
Alternatives ?
Pour les anciennes versions de navigateurs qui ne reconnaissent pas calc()
, son support peut être détecté via Modernizr en JavaScript.
Voici l'extrait de code en question :
var el = document.createElement("div");
var isCalcSupported;
el.style.cssText = "width: calc(2em);"; //adapter pour inclure les préfixes nécessaires
isCalcSupported = !!el.style.length;
(merci @jacqueminv)
Grâce à cette détection, une alternative peut éventuellement être mise en place.
Cet article est inspiré d'un extrait du livre de Hugo Giraudel à paraître prochainement