Expressões matemáticas em CSS com calc()

Expressões matemáticas em CSS com calc()

Um novo recurso bastante interessante do CSS3 é a função calc(). Com esta função agora é possível calcularmos valores de expressões matemáticas diretamente no CSS! Like a rockstar coder.

Em CSS, sabemos que existem diversos tipos de valores e medidas: px, %, em, in, cm, mm, pc, pt e ex. Se quisermos atribuir qualquer valor numérico a uma determinada propriedade, apenas escolhemos uma destas unidades:

#acdc {
    width: 100px;
}

Contudo, em CSS não é permitido fazer isto:

#acdc {
    width: 100px + 10px; /* incorreto */
}

Ou seja, não é possível calcular nenhuma expressão matemática – mesmo que seja uma coisa totalmente desnecessária e tosca como o exemplo acima. E desculpem-me por isto, no próximo melhora.

Um exemplo decente

Acho que boa parte das pessoas que trabalham com CSS já se depararam com o seguinte problema: precisar apenas centralizar um elemento na tela. Isto é, independente da resolução que o cidadão esteja usando, o elemento terá que ficar centralizado. Dai você pensa, “p!@# q%$ p%$!# como é que vou fazer esta m!@#$ funcionar?”. E sem trapacear com JS.

A gambiarra solução para este pequeno impasse é bem simples, na verdade:

#pinkfloyd {
    width: 200px;
    height: 150px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -75px; /* metade da altura */
    margin-left: -100px; /* metade da largura */
}

Hora do purismo: Ter que resolver um problema de posição de um elemento usando margin é toscasso! Se já existem as propriedades top, left, right e bottom, isto deveria ser mais que suficiente, mas pela limitação do CSS de não permitir expressões matemáticas, infelizmente não poderíamos simplesmente fazer: top: 50% - 75px.

Resolvendo a bronca da maneira correta

Não seria legal se a expressão acima (top: 50% - 75px) funcionasse logo de cara, sem frescura? Pois é, por isso apresentamos… calc()!

Com calc() poderemos calcular expressões matemáticas simples de boa. Quando digo simples quer dizer apenas que não dá pra sair calculando integrais e diabo a quatro, os operadores suportados por calc() são apenas os básicos – +, -, * e / – e também podemos usar parênteses – ( e ). Mais do que o suficiente por hora.

O mais interessante é que podemos misturar valores relativos com valores absolutos, e valores de diferentes unidades. calc() automaticamente converte as diferentes unidades e calcula valores relativos (como %).

Misturando valores relativos e absolutos

O exemplo anterior ficaria:

#pinkfloyd {
    width: 200px;
    height: 150px;
    position: absolute;
    /* top: 50%; */
    /* margin-top: -75px; */
    top: calc(50% - 75px);
    /* left: 50%; */
    /* margin-left: -100px; */
    left: calc(50% - 100px);
}

Misturando unidades

Também é possível usar valores de unidades diferentes numa mesma expressão:

#ledzeppelin {
    width: calc(100px + 2in + 5em);
    min-height: calc(5em + 30px + 25% + 3.5pc);
}

Suporte

No momento em que escrevo este post, os únicos navegadores que estão dando suporte a esta propriedade são o Google Chrome v.19 (o mais novo) através da propriedade prefixada -webkit-calc() e o Mozilla Firefox, que já dá suporte desde sua versão 8 através da propriedade prefixada -moz-calc(). O Internet Explorer 9 e o Webkit Nightly Build são os únicos que dão suporte completo até o momento (calc()). Já o Opera, o Safari ainda não estão dando suporte algum.

Se vira nos 30

Agora é a sua vez =). Fiz este pequeno experimento abaixo onde é possível entrar com os valores de cada propriedade e visualizar o resultado.

AC/DC

OBS.: Se alguma expressão matemática que você digitar não surtir efeito, é porque deve estar incorreta.

Dica 1: sempre especifique uma unidade. Ex.:

  • INCORRETO: 0
  • CORRETO: 0px, 0em ou 0% etc.

Dica 2: para soma (+) e subtração (-), sempre deixe espaço entre os elementos da expressão. Ex.:

  • INCORRETO: 10px+30%, 10px +10% etc.
  • CORRETO: 10px + 30%

That’s all folks!

#10