DEV Community

Cover image for Além das unidades CSS - intrinsic sizing e responsividade
Camilo Micheletto
Camilo Micheletto

Posted on

21 1 1 1

Além das unidades CSS - intrinsic sizing e responsividade

Vocês sabem o que são tamanhos intrínsecos no CSS?
Esse artigo pretende explicar como funcionam os valores intrínsecos de max-content, min-content, fit-content e auto. Entender essas propriedades me fez tomar decisões de layout mais informadas, tendo um controle refinado sobre meu conteúdo e criando layouts mais robustos.

Sobre "valor intrínseco"

Intrinisic sizing se refere ao valor de width ou height do componente sendo calculado à partir dos valores do conteúdo e não de fatores externos como unidades estáticas como px ou relativas como % do pai imediato ou unidades de viewport.

Mas e quando queremos que o tamanho do container não seja relativo à unidades externas como viewport ou o container pai, e também não seja fixa como px ou pt?

Vamos pensar no caso de um botão, por exemplo. Esse botão receberá texto ou texto + ícone, ele terá apenas uma linha, nunca podendo "quebrar" o conteúdo pra linha de baixo. Quando esse botão tem espaço o suficiente em um container, nem precisamos declarar width, pois o valor padrão de width é auto, o que significa que a largura do elemento vai ser igual a soma de sua margin-inline, padding-inline, border-inline e conteúdo¹.

Demonstração do valor auto sendo inferido na propriedade width

 

O problema é quando diminuímos o tamanho do container pai - o container tenta "espremer" ou quebrar o conteúdo de linha pra que esse conteúdo não vaze (overflow).

Conteúdo do botão sofrendo overflow quando o container do botão é menor que o mesmo

 

Como esse não é o comportamento esperado, podemos testar algumas soluções como overflow: hidden;, que esconde o conteúdo vazado, somado ao text-overflow: ellipsis; que faz com que o texto oculto pelo overflow ganhe reticências. Porém por mais que essas soluções assegurem a estabilidade do layout, perdemos legibilidade.

4 botões, um com texto, outro com um ícone, o terceiro com texto escondido por overflow e o quarto com overflow ellipsis

 

Percebe que pra esse layout funcionar, precisamos ter controle sobre como o container (nesse caso o botão) se comporta em relação ao seu conteúdo, não em relação ao seu pai?


min-content

O min-content define o menor tamanho que um elemento pode ter sem ter overflow. Ele identifica a largura do maior filho desse container e quebra de linha todos os elementos que não cabem juntos nessa largura.

Exemplo de min-content com um texto quebrando sempre pra linha de
No caso acima, o maior filho era o TextNode com a palavra "corridor". Tudo o que não cabia na largura de "corridor" foi quebrado pra linha de baixo.

 

Um caso de uso incrível é demonstrado nesse tweet do Stefan Judis.


max-content

O valor de max-content por exemplo faz com que o elemento sempre seja do tamanho do conteúdo, independente se ele tem espaço pra isso ou não.

No caso abaixo, o texto em roxo está com max-content, mesmo o container tendo uma width fixa, o tamanho do texto é respeitado, causando overflow.

Exemplo de container sendo transbordado por um texto com max-content

 

Isso resolveria o problema do botão, por exemplo, pois nesse caso de uso a legibilidade do conteúdo sem quebra de linha era mais importante do as restrições de layout que isso causaria pro container pai desse elemento. Para evitar problemas com overflow nesse caso, é necessário que o pai de um elemento max-content tenha alguma lógica de quebra automática de conteúdo, como a propriedade flex-wrap: wrap;, por exemplo.


fit-content

Já o fit-content é um valor mais razoável - ele segue a seguinte lógica:

SE espaço disponível < max-content
Usa o espaço disponível

SE espaço disponível < min-content
Usa o min-content.

Em outras palavras, usa espaço disponível, nunca menor que o min-content, nunca maior que o max-content.

Demonstração de um texto com fit-content cabendo perfeitamente dentro do seu container

Outra forma de expressar o fit-content é na sintaxe de função. Atual

.container {
  // sintaxe ainda não aprovada pra width
  width: fit-content(200px);

  // mas  funciona com CSS grid
  grid-template-columns: fit-content(100%) 1fr;

}
Enter fullscreen mode Exit fullscreen mode

O cálculo do fit-content nesse caso funcionaria da seguinte forma se representado de forma hipotética pelo Javascript. Os valores de tamanho máximo e mínimo são calculados pelo próprio box model, portanto podemos fingir que eles estão disponíveis na closure da função pra esse exemplo.

function fitContent(arg) {
  return Math.min(
    maxSize,
    Math.max(minSize, arg)
  )
}

Enter fullscreen mode Exit fullscreen mode

A sintaxe de função só tá disponível pra uso dentro do contexto do CSS grid, mas já tá disponível pra outras propriedades no rascunho do Box Model Module 4, junto com a propriedade stretch.


Então basta eu usar fit-content pra tudo, né?

Na verdade não.

É sempre bom entender como essas propriedades funcionam e definir seus tamanhos de acordo com suas necessidades. Nos exemplos abaixo, fit-content e auto parecem que dão no mesmo resultado:

Com o valor auto Com o valor fit-content
bloco de texto com valor de width de auto Bloco de texto com o valor de width de fit-content

 

Agora, se eu diminuo o tamanho do texto, o fit-content (à esquerda) faz com que o container do texto seja exatamente igual ao conteúdo do texto, já o auto (à direita) faz com que o conteúdo ocupe a largura disponível, como se fosse um stretch

Com o valor auto Com o valor fit-content
bloco de texto com valor de width de auto Bloco de texto com o valor de width de fit-content

Suporte

As unidades de tamanho intrínseco com atual suporte são max-content, min-content e fit-content, mas há um rascunho da W3C pra aprovação do valor stretch.

Esses valores chegaram no CSS Box-Sizing Module 3 e tem suporte amplo em todos navegadores modernos, porém com algumas restrições!

Print do site caniuse na pesquisa pra intrinsic-sizes
A porcentagem de uso sem prefixing ainda é muito boa, 95.39%. Em

Caso a regra não tenha suporte de navegador, ele mesmo vai usar o valor default, no caso de height e width é auto.
Caso você queira outro comportamento que não auto na ausência de suporte pra propriedades intrínsecas, pode usar uma support rule..

@supports not (width: fit-content) {
 width: auto;
}

Enter fullscreen mode Exit fullscreen mode

¹ A palavra inline é uma _logical property _se refere ao eixo x, ou seja left e right. Declarar dessa forma faz com que os lados esquerdo e direito permaneçam os mesmos inclusive quando o eixo de escrita for rotacionado ou invertido, como é o caso de algumas línguas asiáticas ou árabes. Mais informações nesse artigo do Tárcio Zemel sobre logical properties

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (1)

Collapse
 
desenvolvweb profile image
desenvolvweb

Só agora vi a referência ao artigo. Muito obrigado pela lembrança! :)