CSS CSS – Altura automática proporcional à largura sem JavaScript

Aprenda a definir elementos com dimensões proporcionais com CSS sem nenhuma linha de JavaScript.

Akira Hanashiro 13 de janeiro de 2020

Olá Web Developer! Hoje em dia precisamos desenvolver páginas para os mais variados tamanhos de telas. Isso está cada vez mais simples, principalmente com o Flexbox e CSS Grid. Porém, não temos ainda uma propriedade no CSS que nos permite definir a proporção das dimensões de um elemento. Aqui nós aprenderemos como é fácil fazer isso.

Padding com porcentagem

Algo que pode passar despercebido por alguns desenvolvedores é usar porcentagem como valor das propriedades de margem interna (padding).

Quando definimos um valor em porcentagem, estamos querendo que aquele valor seja relativo a um outro valor. Então quando definimos que queremos um width de 50%, estamos dizendo que queremos que ele tenha a metade do valor do width do elemento pai. Se este tiver 200px de largura, o filho com 50% ficará com 100px de largura.

Quando usamos porcentagem no padding, ele não irá pegar a porcentagem relativa ao padding do elemento pai, e sim, proporcional à largura do pai. Veja no exemplo interativo abaixo:

<div class="box-container" >
    <div class="box-content" ></div>
</div>

Note que eu não defini nenhuma altura para .box-container, apenas largura. E no seu elemento filho, .box-content, mandei ele ter altura igual a 0 e coloquei uma porcentagem em padding-bottom (também poderia ser padding-top). Assim, sua dimensão vertical ficará por conta do padding-bottom.

Como dito anteriormente, a propriedade padding utiliza a largura do elemento pai como base para calcular seu valor quando utilizamos porcentagem. Então se colocarmos o pai com width: 200px e o filho tiver padding-bottom: 50%, sua altura será 100px. Como o elemento filho tem sua altura modificada, o elemento pai também terá. Podemos aproveitar isso para criar um container que mantenha as proporções entre largura e altura. Assim, um elemento que tem sua largura modificada pela largura da tela manterá uma altura proporcional.

Teste com outros valores. Um bom exemplo é deixar o padding-bottom com valor 100%. Isso fará com que a altura do elemento filho seja igual à largura do elemento pai, resultando em um quadrado, não importa o quanto a largura do elemento pai seja modificada.

Só um detalhe: eu defini width do .box-container em px apenas para dar um exemplo, mas você pode usar qualquer unidade para a largura do elemento pai, como % ao criar um elemento responsivo para a sua página.

Criando um container reutilizável

Agora que já entendemos o conceito, vamos arrumar esse elemento para que ele seja reutilizável em qualquer projeto. Vamos por partes para entender como ele vai funcionar até chegar em um resultado bem simples e limpo.

Aproveitando pseudo-elementos

Para não ter o trabalho de escrever no HTML um elemento como container que cuidará da largura e um elemento filho apenas com padding-bottom para cuidar da altura, podemos aproveitar os Pseudo-Elementos. Assim criaremos uma única tag e o CSS automaticamente irá inserir o responsável pela altura.

Vamos então remover o box-content e passar suas propriedades para um pseudo-elemento de box-container.

<div class="box-content" ></div>

E nosso CSS está no exemplo abaixo:

Ok, não temos mais uma div vazia, passamos essa função para um pseudo-elemento que já está crescendo, mas o elemento pai não está mais. O pseudo-elemento também não possui mais largura, pois sua dimensão é baseada no seu conteúdo, e definimos content como vazio (“”). Mas isso não importa, já que ele é apenas um controlador de altura. O que faremos agora é arrumar para que o elemento pai possa ter sua altura modificada.

Arrumando os pseudo-elementos

A primeira coisa a se notar é que o pseudo-elemento está ocupando espaço. Isso pode atrapalhar o conteúdo que quisermos colocar no nosso container. Um jeito simples para ele não atrapalhar nosso conteúdo é colocar um float.

A propriedade float sempre precisa ser limpada para evitar problemas no layout. Podemos fazer isso usando outro pseudo elemento, que colocaremos no ::before. Como por padrão os pseudo-elementos crescem de acordo com seu conteúdo e aqui também colocamos o content vazio, vamos mudar seu display para block para ele ter um tamanho.

Nosso código ficará assim:

Deixando o elemento reutilizável

Veja que agora temos uma única tag que podemos controlar a altura apenas mudando a sua largura. Mas para que o elemento seja realmente reutilizável, precisamos permitir que o desenvolvedor possa definir qual a proporção daquele elemento. Podemos aproveitar as variáveis CSS. Se você ainda não sabe como usá-las, eu mostro no nosso canal do YouTube no vídeo Variáveis com CSS puro.

Vamos criar uma variável CSS que vai indicar qual a proporção que deve ser mantida. Vamos chamar de aspect-ratio e colocar diretamente na tag. Vamos supor que queremos a mesma proporção de telas widescreen, que é 16:9. Vamos criar a variável com o valor 16/9. Assim poderemos utilizar este valor com a função calc() para calcular a porcentagem, afinal é mais simples de entender 16/9 do que 56.26%, não é mesmo?

<div class="box-content" style="--aspect-ratio: 16/9" ></div>

E o nosso novo padding-bottom está no exemplo abaixo:

Simplificando ainda mais o HTML

O nosso elemento com dimensões proporcionais está pronto. Temos um CSS simples e para utilizar basta criar um elemento com a classe box-content e colocar uma variável aspect-ratio para definir a proporção. Se quiser, você pode parar por aqui mesmo.

Mas se precisamos definir a variável de controle de proporção, não seria mais simples definir estes estilos simplesmente para elementos que possuem essa variável, nos poupando do trabalho de ter que colocar a classe box-content? Podemos fazer isso apenas alterando os seletores.

Vamos trocar o seletor .box-content por [style*="--aspect-ratio"]. Esse seletor basicamente está indicando para pegar os elementos que possuem --aspect-ratio em alguma parte dentro do atributo style.

Veja como nosso HTML ficará bem mais simples:

<div style="--aspect-ratio: 4/3" ></div>
<div style="--aspect-ratio: 16/9" ></div>

E nosso CSS:

Agora você tem um container reutilizável que mantém a proporção entre largura e altura. Para deixá-lo responsivo, basta deixar seu width como 100%. Assim ele mudará de tamanho de acordo com o seu elemento pai.

Deixe seu comentário

Conheça o autor desse artigo

  • Foto Autor Akira Hanashiro
    Akira Hanashiro

    Graduado em Análise e Desenvolvimento de Sistemas, Pós-graduado em Projetos e Desenvolvimento de Aplicações Web e MBA em Machine Learning. Especializado em Front End e curte desenvolvimento de jogos.

    Posts desse Autor

Artigos relacionados