5 pontos por GN⁺ 2024-02-14 | 3 comentários | Compartilhar no WhatsApp
  • Centralizar no CSS não é mais um truque único; trata-se de escolher entre Flow, Flexbox, Positioned layout, CSS Grid, text-align conforme o elemento esteja no fluxo do documento, flutuando, ou haja vários elementos
  • Para centralizar horizontalmente um único elemento, a abordagem de Flow layout com max-width: fit-content para limitar a largura e margin-inline: auto tende a afetar menos os elementos irmãos
  • Com Flexbox, basta justify-content: center e align-items: center para centralizar horizontal e verticalmente um ou vários filhos, e mesmo que os filhos ultrapassem o contêiner, o overflow acontece de forma simétrica
  • Para interfaces flutuantes como modais e banners, a combinação de position: fixed, inset: 0, limites de tamanho e margin: auto é a mais adequada, enquanto o CSS Grid se destaca por uma sintaxe curta e por empilhar sobreposições
  • O próprio texto exige text-align: center, não alinhamento de layout, e conforme o suporte a align-content no Flow layout se ampliar, pode diminuir a necessidade de trocar para Flexbox ou Grid apenas para alinhamento vertical simples

Centralização horizontal no Flow layout com auto margin

  • Uma das estratégias antigas é limitar a largura do elemento e então definir as margens laterais como auto
.element {
  max-width: fit-content;
  margin-left: auto;
  margin-right: auto;
}
  • Elementos no Flow layout normalmente ocupam todo o espaço horizontal disponível, então é preciso primeiro restringir a largura para colocá-los no centro
  • fit-content faz o elemento envolver o conteúdo, permitindo que a width seja determinada pelo tamanho do conteúdo, como acontece com height
  • Usar max-width em vez de width limita apenas o tamanho máximo, então, se o contêiner ficar mais estreito, o elemento também pode encolher
  • Se houver apenas margin-left: auto, o espaço restante vai para a margem esquerda; se as duas margens forem auto, o espaço restante é dividido igualmente e o elemento fica centralizado
.element {
  max-width: fit-content;
  margin-inline: auto;
}
  • margin-inline é a forma moderna de definir margin-left e margin-right com o mesmo valor, e tem bom suporte nos navegadores
  • margin-inline faz parte das logical properties, então funciona com base no eixo inline da direção de escrita, e não simplesmente em esquerda/direita
    • Assim, a margem é aplicada corretamente tanto em idiomas escritos da esquerda para a direita quanto da direita para a esquerda
  • Essa abordagem é útil quando você quer centralizar apenas um único filho — como uma imagem entre parágrafos de um blog — sem afetar os elementos irmãos

Centralizar um ou vários filhos com Flexbox

  • Flexbox é um modo de layout forte para posicionar vários itens ao longo do eixo principal, e por isso é muito usado para centralização
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}
  • Usando justify-content: center junto com align-items: center, é possível centralizar os filhos horizontal e verticalmente
  • Mesmo que os filhos não caibam no contêiner, o alinhamento é mantido e, quando há excesso, o overflow acontece de forma simétrica
  • Também é possível centralizar vários filhos, e flex-direction controla a direção em que eles são empilhados
.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  gap: 4px;
}
  • É uma opção padrão excelente por se aplicar amplamente a um único filho ou a vários

Centralizar interfaces flutuantes com Positioned layout

  • Elementos como modais, prompts e banners, que precisam sair do fluxo normal do documento e ficar flutuando acima dele, podem ser tratados com Positioned layout
.element {
  position: fixed;
  inset: 0px;
  width: 12rem;
  height: 5rem;
  max-width: 100vw;
  max-height: 100dvh;
  margin: auto;
}
  • position: fixed fixa o elemento à viewport, e inset: 0px define top, left, right e bottom como 0px
  • Se houver apenas inset: 0px, o elemento tentará ocupar toda a viewport, por isso é necessário limitar seu tamanho com width, height, max-width e max-height
  • Essa combinação cria de propósito uma condição impossível
    • O elemento não pode ao mesmo tempo estar a 0px da esquerda e da direita e ainda ter largura de 12rem
    • O motor de renderização do CSS prioriza a restrição de width e resolve a tensão encostando em um dos lados, conforme a direção do idioma
  • Ao adicionar margin: auto, a forma como o navegador resolve isso muda, e o elemento passa a ficar centralizado na horizontal e na vertical
  • As quatro condições necessárias são position: fixed, inset: 0px, largura e altura limitadas, e margin: auto
  • Centralizar em apenas uma direção, como em um banner inferior

    .element {
      position: fixed;
      left: 0px;
      right: 0px;
      bottom: 8px;
      width: 12rem;
      max-width: calc(
        100vw - 8px * 2
      );
      margin-inline: auto;
    }
    
    • Ao omitir top: 0px, a condição impossível no eixo vertical desaparece e o elemento fica preso na parte inferior
    • calc(100vw - 8px * 2) limita a largura máxima para deixar uma folga nas duas laterais da viewport
    • margin-inline: auto expressa com mais precisão a intenção de centralizar no eixo horizontal
  • Elementos de tamanho desconhecido

    .element {
      position: fixed;
      inset: 0;
      width: fit-content;
      height: fit-content;
      margin: auto;
    }
    
    • Quando não se sabe previamente o tamanho do elemento, é possível usar width: fit-content e height: fit-content para fazê-lo envolver o conteúdo
    • É possível adicionar limites como max-width: 60vw, mas isso não é obrigatório, e o elemento permanece contido na viewport
  • Um centro intencionalmente um pouco deslocado

    • Ajustar um valor de inset de um lado, como bottom: 48px, desloca o elemento pela metade desse valor
    • Com bottom: 48px, o elemento sobe 24px
    • Isso acontece porque ele fica suspenso no centro de uma caixa virtual entre os limites superior e inferior
    • Se você usar transform: translateY(-48px), pode mover o elemento exatamente 48px para cima
    • A abordagem com offset em bottom também preserva a propriedade transform para animações ou efeitos de entrada futuros

Centralizar rapidamente com CSS Grid e empilhar sobreposições

  • No CSS Grid, o código mais curto para centralizar é a combinação de display: grid com place-content: center
.container {
  display: grid;
  place-content: center;
}
  • place-content é a forma abreviada de justify-content e align-content, aplicando o mesmo valor a linhas e colunas

  • Com essa configuração, surge uma célula de Grid 1×1 no centro do contêiner pai

  • Diferença em relação ao Flexbox

    • Embora pareça parecido com Flexbox, o CSS Grid usa um algoritmo de layout completamente diferente
    • A diferença aparece se os filhos receberem width: 50% e height: 50%
    • No Flexbox, os percentuais são calculados com base no pai .container
    • No CSS Grid, os percentuais são calculados com base na célula do Grid
    • Se grid-template-columns ou grid-template-rows não forem definidos, as trilhas do Grid calculam o tamanho com base no conteúdo, e por isso o elemento pode ficar menor do que o esperado
    • Nesses casos, dá para ajustar o Grid com mais CSS, mas para centralização simples o Flexbox pode ser mais prático
  • Empilhar vários elementos na mesma posição

    .container {
      display: grid;
      place-content: center;
    }
    
    .element {
      grid-row: 1;
      grid-column: 1;
    }
    
    • O CSS Grid permite colocar vários filhos na mesma célula
    • Se todos os .element tiverem grid-row: 1 e grid-column: 1, eles compartilham o mesmo espaço do Grid e ficam empilhados uns sobre os outros
    • Isso pode funcionar mesmo quando os filhos têm tamanhos diferentes
    .container {
      display: grid;
      place-content: center;
      place-items: center;
    }
    
    .element {
      grid-row: 1;
      grid-column: 1;
    }
    
    • Para sobrepor filhos de tamanhos diferentes e mantê-los centralizados, é preciso adicionar place-items: center
    • place-items é a forma abreviada de justify-items e align-items, e controla o alinhamento das imagens dentro da célula do Grid
    • Sem essa propriedade, mesmo que a célula do Grid em si esteja centralizada, as imagens dentro dela ficam empilhadas no canto superior esquerdo
    • Para aprofundar em CSS Grid, veja An Interactive Guide to CSS Grid

Texto é alinhado separadamente com text-align

  • Texto precisa ser tratado separadamente no CSS, porque técnicas de layout como Flexbox não alinham caracteres individuais
  • Se você centralizar um parágrafo com Flexbox, o bloco do parágrafo fica no centro, mas as letras dentro dele continuam alinhadas à esquerda
  • Para centralizar o próprio texto, é preciso usar text-align: center
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

O futuro do Flow layout: align-content

  • No Flow layout, a centralização horizontal já é possível com auto margin, mas até agora o alinhamento vertical exigia outros modos de layout, como Flexbox ou Grid
  • No início de 2024, os fornecedores de navegadores estavam implementando align-content no Flow layout
  • Esse novo comportamento controla o alinhamento do conteúdo na direção de bloco, e na época só podia ser usado por trás de flag no Chrome Canary e no Safari Technical Preview
  • O demo de exemplo não mostra o comportamento real do Flow layout; ele reproduz isso com Flexbox após verificar como Chrome Canary e Safari TP se comportavam
  • Esse recurso não cria novas interfaces, mas pode reduzir a necessidade de trocar para outro modo de layout apenas para centralização simples

Critérios de escolha conforme a situação

  • Para centralizar horizontalmente um único elemento sem afetar os irmãos, use a estratégia de auto margin no Flow layout
  • Para interfaces flutuantes como modais ou banners, use Positioned layout com auto margin para posicioná-las no centro
  • Se você quiser empilhar vários elementos centralizados na mesma posição, CSS Grid é o mais indicado
  • Para centralizar texto, use text-align, que pode ser combinado com outros métodos de centralização
  • Na maioria das demais situações, Flexbox é a escolha mais versátil
    • Funciona com um único filho ou com vários
    • Permite centralização horizontal e vertical
    • Pode ser usado tanto quando os filhos cabem no contêiner quanto quando ultrapassam seus limites

3 comentários

 
v08zbv8fvlkjasdflkj 2024-02-15

Pensando bem, de repente me incomodou que até no GeekNews os artigos não estejam centralizados... aff, rs

 
joyfui 2024-02-14

Tenho usado bastante place-items: center;, mas há vários outros métodos também.

 
GN⁺ 2024-02-14
Opiniões no Hacker News
  • Já que outros comentários estão comentando os próprios comentários, vou entrar na conversa: acho que o meme de centralização em CSS geralmente quer dizer “como colocar um elemento exatamente no centro de outro elemento”
    Do ponto de vista de implementação, é verdade que centralizar é difícil e pode ter vários significados, mas para a geração GeoCities e AngelFire isso era difícil de engolir, porque mesmo nos anos 90, com HTML, dava para colocar hello bem no meio de uma caixa amarela de 600x600 sem problemas
    Era irritante receber uma nova ferramenta supostamente melhor que não conseguia fazer uma tarefa padrão que já fazíamos, e por isso continuamos usando layouts com tabelas até o fim dos anos 2000. Eu gosto de CSS, mas talvez isso seja uma espécie de síndrome de Estocolmo
    Fiquei surpreso que valign funcione no Chromium mesmo sem existir, e não sei se isso é uma mudança recente

    • Exatamente como você disse: colocar hello no meio de uma caixa amarela de 600x600 era possível desde a primeira versão do CSS. Por exemplo, o atributo HTML valign corresponde à propriedade CSS vertical-align de caixas inline, inline-block e table-cell
      Dito isso, pela minha experiência, uma boa parte das pessoas que falam romanticamente em usar só tabelas ou reclamam que CSS é limitado e confuso não se esforçou muito para aprender como CSS realmente funciona. O autor ao menos tem consciência disso
    • No Firefox também funciona sem o atributo "valign". Mas, ao usar tabelas sem layout fixo, sempre vi diferenças sutis entre os três principais navegadores, então, em geral, eu não dependeria do comportamento de layout automático
  • Ótimo texto, e a reação aqui é bem surpreendente para um público supostamente técnico. Layout automático de páginas e formatação são realmente difíceis; na prática, chegam a ser tema de tese de doutorado[1]
    Não é realista esperar que toda essa complexidade seja abstraída em uma expressão simples como “faça do jeito que eu quero”
    Se você olhar o site de Gwern Branwen[2], ele chega perto de arte, mas o ponto central é primeiro decidir a aparência desejada e então restringir o texto para que possa ser expresso dentro daquele estilo
    Acompanho layout de páginas web desde que entrei, em 1995, numa startup chamada “a primeira revista de golfe da web”[3], e o Zen Garden e a lista/site A List Apart[4] me fizeram entender como é difícil criar conteúdo web que fique bom em vários ambientes de saída
    Levar conteúdo semântico para uma tela, papel ou um plano finito é, em essência, um mapeamento ou projeção do espaço original para o conjunto de regras do espaço de destino, e essas regras incluem restrições físicas, restrições do software do navegador e comportamentos próprios de cada navegador
    Por isso, CSS parece uma bagunça para quem quer “criar uma página web do zero”, mas, na verdade, está mais para excesso de opções do que para um conjunto de restrições que impedem você de fazer coisas
    [1] https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=thes...
    [2] https://gwern.net/
    [3] Chamava-se Golfweb e, ao que parece, acabou virando parte da CBS Sports
    [4] https://www.alistapart.com

    • Minha carreira com layout web começou em 1998, então estou uns 3 anos atrás, mas, considerando toda a experiência relacionada, ainda não vi nada tão excelente quanto o material Every Layout[1]. Recomendo muito
      [1] https://every-layout.dev/rudiments/boxes/
    • O problema do CSS é quase totalmente uma complexidade autoinfligida. É verdade que layout é difícil, mas me pergunto por que quiseram torná-lo ainda mais difícil mirando no modelo que temos hoje
      Em especial, há o objetivo de buscar um grande modelo único que sirva para todas as páginas, com a meta sisífica de recalcular o layout automático a cada página. Some a isso a meta de cobrir todos os tamanhos de janela, e não sei por que acharam que isso seria possível
    • Eu não podia deixar de incluir este link para quem quer ver mais arte em CSS
      https://css-art.com/the-girl-with-a-p-e-a-r-l-css-earring/
      Não sei quantos divs centralizados há ali
    • Nos últimos dias, tentei enfiar layout baseado em fluxo e paginação em um sistema de layout baseado em Flexbox, e confirmei que layout e formatação são mesmo difíceis
      Em especial, numa tabela com textos e objetos de tamanhos diferentes em cada coluna, decidir quando e como passar elementos para a próxima página é um trabalho complicado de escolher boas heurísticas
    • Não sei como distinguir se isso é um problema autoimposto ou um problema de pesquisa intrinsecamente difícil. Antes de entrar em desenvolvimento web, eu nunca tinha pensado que “layout é difícil”, e naquela época também já existiam janelas roláveis e redimensionáveis
      Em custom appkit, controles GTK e toolkits internos baseados em Lua, centralizar conteúdo ou quebrar linhas e alinhar elementos não era nada demais; fico curioso sobre o que estamos deixando passar na web
      Dizer que “é só uma abundância de opções” soa parecido com o TMTOWTDI, há muito enterrado
  • Excelente texto, e os elementos interativos são especialmente bons. O que me ajudou muito a entender posicionamento e centralização em CSS alguns anos atrás foi ler sobre o modelo de caixas
    Entender o modelo de caixas ajuda a avaliar o fluxo dentro do DOM, e as propriedades CSS display e position também são fundamentais para aprender posicionamento. A documentação da MDN é boa
    https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_...
    https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layou...

  • “Como centralizar” é uma pergunta clássica de CSS, e o próprio fato de isso não ser óbvio a ponto de estar na sua frente diz muita coisa. CSS é mais parecido com uma mistureba turva, uma coleção do tipo “pia da cozinha”, projetada simultaneamente por vários comitês, não por um único comitê
    A ideia de um release de verdade foi abandonada há muito tempo, e o estado atual do CSS é mais uma reunião dos estados de módulos individuais que mudam continuamente. Não é assim que se desenvolve software e, na verdade, não é uma boa forma de criar coisa nenhuma

    • Concordo e discordo. Grandes grupos humanos naturalmente se movem de forma lenta e caótica assim; é quase como tentar pastorear gatos
      Também não está claro para onde a web e suas tecnologias estão indo coletivamente, então é inevitável que surjam muitos experimentos fracassados e inconsistências. O escopo é muito mais amplo do que o de um projeto de engenharia bem planejado, com objetivos e caminhos claros
    • Acho que a pergunta sobre centralizar aparece com frequência porque, para quem está aprendendo, é uma das primeiras perguntas mais naturais
      Quem está começando a aprender a fazer uma página web ficar do jeito que quer normalmente aprende tamanho da fonte, cor, cor de fundo e alinhamento; tirando alinhamento, o resto corresponde quase 1:1 às formas anteriores ao CSS
      Antes do CSS, se você quisesse colocar conteúdo no centro, bastava colocá-lo em uma tag, não importando se era texto ou um objeto HTML como div, tabela ou botão. Muita gente esperava que o CSS também funcionasse como antigamente, sem distinguir objetos inline e de bloco, mas, como o CSS não batia com essa ideia preconcebida, surgiram perguntas como essa
  • Gostei muito deste texto, especialmente do modo de interação. Também existe uma ferramenta que, há muito tempo, quase sempre dava o resultado desejado
    http://howtocenterincss.com

  • O CSS levou décadas para oferecer uma solução tão utilizável quanto uma tabela com conteúdo centralizado, enquanto, nesse meio-tempo, usar tabelas para layout era criticado

  • Como muita gente aqui, acho CSS um desastre completo. O problema central é que as instruções de estilo ficam constantemente sobrescrevendo umas às outras, ou falham silenciosamente sem produzir efeito nenhum

  • Gostei de como um dos exemplos tinha um aviso de cookies brutalmente honesto
    “Valorizamos seus dados pessoais. Para melhorar sua experiência de navegação, usamos cookies que vendem esses dados a anunciantes. Isso é muito valioso”

  • É interessante o que dá para aprender com a história do uso de tabelas para layout. Tabelas têm bordas, padding e um layout baseado em células organizadas em colunas; por extensão, também é necessário haver espaçamento ao redor das tabelas e células, isto é, margens
    Tabelas são um elemento há muito estabelecido em layout e, na verdade, continham a sabedoria de que todos os elementos deveriam, em alguma medida, se comportar como células de tabela
    Elementos devem seguir o modelo de caixa, o que é bastante óbvio para quem trabalha com tipografia, mas o fato de que também precisam ser organizados em colunas é menos evidente, e se tornou a base do Grid layout e do Bootstrap
    Encontrar um problema de layout, resolvê-lo com tabelas e depois perceber que é preciso um novo recurso que tenha algumas propriedades das tabelas, mas não todas, é uma evolução natural
    O CSS descobriu isso, mas, curiosamente, alguns sistemas, como processadores de texto, não conseguiram unificar elementos sob o modelo de caixa

  • As reclamações do tipo “por que isso ainda é tão difícil?” me parecem bem equivocadas. Como o texto diz, Flexbox resolve de forma intuitiva todos os casos simples de centralização
    Se não dá para resolver com Flexbox, então não é só uma centralização simples, mas algo mais complexo, e não é adequado esperar que a implementação seja extremamente simples

    • Do ponto de vista de quem faz isso há muito tempo, antes do Flexbox era difícil; e mesmo na época em que o Flexbox não tinha 100% de suporte, também era difícil, porque era preciso acompanhar continuamente o uso dos navegadores para decidir se dava para usá-lo
      Hoje há tantas formas de fazer que a complexidade é esmagadora. Muitas vezes se corrige código antigo em vez de criar algo novo, e é preciso avaliar por que o CSS foi escrito de determinada maneira, quais casos de borda podem quebrar, se é seguro corrigir e, quando a situação não é simples, qual solução escolher entre várias
      Mesmo dando uma olhada no texto, não é intuitivo. No Flexbox, a configuração horizontal é justify-content e a vertical é align-items, mas os nomes das propriedades CSS são tantos e tão arbitrários que já nem dá mais para lembrar bem
      No fim, a diferença é entre construir soluções complexas com blocos de construção simples, intuitivos e confiáveis, ou construir soluções complexas com blocos de construção complexos, que se sobrepõem parcialmente e exigem buscas constantes
      Go e Python estão mais próximos do primeiro caso; CSS, do segundo
    • Flexbox é aquilo que eu sempre quis que CSS fosse; por muito tempo não foi assim, até que um dia passou a ser, e tornou-se possível abandonar o suporte a navegadores sem Flexbox. Quase parece a forma final do CSS
      Havia um motivo para as pessoas gostarem do sistema de grid do Bootstrap, e o Flexbox faz tudo aquilo e mais, diretamente dentro do navegador. É difícil exagerar o quanto eu gosto dele
    • Em certos casos, isso já foi razoavelmente difícil, mas nos últimos 10 anos mais ou menos já é um problema resolvido. Ainda há gente falando como se centralizar uma div em CSS fosse algo entre alquimia e ciência de foguetes
      Isso revela que a pessoa não acompanhou as mudanças em CSS tanto quanto acompanhou outras partes do desenvolvimento web, mas ainda assim se sente à vontade para fazer afirmações desse tipo
    • Além disso, o Flexbox é amplamente suportado há mais de 10 anos. O fluxo de comentários aqui é bem fascinante
    • É exatamente isso. Quando estiver apanhando do Flexbox, ajuda dar um passo para trás e resolver uma etapa de cada vez
      Seguir de fora para dentro, do elemento pai para os elementos filhos, torna tudo muito mais fácil. Exige técnica, sim, mas no fundo é mais uma espécie de álgebra flexível