Enfrentando problemas de alinhamento Vertical e Horizontal com CSS3.
É muito interessante hoje como lidamos com centralizações verticais e horizontais usando somente CSS3, mas o que chega a impressionar é uma grande quantidade de jovens desenvolvedores que ainda possuem dúvidas com relação a alinhamentos de elementos ou textuais.
Bem, antes de tudo, vamos criar uma lista sobre quais tópicos vamos abordar (lembrando que são propriedades base e, sozinhas, não surtem nenhum efeito):
• Display: table-cell;
• Transform: translate();
• Display: flex;
Lembre-se, deixarei explicado como o método funciona em todos os seus aspectos, incluindo como o browser renderiza e interpreta as propriedades escolhidas. Vamos ao que interessa!
Display: table-cell;
Você leitor, provavelmente já deve ter visto um conceito chamado Tableless, certo? Que era o simples fato de deixar de usar table’s e começar a trabalhar usando div’s e aproveitando o CSS para alinhar os elementos. Bem, quando deixamos de usar table’s, surgiram propriedades CSS que imitavam a forma delas e as interpretava nas div’s, como o display: table; e o que estamos citando para alinhamento.
Em tradução livre: table-cell = célula de uma tabela. Ou seja, todos os elementos que possuirem essa propriedade, vão ser somente uma única célula de uma tabela.
Segue uma demostração da diferença entre essas propriedades:
Table = <table>
Table-cell = <td>
“Mas Lucas, viemos entender como alinhar os elementos, não a história”.
Calma meu jovem, antes de toda prática, vem a teoria.
Como declarei na listagem dos tópicos, essas propriedades são nulas quando utilizadas separadamente, mas para que possamos alinhar os elementos em um table-cell, também necessitaremos das propriedades:
• Vertical-align: middle;
• Text-align: center;
• Display: inline-block; (Que será atribuido ao elemento filho, o qual queremos alinhar).
Vertical-align: middle;
Todo elemento dentro de um table-cell ou table pode ser alinhado (principalmente text0s) no eixo Y, afinal, traduzindo a propriedade: Alinhamento-vertical: meio (ao centro);
Text-align: center;
Alinha todos os elementos textuais ao centro do eixo X.
Entendendo todos esses conceitos, vamos ao que realmente interessa (“talk is cheap, show me the code!”).
“E como isso tudo junto funciona?”
Ah, vamos montar uma pequena história para exemplificar o feito!
Lembra quando traduzimos todos aqueles conceitos acima? Então é basicamente isso que você entendeu. O browser considera que você tenha uma célula de tabela (<td>) e ela consegue interpretar propriedades como vertical-align e text-align, já que a interpretação dela não é tão relativa quanto a de uma div que necessita 100% de estilização para ser renderizada. Ou seja, ela sempre existe, independente se tem conteúdo ou não.
Para saber mais sobre <td>: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td
Transform: translate();
Essa propriedade deve ser a que mais gera dúvidas em seu modo de funcionamento, mas, na verdade, é tão simples quanto roubar doce de criança (não que você deva roubar, isso é errado / feio) :P
“Mas Lucas, eu vou transformar uma tradução?”
Quê? O.o — Bem, acho que talvez você não esteja todo errado.
Vamos ao que interessa. Como toda propriedade listada, elas necessitam de algumas filhas e para esse métodos, essas filhas são:
• Position: absolute;
• Top: #;
• Left: #;
Position: absolute;
Faz com que seu elemento saia de um plano estático (static) e faça parte de um plano absoluto, isso significa que, agora ele vair “sair” do HTML e começar a fazer parte de um plano paralelo, como se fossem camadas do Photoshop (e então entra o z-index para você definir em qual camada ele vai estar). Se não for definido nenhum top, right, bottom ou left, o elemento permanecerá na posição onde ele foi renderizado (incluido no HTML).
Top: #;
Define a distância de um elemento (que esteja fora de um plano estático) do topo do documento.
Left: #;
Define a distância de um elemento (que esteja fora de um plano estático) da esquerda do documento.
Se juntarmos as três propriedades, utilizando 50% em top e left, você pode ver que ficará um pouco mais baixo e a direita, não estando no centro. Isso ocorre, pois o top e left vão considerar o primeiro pixel do topo e o primeiro da esquerda como alinhamento, concluindo então que a primeira interseção de pixel estará totalmente centralizado, enquanto o resto do elemento ficará para fora e ai entra o Transform: translate();
Transform: translate();
O que ele faz é justamente traduzir para o browser que esse elemento existe e tem sua própria largura e altura, bem, mas isso foi só uma ligação sobre a brincadeirinha que deixei no começo desse tópico. O que acontece na verdade é que o top e left são considerados propriedades do Documento, enquanto transform é considerado uma propriedade do Elemento.
Se temos 50% para ambos top e left, então precisamos fazer com que o browser entenda que a largura e altura do elemento devem ser considerados, ou seja: transform: translate(-50%, -50%);
Ele anula as posições com relação ao Elemento, não ao Documento. Vamos supor que o Elemento tenha 100px de largura e altura, então o que ele vai fazer é basicamente isso:
top: calc(50% - (100px / 2));
left: calc(50% - (100px / 2));
Bem, acho que consegui explicar essa parte :p
Display: flex;
Essa é a mais recente e que não precisa de muitas explicações. Vamos levar em consideração o conceito “aceita que dói menos”. Nessa parte eu vou precisar falar pouco e mostrar diretamente o código, já que sua construção é completamente semântica e não deixa dúvidas.
O display: flex; também acompanha outras duas propriedades para alinhamento, tais como:
• justify-content: center;
• align-items: center;
Justify-content: center;
Em tradução livre, justifica todo o conteúdo filho ao eixo X do elemento pai.
Align-items: center;
Em tradução livre, alinha todo o conteúdo filho ao eixo Y do elemento pai.
Levando tudo isso em consideração, também pelo fato de ser totalmente semântico, agora só me resta exibir o exemplo prático:
Bom, ficamos por aqui com todas as explicações. Se você já é desenvolvedor faz algum tempo e viu algum ponto (ou muitos) em que posso melhorar esse tópico, adoraria que me enviassem feedbacks. Se forem desenvolvedores iniciantes, adoraria também ver o ponto de vista de vocês e o retorno.
Um grande abraço a todos!