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.