Função Calc()

Com a chegada do CSS3, diversas gambiarras que tínhamos que fazer para resolver problemas simples não são mais necessárias. Uma das novidades que ganhamos é a função calc(). Segundo a especificação da W3C:

The calc() function allows mathematical expressions with addition (‘+’), subtraction (‘-’), multiplication (‘*’), and division (‘/’) to be used as component values. The ‘calc()’ expression represents the result of the mathematical calculation it contains, using standard operator precedence rules. It can be used wherever <length>, <frequency>, <angle>, <time>, <number>, or <integer> values are allowed. Components of a ‘calc()’ expression can be literal values, ‘attr()’ or ‘calc()’ expressions, or <percentage> values that resolve to one of the preceding types.

O função calc () permite expressões matemáticas, como adição (‘+’), subtração (‘-‘), multiplicação (‘*’), e divisão (‘/’) que são utilizados como valores de componentes. A expressão ‘calc ()’ representa o resultado do cálculo matemático que contém, utilizando as regras de operação padrão de precedência. Ele pode ser usado sempre que <length>, <frequency>, <angle>, <time>, <number> ou <integer> são permitidos. Componentes de uma expressão “calc () ‘podem ser valores literais,” attr () “ou” calc ()’ expressões ou valores <porcentagem> que resolver para um dos tipos anteriores.

Essa função permite, ainda, que sejam utilizadas diferentes unidades de medidas para o definir os valores dos elementos, como px, em, %, etc…

Vamos começar definindo o estilo dos nossos elementos article:

article {
    border: 1px solid #333;
    height: 80px;
    margin: auto;
    width: 800px;
}

 

No nosso primeiro exemplo temos um elemento article com 3 section que dividirão o espaço igualmente entre si.

O HTML:

<article id="um">
    <section class="um-um">Um Um</section>
    <section class="um-dois">Um Dois</section>
    <section class="um-tres">Um Três</section>
</article>

O CSS:

 

#um section {
    float:left;
    height: 80px;
    width: calc(100% / 3);
    width: -webkit-calc(100% / 3);
    width: -moz-calc(100% / 3);
}

.um-um { background: #555; }

.um-dois { background: #999; }

.um-tres { background: #ccc; }

Você pode me dizer: “Mas é só colocar as section com 33% de width que resolve.”. Aí eu te pergunto: “Onde fica o 1% que sobra?”.

Bom, reconheço que não fui muito feliz na escolha do primeiro exemplo, mas agora você vai ver o que realmente importa. Vou mudar o seu mundo (tá exagerei).

O HTML:

<article id="dois">
    <section class="dois-um">Dois Um</section>
    <section class="dois-dois">Dois Dois</section>
</article>

O CSS:

 

#dois section {
    float:left;
    height: calc(100% - 40px);
    height: -webkit-calc(100% - 40px);
    height: -moz-calc(100% - 40px);
    width: calc(100% / 2 - 40px);
    width: -webkit-calc(100% / 2 - 40px);
    width: -moz-calc(100% / 2 - 40px);
}

.dois-um {
    background: #ccc;
    padding: 20px;
}

.dois-dois {
    background: #999;
    margin: 20px;
}

Quando você adiciona o atributo padding/margin em um elemento, os valores desse atributo são somados ao tamanho do elemento. Neste caso, cada um dos elementos section ficaria com 50% (100$ / 2) do tamanho total do elemento article (400px) mais os 40px de padding/margin em cada lado do elemento. Assim os 2 elementos section ficarão um abaixo do outro, pois os 2 elementos terão 440px de largura total, enquanto o article tem apenas 800px de largura.

Com o CSS 2.1 não teríamos como corrigir isso. Com a função calc() basta diminuirmos o tamanho do padding/margin do tamanho do elemento.

No exemplo publicado você pode ver o funcionamento da função calc() e se quiser baixar o código fique a vontade.

Teste, modifique, questione, critique. Use o campo de comentários para sanar dúvidas. Mas atenção, essa função ainda é uma candidata a recomendação da W3C. Para utilizá-la são necessários os prefixos proprietários (somente Chrome e Firefox suportam atualmente).

Fonte:

Maujor – Função calc();

Hongkiat – CSS3 calc() function;

W3C – CSS Values and Unit Module Level 3;

Leave a Reply