Funções matemáticas CSS: calc, min, max, clamp

Publicados: 2022-03-20
Introdução » As funções lógicas CSS calc() , clamp() , min() e max() são suportadas por todos os navegadores modernos. Mas, apesar de estar prontamente disponível – uma simples pesquisa no GitHub nos diz que a adoção dessas funções tem sido lenta. Então, como exatamente os usamos para criar experiências de layout fluidas e responsivas? Vamos descobrir.

Índice
  • calcular()
  • min()
  • max()
  • braçadeira()
  • Criando uma barra lateral responsiva com grade
  • Aplicando uma lacuna responsiva para layouts Flexbox
  • Posso usar: O suporte está lá
  • Conclusão

Eu sei o que você pode estar pensando: “Matemática?! Que nojo. Tire isso da minha vista.” . Mas, pergunte a si mesmo – você tem força de vontade para resistir à satisfação de contêineres aninhados perfeitamente alinhados?

Você sabe, depois que escrevi meu artigo sobre vários truques de CSS (ele foi escolhido por algumas publicações), vi tráfego chegando ao site para palavras-chave como “como centralizar um elemento div”, o que é engraçado porque nunca mencionei isso em especificamente o artigo. Mas isso mostra que os desenvolvedores precisam de acesso a trechos rápidos que podem ser reimplementados com facilidade.

Como tal, essa será a premissa para este tutorial.

 Atualização: eu comecei a escrever um tutorial detalhado para centralizar elementos em CSS.

Vou me concentrar no tópico das funções matemáticas do CSS no contexto da obtenção de vários resultados de layout. Por exemplo , como criar um contêiner responsivo com algumas linhas de CSS, como adicionar preenchimento adaptativo e como fazer com que a barra lateral realmente se comporte como uma barra lateral.

Vamos dar uma olhada.


calcular()

A função calc() suporta quatro operações aritméticas: adição (+), subtração (-), multiplicação (*) e divisão (/). A função é usada principalmente para calcular a largura e a altura dinâmicas do contêiner para criar experiências de layout adaptáveis.

Exemplo de código

 .calc { background: #c8e6f5; padding: 10px 20px; width: calc(100% - 200px); } .no-calc { background: #c8e6f5; padding: 10px 20px; margin-top: 10px; } <div class="calc">100% – 200px</div> <div class="no-calc">Default container width</div>

E este seria o resultado:

100% - 200px
Largura padrão do contêiner

Mas, onde calc() mais se destaca é quando é usado para organizar elementos com um valor específico em mente. Normalmente, um design responsivo seria obtido procurando pontos de interrupção específicos e, em seguida, escrevendo sua lógica individualmente. Com calc() – podemos obter um layout responsivo com apenas uma especificação, o que o torna muito mais sustentável.

Vejamos um exemplo concreto usando display: flex; . Nosso objetivo é criar 3 elementos lado a lado que estejam vinculados à largura (100%) do container. Também queremos adicionar um espaço de 30px entre cada elemento e, claro, precisamos que ele seja responsivo!

Exemplo de código

 <style> .calc-container-flex { display: flex; justify-content: center; } .calc-container-style .item { background: #fff2ea; padding: 20px 0; width: calc((100% - 90px)/3); text-align: center; } .calc-container-style .item + .item { margin-left: 30px; } </style> <div class="calc-container-flex calc-container-style"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div>

E aqui você pode redimensionar o resultado para ver como funciona:

1
2
3

Como queremos ter um intervalo de 30px entre cada elemento, subtraímos 90px da largura inicial do contêiner (100%) e dividimos por 3 para especificar quantos elementos temos.

Ao redimensionar o resultado acima, você notará que todos os elementos respeitam suas respectivas lacunas enquanto permanecem responsivos à largura do contêiner. Muito arrumado.


min()

A função min() é usada para definir o menor valor aceitável. Leva 2 especificações diferentes separadas por uma vírgula e suporta expressão aritmética.

Digamos que você especifique font-size: min(25px,1vw); – neste exemplo, o tamanho da fonte nunca será maior que 25px e diminuirá para 1vw dependendo do tamanho da janela de visualização.

Também podemos usar min() para manipular a largura dos elementos do contêiner.

Exemplo de código

 .min-sample-box-container { width: 100%; max-width: 1000px; } .min-sample-box { background: #fff2ea; padding: 15px 30px; width: min(70%, 800px); } <div class="min-sample-box-container"> <div class="min-sample-box">min() example - 800px limit</div> </div>

Tente redimensionar isso:

min() exemplo – limite de 800px

Nesse contexto, o elemento div dentro de nosso contêiner não pode exceder 800px de largura, apesar de o contêiner ter uma largura máxima de 1000px.


max()

A função max() nos permite fazer exatamente o oposto. Dos dois valores, especificamos dentro de max() – o maior será priorizado.

Exemplo de código

 .max-sample-box-container { width: 100%; max-width: 1000px; } .max-sample-box { background: #fff2ea; padding: 15px 30px; width: max(70%, 200px); } <div class="max-sample-box-container"> <div class="max-sample-box">max() example - 200px limit</div> </div>

Tente redimensionar isso em um contêiner menor para ver o que acontece:

exemplo max() - limite de 200px

Como você pode ver – o container respeita a width: 100%; mas não fica abaixo da marca de 200px especificada, pois é o maior valor para o contêiner.

O recurso max() é particularmente útil ao aplicar margens responsivas. Normalmente, o que acontece quando você usa muitos elementos menores em um layout é que eles entopem a tela uma vez redimensionados. Com max() podemos priorizar uma margem específica para respeitar a largura do container.

Exemplo de código

 .max-margin-container { display: flex; flex-wrap: wrap; width: 100%; } .max-margin-container li { background: #fff2ea; color: #fff; padding: 3px 25px; min-width: 60px; text-align: center; margin: 0 max(4px,1vw) max(4px,1vw) 0; } <ul class="max-margin-container"><li>calc()</li><li>min()</li><li>max()</li><li>clamp()</li> <li>sin()</li><li>cos()</li><li>tan()</li><li>acos()</li><li>asin()</li><li>atan()</li> <li>atan2()</li><li>hypot()</li><li>sqrt()</li><li>pow()</li></ul>

Tente redimensionar a lista para vê-la em ação:

  • calcular()
  • min()
  • max()
  • braçadeira()
  • pecado()
  • cos()
  • bronzeado()
  • acos()
  • como em()
  • numa()
  • atan2()
  • hipot()
  • sqrt()
  • Pancada()

Alterar a janela de visualização do seu navegador é um exemplo melhor dessa demonstração em ação. E, sim, essas são de fato todas as funções matemáticas disponíveis em CSS!

Como você pode ver, apesar da largura da janela de visualização mudar, os botões mantêm sua margem de 4px o tempo todo.


braçadeira()

A função clamp() é usada para definir o intervalo aceitável de vários valores para um elemento de layout: mínimo , preferencial e máximo . Mais comumente, clamp() é usado para definir um intervalo de valores aceitáveis ​​para tipografia, para criar o efeito de tipografia fluida .

É, em essência, a culminação dos recursos min() e max() .

Um exemplo:

font-size: clamp(1rem, 4vw + 1rem, 4rem);

E aqui está o que parece:

Exemplo de função de grampo CSS

Nesse contexto, estilizamos nosso cabeçalho h2 com um valor mínimo de 1rem , um máximo de 4rem e definimos nosso tamanho preferido para 4vw (unidades de viewport) + 1rem . Como você pode ver na demonstração acima, à medida que nossa janela de visualização muda, o tamanho da fonte do título também muda.

Isso também conclui nossa introdução às funções matemáticas mais amplamente suportadas em CSS.

A próxima seção é dedicada inteiramente a exemplos e vários casos de uso em que essas funções podem ser aplicadas. No geral, nosso foco está na criação de elementos de design responsivos que, de outra forma, precisariam ser escritos por meio de consultas de mídia.

Criando uma barra lateral responsiva com grade

Você pode implementar uma barra lateral responsiva totalmente funcional com apenas 2 linhas de CSS?

Absolutamente.

Para esta demonstração, vamos criar uma barra lateral responsiva usando display: grid; e personalizar a capacidade de resposta com grid-template-columns . Especificamente, usaremos as funções fit-content e minmax() para definir nossas restrições.

Exemplo de código

 .grid-sidebar-demo { display: grid; grid-template-columns: fit-content(25ch) minmax(min(55vw, 35ch), 1fr) }

Aqui está o resultado:

O conteúdo da barra lateral Seu conteúdo na página

Vamos entender o que está acontecendo aqui.

Primeiro, aplicamos fit-content para declarar o tamanho preferido de nossa barra lateral. O valor que especificamos aqui empurrará a barra lateral para aumentar (com base no tamanho da janela de visualização) ou diminuir em telas menores. O tempo todo considerando a quantidade de conteúdo que você tem na barra lateral.

Depois, aplicamos minmax() porque não queremos que a barra lateral se sobreponha à área de conteúdo da página. No nosso caso, defina um valor de 55vw que será usado para exibição em dispositivos móveis e 35ch que será usado para viewports maiores. E, por último, aplicamos a unidade de fração específica da grade para preencher o espaço quando a janela de visualização permitir.

Aplicando uma lacuna responsiva para layouts Flexbox

Este é um exemplo semelhante ao preenchimento responsivo que vimos anteriormente. Mas para esta demonstração, estamos usando flexbox e a propriedade gap junto com clamp() .

Exemplo de código

 .gap-boxes-container { display: flex; flex-wrap: wrap; gap: clamp(5px, 1vw, 25px); place-content: center; } .gap-box { display: inline-flex; width: 100px; height: 100px; background-color: #fff2ea; align-items: center; justify-content: center; } <div class="gap-boxes-container"> <div class="gap-box">1</div> <div class="gap-box">2</div> <div class="gap-box">3</div> <div class="gap-box">4</div> </div>

Experimente:

1
2
3
4

Mais uma vez, esta demonstração funciona melhor quando você redimensiona a janela de visualização real do navegador.

Especificando gap: clamp(5px, 1vw, 25px); estamos dizendo ao navegador para adaptar a lacuna entre cada coluna com base no tamanho da janela de visualização. Portanto, se a janela exceder 1vw – a lacuna aumenta para 25px, enquanto uma pequena janela de visualização diminuirá para 5px (no celular, por exemplo).

Aliás, você deve ter notado que usei uma propriedade interessante para centralizar as caixas do container, é place-content: center; . Esta é uma propriedade abreviada que suporta o posicionamento do conteúdo em várias direções. Você pode ler mais sobre isso no MDN.

Posso usar: O suporte está lá

Conclusão

Você está animado para experimentar alguns desses conceitos em seu próximo projeto?

Devo dizer que o CSS percorreu um longo caminho desde o início dos anos 2010. Na verdade, se pudermos fazer a maior parte do nosso estilo responsivo sem consultas de mídia, isso atrairá ainda mais desenvolvedores que desejam escrever código e não se preocupar com a compatibilidade entre vários dispositivos.

Obrigado por ler, e divirta-se!