Além das unidades CSS - intrinsic sizing e responsividade
Camilo Micheletto
Posted on April 30, 2023
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¹.
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).
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.
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.
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.
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
.
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 já funciona com CSS grid
grid-template-columns: fit-content(100%) 1fr;
}
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)
)
}
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
|
---|---|
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
|
---|---|
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!
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;
}
¹ A palavra
inline
é uma _logical property _se refere ao eixo x, ou sejaleft
eright
. 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
Posted on April 30, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
March 1, 2024