Layout

Podcast do CSS - 009: Layout

Imagine que você está trabalhando como desenvolvedor e um colega designer entrega o design de um site novo. O design tem todos os tipos de layouts e composições interessantes: layouts bidimensionais que consideram a largura e a altura da janela de visualização, além de layouts que precisam ser fluidos e flexíveis. Como decidir a melhor maneira de definir o estilo com CSS?

O CSS nos oferece várias maneiras de resolver problemas de layout: em um eixo horizontal, um eixo vertical ou até mesmo ambos. Escolher o método de layout certo para um contexto pode ser difícil e, muitas vezes, você pode precisar de mais de um método de layout para resolver o problema. Para ajudar nisso, nos módulos a seguir, você vai aprender sobre os recursos exclusivos de cada mecanismo de layout CSS para informar essas decisões.

Layout: uma breve história

No início da Web, designs mais complexos do que um documento simples foram apresentados com elementos <table>. A separação do HTML dos estilos visuais ficou mais fácil quando o CSS foi amplamente adotado pelos navegadores no final dos anos 90. O CSS abriu as portas para que os desenvolvedores pudessem alterar completamente a aparência de um site sem nunca tocar em HTML. Esse novo recurso inspirou projetos como The CSS Zen Garden, que foi criado para demonstrar o poder do CSS e incentivar mais desenvolvedores a aprender sobre ele.

O CSS evoluiu à medida que nossas necessidades de web design e tecnologia de navegador aumentaram. Leia como o layout CSS e nossa abordagem de layout evoluiu ao longo do tempo neste artigo de Rachel Andrew.

Um cronograma que mostra como o CSS evoluiu ao longo dos anos, de 1996 a 2021

Layout: o presente e o futuro

O CSS moderno tem ferramentas de layout excepcionalmente poderosas. Temos sistemas dedicados para layout e vamos fazer uma análise geral do que temos à nossa disposição, antes de nos aprofundarmos no Flexbox e no Grid nos próximos módulos.

Noções básicas sobre a propriedade display

A propriedade display faz duas coisas. A primeira coisa que ele faz é determinar se a caixa aplicada para atuar como inline ou de bloco.

.my-element {
  display: inline;
}

Os elementos inline se comportam como palavras em uma frase. Elas ficam lado a lado na direção in-line. Elementos como <span> e <strong>, normalmente usados para definir o estilo de partes do texto dentro de elementos que contêm elementos, como um <p> (parágrafo), são inline por padrão. Eles também preservam os espaços em branco ao redor.

Diagrama mostrando todos os diferentes tamanhos de uma caixa e onde cada seção de dimensionamento começa e termina

Não é possível definir uma largura e altura explícitas em elementos inline. Qualquer margem e preenchimento no nível do bloco serão ignorados pelos elementos ao redor.

.my-element {
    display: block;
}

Os elementos de bloco não ficam lado a lado. Ele cria uma nova linha para si. A menos que tenha sido modificado por outro código CSS, um elemento de bloco é expandido para o tamanho da dimensão in-line, incluindo a largura total no modo de escrita horizontal. A margem em todos os lados de um elemento de bloco será respeitada.

.my-element {
    display: flex;
}

A propriedade display também determina como os filhos de um elemento vão se comportar. Por exemplo, definir a propriedade display como display: flex transforma a caixa em uma caixa no nível do bloco e também converte os filhos em itens flexíveis. Isso ativa as propriedades flexíveis que controlam o alinhamento, a ordenação e o fluxo.

Flexbox e grade

Há dois mecanismos principais de layout que criam regras de layout para vários elementos: flexbox e grade. Elas compartilham semelhanças, mas são projetadas para resolver diferentes problemas de layout.

Flexbox

.my-element {
    display: flex;
}

O Flexbox é um mecanismo de layout para layouts unidimensionais. Layout em um único eixo, horizontal ou verticalmente. Por padrão, o flexbox vai alinhar os filhos do elemento um ao lado um do outro, na direção inline, e esticá-los na direção do bloco, para que tenham a mesma altura.

Os itens vão permanecer no mesmo eixo e não serão agrupados quando ficarem sem espaço. Em vez disso, eles vão tentar se comprimir na mesma linha um do outro. Esse comportamento pode ser mudado usando as propriedades align-items, justify-content e flex-wrap.

O Flexbox também converte os elementos filhos em itens flexíveis, o que significa que é possível escrever regras sobre como eles se comportam dentro de um contêiner flexível. É possível mudar o alinhamento, a ordem e a justificativa em um item individual. Também é possível mudar a forma como ela diminui ou aumenta usando a propriedade flex.

.my-element div {
    flex: 1 0 auto;
}

A propriedade flex é uma abreviação de flex-grow, flex-shrink e flex-basis. Você pode expandir o exemplo acima desta forma:

.my-element div {
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: auto;
}

Os desenvolvedores fornecem essas regras de baixo nível para sugerir a um navegador como o layout deve se comportar quando é desafiado pelas dimensões do conteúdo e da janela de visualização. Isso o torna um mecanismo muito útil para o web design responsivo.

Grade

.my-element {
    display: grid;
}

A grade é semelhante ao flexbox de muitas maneiras, mas foi projetada para controlar layouts de vários eixos em vez de layouts de eixo único (espaço vertical ou horizontal).

A grade permite que você programe regras de layout em um elemento que tenha display: grid e introduz alguns novos primitivos para estilo de layout, como as funções repeat() e minmax(). Uma unidade de grade útil é a fr, que é uma fração do espaço restante. É possível criar grades tradicionais de 12 colunas, com uma lacuna entre cada item, com três propriedades CSS:

.my-element {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

O exemplo acima mostra um layout de eixo único. Enquanto o flexbox trata principalmente os itens como um grupo, a grade oferece controle preciso sobre o posicionamento em duas dimensões. Podemos definir que o primeiro item da grade ocupa 2 linhas e 3 colunas:

.my-element :first-child {
  grid-row: 1/3;
  grid-column: 1/4;
}

As propriedades grid-row e grid-column instruem o primeiro elemento na grade a abranger o início da quarta coluna, da primeira coluna, e depois a extensão até a terceira linha, a partir da primeira linha.

Layout de fluxo

Se não estiver usando grade ou flexbox, seus elementos serão exibidos no fluxo normal. Existem diversos métodos de layout que podem ser usados para ajustar o comportamento e a posição dos itens no fluxo normal.

Bloqueio inline

Lembra como os elementos ao redor não respeitam a margem do bloco e o preenchimento em um elemento in-line? Com inline-block, você pode fazer isso acontecer.

p span {
    display: inline-block;
}

O uso de inline-block oferece uma caixa que tem algumas das características de um elemento no nível do bloco, mas ainda flui inline com o texto.

p span {
    margin-top: 0.5rem;
}

Variações

Se você tivesse uma imagem dentro de um parágrafo de texto, não seria útil que esse texto envolvia essa imagem como você veria em um jornal? É possível fazer isso com flutuações.

img {
    float: left;
    margin-right: 1em;
}

A propriedade float instrui um elemento a "flutuar" para a direção especificada. A imagem neste exemplo é instruída a flutuar para a esquerda, o que permite que elementos irmãos se "envolvam" em torno dela. Você pode instruir um elemento para exibir left, right ou inherit em ponto flutuante.

Layout de várias colunas

Se você tiver uma lista muito longa de elementos, como uma lista de todos os países do mundo, isso pode resultar em muito tempo de rolagem e desperdício de tempo do usuário. Também pode criar excesso de espaços em branco na página. Com CSS de várias colunas, é possível dividir em várias para ajudar a resolver esses dois problemas.

<h1>All countries</h1>
<ul class="countries">
  <li>Argentina</li>
  <li>Aland Islands</li>
  <li>Albania</li>
  <li>Algeria</li>
  <li>American Samoa</li>
  <li>Andorra</li>
  …
</ul>
.countries {
    column-count: 2;
    column-gap: 1em;
}

Isso divide automaticamente essa longa lista em duas colunas e adiciona uma lacuna entre as duas colunas.

.countries {
    width: 100%;
    column-width: 260px;
    column-gap: 1em;
}

Em vez de definir o número de colunas em que o conteúdo é dividido, você também pode definir uma largura mínima desejada usando column-width. À medida que mais espaço é disponibilizado na janela de visualização, mais colunas são criadas automaticamente e, à medida que o espaço é reduzido, as colunas também são reduzidas. Isso é muito útil em contextos de web design responsivo.

Posicionamento

Por último, nesta visão geral dos mecanismos de layout, é o posicionamento. A propriedade position muda a forma como um elemento se comporta no fluxo normal do documento e como ele se relaciona a outros elementos. As opções disponíveis são relative, absolute, fixed e sticky, com o valor padrão static.

.my-element {
  position: relative;
  top: 10px;
}

Esse elemento é deslocado 10 px para baixo com base na posição atual no documento, já que está posicionado em relação a si mesmo. Adicionar position: relative a um elemento também o torna o bloco contêiner de qualquer elemento filho com position: absolute. Isso significa que o filho será reposicionado nesse elemento específico, em vez do pai relativo superior, quando tiver uma posição absoluta aplicada a ele.

.my-element {
  position: relative;
  width: 100px;
  height: 100px;
}

.another-element {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 50px;
    height: 50px;
}

Quando você define position como absolute, o elemento sai do fluxo de documentos atual. Isso significa duas coisas:

  1. Você pode posicionar esse elemento onde quiser, usando top, right, bottom e left no pai relativo mais próximo.
  2. Todo o conteúdo ao redor de um elemento absoluto reflui para preencher o espaço restante deixado por esse elemento.

Um elemento com um valor position de fixed se comporta de maneira semelhante a absolute, com o pai sendo o elemento raiz <html>. Os elementos de posição fixa ficam fixados no canto superior esquerdo com base nos valores top, right, bottom e left que você definir.

É possível alcançar os aspectos ancorados e fixos de fixed e os aspectos mais previsíveis que respeitam o fluxo de documentos de relative usando sticky. Com esse valor, conforme a janela de visualização rola além do elemento, ele permanece fixo nos valores top, right, bottom e left que você definiu.

Conclusão

Há muitas opções e flexibilidade no layout CSS. Para saber mais sobre o poder do Flexbox e da Grid do CSS, continue nos próximos módulos.

Teste seu conhecimento

Testar seus conhecimentos sobre layout

Quais são as duas coisas que a propriedade display faz?

Determina inline, block ou none.
O mecanismo de layout precisa saber se a caixa tem largura total ou não e precisa de uma nova linha.
Determina o frame do layout de grade.
A propriedade de exibição pode definir a exibição como grade, mas não tem nada a ver com um frame de layout.
Determina como os filhos devem se comportar.
O Flexbox e a grade têm opiniões e novos recursos para os filhos.
Determina se a caixa deve rolar.
Essa é a propriedade overflow.

Para dividir vários parágrafos em colunas, qual propriedade de CSS é melhor para essa tarefa?

display: grid
Embora a grade possa colocar vários parágrafos em colunas, essas colunas seriam suas próprias colunas, não fluindo juntas de um para o próximo.
column-count
Os parágrafos vão do final de uma coluna para o início da próxima, como em uma revista ou jornal.
display: flex
Embora a flexibilidade possa colocar vários parágrafos em colunas, essas colunas seriam suas próprias colunas, não fluindo juntos de um para o próximo como é necessário.
float
Tente de novo.

O que significa quando um bloco está fora de fluxo?

Está preso na beira do rio.
Aqui, o contexto é o CSS, não a geografia.
Ela recebeu um valor de posição top ou left.
Ter essas propriedades sozinhas não tira uma caixa do fluxo.
Ele não é mais posicionado com base nas posições dos irmãos.
Uma caixa com position: absolute, por exemplo, agora é posicionada com as coordenadas x e y com base no bloco que o contém, e não na ordem com outros elementos irmãos

O Flexbox e Grid encapsulam os filhos por padrão?

Verdadeiro
Ele precisa ser ativado com flex-wrap: wrap ou repeat(auto-fit, 30ch).
Falso
O flexbox e o Grid têm recursos de wrapper especiais que precisam de mais estilos para serem aplicados.