Nova propriedade CSS de proporção compatível com Chromium, Visualização da tecnologia do Safari e Firefox Nightly

A nova propriedade CSS que ajuda a manter o espaçamento em layouts responsivos.

Proporção

Compatibilidade com navegadores

  • Chrome: 88.
  • Borda: 88.
  • Firefox: 89.
  • Safari: 15

Origem

A proporção é mais comumente expressa como dois números inteiros e dois pontos nas dimensões de: largura:altura ou x:y. As proporções mais comuns para fotografia são 4:3 e 3:2, enquanto vídeo, e as câmeras mais recentes costumam ter uma proporção de 16:9.

Duas imagens com a mesma proporção. Um tem 634 x 951 px, enquanto o outro tem 200 x 300 px. Ambas têm proporção de 2:3.
Duas imagens com a mesma proporção. Um tem 634 x 951 px, enquanto o outro tem 200 x 300 px. Ambas têm proporção 2:3.

Com o advento do design responsivo, manter a proporção tem se tornado cada vez mais importante para desenvolvedores Web, especialmente porque as dimensões das imagens e os tamanhos dos elementos mudam com base nas espaço.

Alguns exemplos de onde a manutenção da proporção se torna importante:

  • Criação de iframes responsivos, em que eles têm 100% da largura do elemento pai e a altura deve permanecer uma proporção específica da janela de visualização
  • Criar contêineres intrínsecos de marcador para imagens, vídeos e incorporações para evitar um novo layout quando os itens são carregados e ocupam espaço.
  • Criação de espaço uniforme e responsivo para visualizações interativas de dados ou animações SVG
  • Criar um espaço uniforme e responsivo para componentes com vários elementos, como cartões ou datas de calendário
  • Criar um espaço uniforme e responsivo para várias imagens de dimensões variadas (pode ser usado em conjunto object-fit)

Ajuste de objeto

Definir uma proporção nos ajuda a dimensionar a mídia em um contexto responsivo. Outra ferramenta bucket é a propriedade object-fit, que permite aos usuários descrever como um objeto (como uma imagem) dentro de um bloco devem preencher esse bloco:

Visualização de demonstração de ajuste de objetos
Apresentação de diversos valores object-fit. Veja a demonstração no Codepen (link em inglês).

Os valores initial e fill reajustam a imagem para preencher o espaço. Em nosso exemplo, isso faz que a imagem fique comprimida e desfocada durante o reajuste dos pixels. Isso não é ideal. object-fit: cover usos menor dimensão da imagem para preencher o espaço e recortar a imagem para caber dentro dela com base dimensão. Ela "aumenta o zoom" no limite mais baixo. object-fit: contain garante que toda a imagem é sempre visível, portanto, o oposto de cover, onde leva o tamanho do maior limite (em nosso exemplo acima, isso é a largura) e redimensiona a imagem para manter sua proporção intrínseca ao se encaixar no espaço. A caixa object-fit: none mostra a imagem cortada no centro (posição padrão do objeto) com o tamanho natural.

object-fit: cover tende a funcionar na maioria das situações para garantir uma boa interface uniforme ao lidar com com imagens de diferentes dimensões, porém, você perderá informações dessa forma (a imagem é cortada as arestas mais longas).

Se esses detalhes forem importantes (por exemplo, ao trabalhar com uma superfície plana de produtos de beleza), cortar conteúdo importante não é aceitável. Portanto, o cenário ideal seriam imagens responsivas tamanhos variados que cabem no espaço da interface sem cortes.

O truque antigo: manter a proporção com padding-top

Usar o padding-top para definir uma proporção de 1:1 nas imagens da pós-visualização em um carrossel.
Usar padding-top para definir uma proporção de 1:1 em imagens de pós-visualização em um carrossel.

Para torná-los mais responsivos, podemos usar a proporção. Isso nos permite definir tamanho de proporção específico e basear o restante da mídia em um eixo individual (altura ou largura).

Uma solução para vários navegadores atualmente bem aceita para manter a proporção com base no tamanho largura é conhecida como "Padding-Top Hack". Essa solução requer um contêiner pai e um contêiner filho totalmente colocado. A proporção é calculada como uma porcentagem a ser definida como padding-top. Exemplo:

  • Proporção 1:1 = 1 / 1 = 1 = padding-top: 100%
  • Proporção 4:3 = 3 / 4 = 0,75 = padding-top: 75%
  • Proporção 3:2 = 2 / 3 = 0,66666 = padding-top: 66.67%
  • Proporção de 16:9 = 9 / 16 = 0,5625 = padding-top: 56.25%

Agora que identificamos o valor da proporção, podemos aplicá-lo ao nosso contêiner pai. Veja o exemplo a seguir:

<div class="container">
  <img class="media" src="..." alt="...">
</div>

Então, poderíamos escrever o seguinte CSS:

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

Como manter a proporção com aspect-ratio

Usar a proporção para definir uma proporção de 1:1 nas imagens de pós-visualização em um carrossel.
Usar aspect-ratio para definir uma proporção de 1:1 em imagens de pós-visualização em um carrossel.

Infelizmente, calcular esses valores de padding-top não é muito intuitivo e requer algum sobrecarga e posicionamento adicionais. Com o novo aspect-ratio CSS propriedade, a linguagem para manter o aspecto proporções é muito mais clara.

Com a mesma marcação, podemos substituir padding-top: 56.25% por aspect-ratio: 16 / 9, definindo aspect-ratio para uma proporção especificada de width / height.

Como usar o padding-top
.container {
  width: 100%;
  padding-top: 56.25%;
}
Como usar a proporção
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

Usar aspect-ratio em vez de padding-top é muito mais claro e não reformula o padding. para fazer algo fora do escopo normal.

Essa nova propriedade também adiciona a capacidade de Defina a proporção como auto, em que "elementos substituídos por uma proporção intrínseca usam essa proporção". proporção caso contrário, a caixa não terá uma proporção preferencial". Se auto e <ratio> forem especificadas juntas, a proporção preferencial é a proporção especificada de width dividida por height, a menos que ele é um elemento substituído por uma proporção intrínseca. Nesse caso, a proporção é usada.

Exemplo: consistência em uma grade

Isso também funciona muito bem com mecanismos de layout CSS, como o CSS Grid e o Flexbox. Faça uma lista com filhos e você quiser manter uma proporção de 1:1, como uma grade de ícones de patrocinadores:

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
Imagens em grade com o elemento pai em várias dimensões de proporção. Confira a demonstração no Codepen.

Exemplo: impedir a mudança de layout

Outro ótimo recurso do aspect-ratio é que ele pode criar um espaço reservado para evitar Cumulative Layout Shift e fornecer Métricas da Web melhores. Nesta primeira exemplo, carregar um recurso de uma API como Unsplash cria uma mudança de layout quando a mídia termina de carregar.

Vídeo da mudança cumulativa de layout que acontece quando nenhuma proporção é definida em um recurso carregado. Este vídeo foi gravado com uma rede 3G emulada.

O uso de aspect-ratio, por outro lado, cria um marcador de posição para evitar essa mudança de layout:

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
Um vídeo com uma proporção definida é definido em um recurso carregado. Este vídeo foi gravado com uma rede 3G emulada. Confira a demonstração no Codepen.

Dica bônus: atributos de imagem para proporção

Outra maneira de definir a proporção de uma imagem é usando atributos de imagem. Se você souber as dimensões da imagem com antecedência, é uma prática recomendada defina essas dimensões como width e height.

No exemplo acima, sabendo que as dimensões são 800 x 600 pixels, a marcação de imagem ficaria assim: <img src="image.jpg" alt="..." width="800" height="600">. Se a imagem enviada tiver o mesmo aspecto de pixels, mas não necessariamente os valores exatos de pixel, ainda podemos usar imagens valores de atributos para definir a proporção, combinada com um estilo de width: 100% para que para que a imagem ocupe o espaço adequado. Juntas, elas seriam semelhantes a:

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
}

No final, o efeito é o mesmo que definir a aspect-ratio na via CSS e a mudança cumulativa de layout é evitada (veja a demonstração em Codepen).

Conclusão

A nova propriedade CSS aspect-ratio, que é lançada em vários navegadores modernos, mantém as proporções em seus contêineres de mídia e layout fica um pouco mais simples.

Fotos de Amy Shamblen e Lionel Gustave pelo Unsplash.