O que o calc() faz
calc() faz contas dentro de um valor CSS, e consegue misturar unidades que só ganham tamanho na hora do layout. O caso clássico é "a largura toda menos uma barra lateral fixa":
O 100% só é conhecido depois que a página é montada, e 180px é fixo, então nenhuma unidade sozinha conseguiria expressar isso. O calc() resolve: em uma prévia com 800px de largura, a linha tem 784px e a coluna principal fica com 604px, e a linha embaixo do layout mostra os números reais. Hoje, flexbox ou grid fariam esse layout sem conta, mas a mesma subtração continua aparecendo em todo lugar: uma altura menos um cabeçalho, uma largura menos um gap.
As regras de sintaxe
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 */
| Regra | Válido | Inválido |
|---|---|---|
Espaços em volta de + e - | calc(100% - 20px) | calc(100%-20px) |
*: pelo menos um lado é um número puro | calc(2 * 1rem) | calc(2px * 3px) |
/: divida um comprimento por um número puro | calc(100% / 3) | width: calc(300px / 3px) (não é um comprimento) |
| As unidades precisam ser compatíveis | calc(1rem + 10px) | calc(1rem + 2s) |
A regra do espaço existe porque 100% -20px seria lido como dois valores separados, o segundo negativo. Quando um calc() é inválido, a declaração inteira é descartada e o elemento mantém o valor que já tinha de regras anteriores.
Teste uma expressão
Digite qualquer expressão para a largura da caixa. O navegador informa se ela é válida e a largura resultante:
Experimente 100%-200px (inválido, sem espaços), 100% / 3, 50% + 4rem, 2 * 120px, 200px * 2px (inválido) e (100% - 40px) / 2.
calc() com variáveis CSS
Variáveis e calc() andam juntos: guarde um valor base uma vez e derive o resto dele. Uma variável sem unidade vira um comprimento quando você a multiplica por uma unidade:
Mude --space para 12px ou --cols para 4 e todos os valores derivados acompanham. A página de variáveis CSS trata de como declará-las e do escopo delas.
Usos comuns
| Necessidade | calc() |
|---|---|
| Preencher o espaço ao lado de um elemento fixo | width: calc(100% - 240px) |
| Seção abaixo de um cabeçalho fixo | min-height: calc(100vh - 64px) |
| Metade da largura menos metade de um gap | width: calc(50% - 8px) |
| Centralizar uma caixa absolute de 100px | left: calc(50% - 50px) |
| Tamanho de fonte que cresce um pouco com a tela | font-size: calc(1rem + 0.5vw) |
| Transformar uma variável numérica em comprimento | calc(var(--n) * 1px) |
| O negativo de uma variável | calc(var(--space) * -1) |
Para um valor que precisa ficar entre limites, use clamp(), que aceita as mesmas contas nos argumentos sem escrever calc().
Onde o calc() funciona
Em qualquer lugar onde um comprimento, porcentagem, número, ângulo ou tempo é permitido: width, margin, padding, top, font-size, line-height, tamanhos de trilhas do grid, transition-delay e ângulos dentro de transform. Ele pode ser aninhado, e um calc() aninhado equivale a parênteses simples.
Os ângulos são um bom exemplo. Cada marcação abaixo tem o próprio --i (de 0 a 11), e uma única regra o transforma em ângulo com calc(var(--i) * 30deg):
A marcação 3 recebe rotate(90deg), que o Chrome informa como a matriz matrix(0, 1, -1, 0, 0, 0): um quarto de volta. left: calc(50% - 2px) centraliza cada marcação subtraindo metade dos 4px de largura dela.
Erros comuns
- Sem espaços em volta de
-ou+.calc(100%-20px)é inválido e ignorado. - Multiplicar dois comprimentos.
calc(10px * 2px)não tem significado no CSS. Um dos lados do*precisa ser um número puro. - Usar calc() em uma altura em porcentagem sem altura no pai.
calc(100% - 20px)emheightprecisa de um pai com altura definida, assim comoheight: 100%. - Usar calc() onde flexbox ou grid resolveriam.
width: calc(33.333% - 10px)para colunas é frágil;display: grid; grid-template-columns: repeat(3, 1fr); gap: 15pxnão precisa de conta. - Esperar uma mensagem de erro. O navegador não avisa sobre um calc() inválido. Confira o elemento nas ferramentas de desenvolvedor: uma declaração inválida aparece riscada.
Perguntas frequentes
O que o calc() faz no CSS?
Calcula um valor a partir de uma expressão com +, -, * e /, e consegue misturar unidades que o navegador só conhece na hora do layout. width: calc(100% - 200px) é a largura toda do pai menos 200px, seja qual for a largura do pai.
Por que meu calc() não funciona?
A causa mais comum é a falta de espaços: + e - precisam de espaço dos dois lados, então calc(100%-20px) é inválido. Outras causas são multiplicar dois comprimentos (10px * 2px) ou dividir por um comprimento, o que não dá um comprimento. Um calc() inválido torna a declaração inteira inválida, e o navegador a ignora.
Dá para usar variáveis CSS no calc()?
Sim. calc(var(--gap) * 2) dobra uma variável, e calc(var(--columns) * 1px) transforma um número sem unidade em pixels. O valor da variável é substituído primeiro, e depois a conta é feita.
Preciso de espaços em volta de * e / no calc()?
Não. Só + e - exigem espaços, porque sem eles -20px seria lido como um número negativo. Os espaços em volta de * e / são opcionais, mas colocá-los em tudo é a regra mais fácil de lembrar.
Qual a diferença entre calc() e clamp()?
calc() calcula um valor a partir de uma expressão. clamp(MIN, VAL, MAX) mantém um valor entre dois limites. Os dois se combinam: cada argumento do clamp() já aceita contas no estilo do calc, como clamp(1rem, 1rem + 2vw, 3rem).