A nova propriedade CSS que ajuda a manter o espaçamento em layouts responsivos.
Proporção
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 o vídeo e as câmeras de consumo mais recentes tendem a ter uma proporção de 16:9.
Com o advento do design responsivo, manter a proporção tem sido cada vez mais importante para desenvolvedores da Web, especialmente porque as dimensões da imagem são diferentes e os tamanhos dos elementos mudam com base no espaço disponível.
Alguns exemplos de onde a manutenção da proporção se torna importante:
- Criar iframes responsivos, em que eles são 100% da largura de um pai, e a altura precisa permanecer uma proporção de janela de visualização específica
- Criação de contêineres de marcador de posição intrínseco para imagens, vídeos e incorporações para evitar o redimensionamento quando os itens são carregados e ocupam espaço
- Criar um espaço uniforme e responsivo para visualizações de dados interativas ou animações SVG
- Criar um espaço uniforme e responsivo para componentes com vários elementos, como cards ou datas do calendário
- Criação de espaço uniforme e responsivo para várias imagens de dimensões variadas (pode ser usado com
object-fit
)
Ajuste de objeto
A definição de uma proporção ajuda a dimensionar mídias em um contexto responsivo. Outra ferramenta nesse
bucket é a propriedade object-fit
, que permite aos usuários descrever como um objeto (como uma imagem)
dentro de um bloco deve preencher esse bloco:
Os valores initial
e fill
reajustam a imagem para preencher o espaço. No nosso exemplo, isso faz com que
a imagem seja comprimida e desfocada, já que ela reajusta os pixels. Isso não é ideal. O object-fit: cover
usa
a menor dimensão da imagem para preencher o espaço e corta a imagem para que ela se encaixe com base nessa
dimensão. Ela "aumenta o zoom" em seu limite mais baixo. object-fit: contain
garante que toda a imagem
esteja sempre visível, ou seja, o oposto de cover
, em que ela assume o tamanho do limite maior
(no nosso exemplo acima, essa é a largura) e redimensiona a imagem para manter a proporção intrínseca
enquanto se encaixa no espaço. O caso object-fit: none
mostra a imagem cortada no centro
(posição de objeto padrão) no tamanho natural.
O object-fit: cover
tende a funcionar na maioria das situações para garantir uma interface uniforme ao lidar
com imagens de dimensões variadas. No entanto, você perde informações dessa forma (a imagem é cortada
nas bordas mais longas).
Se esses detalhes forem importantes (por exemplo, ao trabalhar com uma superfície plana de produtos de beleza), o corte de conteúdo importante não será aceitável. O cenário ideal seria imagens responsivas de tamanhos variados que se encaixam no espaço da interface sem serem cortadas.
O truque antigo: manter a proporção com padding-top
Para tornar esses elementos mais responsivos, podemos usar a proporção. Isso nos permite definir um 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 na largura de uma imagem é conhecida como "Padding-Top Hack". Essa solução requer um contêiner pai e um contêiner filho absolutamente posicionado. É possível calcular a proporção como uma porcentagem a ser definida
como padding-top
. Exemplo:
- Proporção de 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
Infelizmente, o cálculo desses valores de padding-top
não é muito intuitivo e requer alguns
custos e posicionamentos adicionais. Com a nova propriedade
CSS aspect-ratio
intrínseca, a linguagem para manter as proporções
é muito mais clara.
Com a mesma marcação, podemos substituir padding-top: 56.25%
por aspect-ratio: 16 / 9
, definindo
aspect-ratio
como uma proporção especificada de width
/ height
.
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
Usar aspect-ratio
em vez de padding-top
é muito mais claro e não altera a propriedade
de padding para fazer algo fora do escopo normal.
Essa nova propriedade também adiciona a capacidade de
definir a proporção para auto
, em que "elementos substituídos com uma proporção intrínseca usam essa proporção
caso contrário, a caixa não tem uma proporção preferida". Se auto
e <ratio>
forem
especificados juntos, a proporção preferencial será a proporção especificada de width
dividida por height
, a menos que
seja um elemento substituído com
uma proporção intrínseca. Nesse caso, essa proporção será usada.
Exemplo: consistência em uma grade
Isso funciona muito bem com mecanismos de layout CSS, como a grade CSS e o Flexbox. Considere uma lista com filhos em que você quer 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;
}
Exemplo: como evitar a mudança de layout
Outro ótimo recurso do aspect-ratio
é que ele pode criar espaço para o marcador de posição para evitar a
Cumulative Layout Shift e fornecer Métricas da Web melhores. Neste primeiro
exemplo, o carregamento de um recurso de uma API, como a Unsplash, cria uma
mudança de layout quando a mídia termina de carregar.
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;
}
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
definir essas dimensões como width
e height
.
No exemplo acima, sabendo que as dimensões são 800 x 600 pixels, o markup da imagem seria <img src="image.jpg"
alt="..." width="800" height="600">
. Se a imagem enviada tiver a mesma proporção,
mas não necessariamente os valores exatos de pixels, ainda poderemos usar os valores de
atributo de imagem para definir a proporção, combinados com um estilo de width: 100%
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 o aspect-ratio
na
imagem usando CSS, e a mudança de layout cumulativa é evitada (confira a demonstração no
Codepen).
Conclusão
Com a nova propriedade CSS aspect-ratio
, ao ser lançada em vários navegadores modernos, manter as proporções adequadas nos contêineres de mídia e layout fica um pouco mais simples.
Fotos de Amy Shamblen e Lionel Gustave via Unsplash.