Seleccionar como posicionar um elemento no CSS é por vezes uma escolha sobre quais os efeitos secundários mais aceitáveis.
Posicionamento de layouts no CSS foi outrora uma tarefa muito assustadora, e hacks como o uso de tabelas para todo o layout eram bastante comuns. Ao longo dos anos, a procura de melhores ferramentas de layout levou a um apoio e técnicas cada vez melhores.
Hoje em dia temos opções, e aprender a gerir cada uma destas técnicas é a chave para criar layouts complexos que permanecem fáceis de alterar e flexíveis o suficiente para lidar com vários tamanhos de ecrã.
- Grid
- Flexbox
- Posição
- Floats
Grid
Grid é a mais recente forma de criar layouts na web. É um poderoso conjunto de regras que lhe permite posicionar elementos num plano vertical e horizontal.
Unlike flexbox, a grelha deve ser utilizada para um layout de página maior. O Flexbox pode, e deve, ser colocado dentro de uma disposição da grelha para ajudar a posicionar os componentes que uma disposição da grelha contém. O suporte de browser para grelha é óptimo, excepto para alguns problemas com o Internet Explorer que requerem um prefixo de fornecedor para lidar com uma versão anterior da especificação.
Há muitas propriedades e funções a aprender a fim de implementar a grelha, mas uma vez colocado no lugar, faz maravilhas para manter os seus layouts flexíveis e de manutenção.
Aí está como começar com um layout de grelha na sua página:
<body> <header></header> <nav></nav> <main></main> <footer></footer> </body>
body { display: grid; }
é isso! Ainda não verá quaisquer alterações visuais com esta configuração porque, ao contrário do flexbox, a direcção padrão da disposição é por fila (o que significa que os itens são empilhados verticalmente uns sobre os outros). Mas deu um passo importante na configuração do seu novo layout da grelha – todos os elementos de primeiro nível de body
são agora itens de grelha! Pode agora controlar a sua posição, alinhamento e largura com mais algumas declarações.
Modelos de colunas e linhas
grid-template-rows
e grid-template-columns
são propriedades que definem explicitamente o dimensionamento da faixa de itens da grelha horizontalmente (coluna) ou verticalmente (linha). É possível definir apenas uma direcção ou ambas! É possível definir o tamanho de cada item da grelha com uma variedade de unidades de medida. A ordem dos valores na grelha é aplicada respectivamente à ordem dos elementos no DOM dentro do contentor da grelha (por exemplo, no exemplo abaixo, se o primeiro elemento no corpo for cabeçalho, obterá uma altura de linha de 100px)
body { display: grid; grid-template-rows: 100px 5rem auto 30%; }
P>É possível criar colunas e linhas de grelha implícitas com grid-auto-rows
e grid-auto-columns
que requerem apenas um único valor de medição que se aplicará a todos os elementos directos da grelha.
body { display: grid; grid-auto-rows: 30px; }
Fluxo automático
grid-auto-flow
controla a forma como os elementos são automaticamente colocados na grelha. Esta propriedade é muito semelhante a flex-direction
porque direcciona o empilhamento automático de itens, vertical ou horizontalmente. O padrão é row
, mas um valor de column
pode ser utilizado para que os artigos sejam colocados uns ao lado dos outros ao longo do eixo horizontal. Pode usar grid-auto-flow
sem definir tamanhos para linhas/colunas de modelos se estiver simplesmente à procura de mudar a direcção de empilhamento.
body { display: grid; grid-auto-flow: column; }
Adicionalmente, pode definir um valor de dense
que visa “preencher os buracos” o mais rapidamente possível na grelha. Também pode especificar a direcção da densidade com column dense
ou row dense
. O aviso para utilizar este valor é que pode colocar um item fora de ordem na sua grelha numa tentativa de ocupar qualquer espaço vazio não utilizado.
body { display: grid; grid-auto-flow: row dense; }
A unidade fraccional
Grid também introduz uma nova unidade chamada fracção ou fr
fr
define a proporção que um item deve ocupar em relação ao seu recipiente (pense em cocktail-mixing: 7 partes de gin e 1 parte de vermute seco para fazer um martini). No exemplo abaixo, os dois primeiros artigos da grelha assumirão proporções iguais, enquanto o terceiro artigo assumirá três vezes o tamanho dos dois primeiros; o último artigo terá o mesmo tamanho que os dois primeiros artigos.
body { display: grid; grid-template-rows: 1fr 1fr 3fr 1fr; }
Áreas do modelo de grelha
grid-template-areas
atribui nomes às células da grelha que podem ser referenciadas em elementos infantis para as colocar na grelha. O mais fixe nas áreas da grelha é que está a desenhar a sua grelha com uma declaração (isto também faz com que as consultas multimédia sejam surpreendentemente simples). Cada cadeia separada (dentro de cada bloco de citações) representa uma linha distinta; cada item dentro dessa cadeia representa uma coluna distinta. Pode distribuir um item por várias colunas ou linhas repetindo o nome (as células devem formar-se numa forma rectangular; não é possível desarticulá-las). Este método de nomear áreas da grelha é útil quando se lida com a disposição de páginas de alto nível para a legibilidade numa colcha complexa de elementos.
body { display: grid; grid-template-areas: "head head" "nav main" "foot foot"; }
As áreas de modelo definidas acima precisam de corresponder com elementos particulares utilizando a propriedade grid-area
.
header { grid-area: head; } nav { grid-area: nav; } main { grid-area: main; } footer { grid-area: foot; }
Adicionar um período dentro de uma cadeia de linhas diz ao navegador para renderizar uma célula vazia.
body { display: grid; grid-template-areas: "head ." "nav main" "nav foot"; }
Itens de grelha podem ser organizados em qualquer ordem. Mas desconfie dos problemas de acessibilidade com elementos DOM totalmente reordenados, pois pode ser uma experiência frustrante com leitores de ecrã e separadores.
body { display: grid; grid-template-areas: "foot . ." "main nav nav" "head head head"; }
A função de repetição
Se desejar criar um padrão de medição para os seus itens da grelha (sem escrever o mesmo valor vezes sem conta), pode usar a função de repetição. Esta função requer dois argumentos: número de repetições e largura/altura de cada coluna ou linha. No exemplo abaixo, cada linha da grelha terá a mesma altura em 3 colunas. Isto também definirá o enrolamento dos elementos na sua grelha.
body { display: grid; grid-template-columns: repeat(4, 1fr); }
Um padrão de repetição também pode tomar múltiplos valores de medição para definir um padrão mais complexo.
body { display: grid; grid-template-columns: repeat(2, 100px 1fr); }
É também importante notar que a grelha também introduziu outras funções úteis tais como minmax e fit-content.
Grid gap
Talvez a propriedade mais excitante agora disponível para nós seja grid-gap
, que define as caleiras ou intervalos entre linhas e colunas. Antes desta característica útil existir, a definição das caleiras era uma tarefa árdua que exigia margens negativas e cálculos precisos da largura.
grid-gap
é a abreviatura para row-gap
e column-gap
e toma a maior parte de qualquer valor de medição. Escrever um único valor aplica-se a mesma lacuna tanto para linhas como para colunas; escrever 2 valores separados um ao lado do outro aplica-se a cada lacuna para linhas e colunas respectivamente. Se apenas desejar especificar uma lacuna quer para as colunas quer para as linhas, use row-gap
ou column-gap
com um valor.
body { display: grid; grid-auto-rows: 30px; grid-gap: 2rem; }
Coluna e linha da grelha
Não é necessário fazer todo o posicionamento da grelha dentro do elemento pai; os elementos filhos adquirem algumas propriedades para um maior controlo. grid-area
é usado para definir a posição de um elemento quando se usa grid-template-area
(detalhado numa secção anterior). Se a sua grelha for desenhada com modelo ou linhas/colunas auto, pode posicionar com precisão itens em linhas específicas da grelha. Para tal, pode usar as propriedades grid-column
e/ou grid-row
. Estas são abreviaturas para grid--start
e grid--end
, separadas por uma barra (por exemplo grid-column: grid-column-start / grid-column-end
).
É importante notar que as linhas da grelha começam e terminam no recipiente exterior e são numeradas a partir de 1. Por exemplo, uma grelha com 6 colunas terá 7 linhas de grelha.
body { display: grid; grid-template-columns: repeat(6, 1fr); } header { grid-column: 2 / 4; }
Também podemos dizer a um item de grelha que se espalhe por um certo número de colunas ou linhas com span
.grid { display: grid; grid-template-columns: repeat(6, 1fr); } header { grid-column: span 3; }
Auto-alinhamento
Na secção flexbox, discutiremos o alinhamento dos pais com align-content
justify-content
align-items
e justify-items
(que também se aplicam à grelha). Agora, podemos aplicar algumas propriedades semelhantes aos próprios elementos da criança com align-self
e justify-self
. Ambos tomam valores de cadeia tais como center
start
e end
Align-self
alinha no eixo do bloco, enquanto justify-self
alinha no eixo em linha. O alinhamento toma a quantidade de espaço que o conteúdo dentro do item da grelha ocupa e coloca-o em conformidade.
body { display: grid; height: 100vh; } footer { align-self: end; }
Se quiser simplificar ainda mais, pode utilizar a abreviatura place-self, que define align-self
e justify-self
respectivamente. Pode usar dois valores para colocar um item, ou um valor que é aplicado a ambas as propriedades. Isto faz da centralização de uma brisa.
body { display: grid; height: 100vh; } main { place-self: center; }
O passado e o futuro da grelha
Grid é talvez uma das mais poderosas técnicas de layout disponíveis neste momento na web e foi também uma das adopções mais rápidas de uma especificação pelos principais navegadores. No entanto, se ainda estiver a apoiar o IE, note que ainda pode usar a grelha com um pouco de autoprefixação. Edge, por outro lado, suporta totalmente a grelha sem a necessidade de prefixação.
Looking to the future, é provável que este post seja actualizado para incluir uma funcionalidade chamada sub grelha, que nos permitirá aninhar facilmente grelhas!
Flexbox
Uma boa maneira de lidar com elementos de tamanhos variáveis é usar as novas flexboxproperties introduzidas no CSS3.1. Isto dá-nos muito mais opções para controlar e resolveu alguns dos problemas de longa data no CSS. O suporte do navegador é bom, e com um polifill ou fallback para acelerar o Internet Explorer, está pronto para a utilização da produção.
Eu disse que não íamos falar sobre como funciona o CSS, mas a flexbox ainda é nova e infelizmente a sintaxe é muito confusa. Flexbox é uma ferramenta tão poderosa e substitui tantas outras soluções hacky, pelo que vale a pena dedicar algum tempo a compreender como utilizá-la.
P>Pulemos para dentro. Eis como configurar um elemento para utilizar a flexbox.
<div class="container"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
.container { display: flex; flex-direction: row; }
Configurar o recipiente para display: flex
simplesmente deixa o navegador saber que pretendemos que as crianças utilizem a flexbox para o seu layout. Depois adicionamosflex-direction: row
às crianças para as alinharem horizontalmente, e por defeito terão a mesma largura, a menos que tenham uma largura definida.
Direcção Flex
Direcção Flex permite especificar se os seus elementos devem ser dispostosverticalmente ou horizontalmente. Por omissão, o valor será row
, o que simplesmente lhe garante os elementos horizontalmente. Também pode usar column
para mudar para orientação média.
.container { display: flex; flex-direction: row; }
Keep tendo em mente que a utilização de column
pode afectar a forma como as outras propriedades de flex-direcção dos seus artigos, e para simplificar estaremos a falar principalmente de artigos abouthorizontais porque esse é de longe o caso mais comum de utilização, mas não se esqueça de que esta outra opção de direcção existe.
Flex-wrap
Flex-wrap define se os elementos devem ser forçados a caber numa única linha(no-wrap
, o comportamento por defeito) ou permitidos a manter o seu tamanho normal comwrap
. A maior parte das vezes desejará o comportamento por defeito, mas a sobreposição desta propriedade permitir-lhe-á utilizar as outras propriedades do flexbox sem afectar as larguras.
.container { display: flex; flex-wrap: wrap; }
Quando definido para no-wrap
, os elementos continuarão a ser dimensionados proporcionalmente uns aos outros.Por exemplo, imagine que os itens de uma lista sejam 100px
largo, excepto para o último que é 200px
. Os itens serão redimensionados para caberem no contentor, mas o último item continuará a ser duas vezes mais largo que os outros.
Justify-content
Justify-content determina como espaçar o seu conteúdo na sua linha ou coluna. O valor por defeito é flex-start
, que deixará alinhados os seus itens. Naturalmente, também temos flex-end
para alinhar à direita os itens e center
para os centrar.As coisas ficam mais interessantes com space-between
, que dão espaçamento igual entre os itens mas não nas extremidades, enquanto space-around
dá espaçamento igual também para as extremidades.
.container { display: flex; justify-content: center; }
Isto é melhor utilizado quando os elementos tiverem definido larguras (ou tiverem atingido as suas larguras máximas).
Isto pode ser realmente útil ao alinhar os itens da sua caixa flexível com a sua grelha, sem depender de coisas como flutuadores.
Align-content
Align-content é semelhante a justify-content
, mas controla onde os itens estão no eixo transversal. Eu digo “outro” porque quando se usaflex-direction: row
, então align-items
controla o alinhamento vertical, mas quando se usa flex-direction: column
, é o outro caminho.
Pode alinhar os itens com a linha de base do texto dentro de cada item usandobaseline
. Existe também uma opção para fazer com que cada item se estenda de uma extremidade do eixo para a outra com stretch
.
.container { display: flex; align-items: center; }
Podemos usar align-items: stretch
para resolver o problema das “colunas de altura igual” que tem atormentado os layouts do CSS desde o início. Também pode definir ambosjustify-content
e align-items
a center
para centrar os seus itens no centro do contentor, o que é realmente útil para coisas como áreas de heróis e páginas de splash.
Existem várias outras propriedades que são utilizadas com menos frequência, mas que poderá achar úteis.
Align-items
Align-items afecta as linhas de conteúdo e onde devem estar dentro do seu contentor. Pode ver abaixo que os itens em cada linha mantêm as suas alturas normais (a menos que esteja a utilizar stretch
).
.container { display: flex; align-content: stretch; }
Mais algumas propriedades
Há também um número de propriedades de flexbox para os artigos no contentor.Estas são bastante mais fáceis de compreender do que as propriedades dos pais e, felizmente, existe uma abreviatura útil que podemos utilizar para facilitar esta tarefa.
.list-item { flex: <flex-grow> <flex-shrink> <flex-basis>; }
-
flex-grow: <integer>
: Isto proporciona uma outra forma de dar aos seus artigos flexíveis larguras diferentes. Se definir todos os elementos da sua criança paraflex-grow: 1
, mas definir a última criança paraflex-grow: 2
, ela será duas vezes mais larga que os seus irmãos. -
flex-shrink: <number>
: Determina como o elemento irá encolher quando o contentor não for suficientemente largo para que os itens mantenham a sua largura natural. Se o último elemento estiver definido paraflex-shrink: 2
enquanto os seus irmãos estão definidos paraflex-shrink: 1
, irá encolher o dobro do que os seus irmãos. -
flex-basis: <size>
: O que devemos considerar como sendo o tamanho natural do item. Isto pode ser considerado como o “ponto de ruptura” em que as propriedades de crescimento e encolhimento são desencadeadas.
Ordem controla a ordem em que o item aparece no contentor. Negativenumbers são aceites e aparecerão antes do que normalmente seria o primeiro elemento.
Align-self tem todas as mesmas opções que align-items
, mas permite controlar como os elementos individuais estão alinhados. Por exemplo, os irmãos podem ser definidos paraflex-start
, mas pode escolher um item para definir para flex-end
.
Provavelmente não estará a utilizar todos estes itens juntos, mas tal monstruosidade pareceria assim:
.container { align-items: flex-start; display: flex; height: 40em; } .item { flex: 1 1 2em; } .item:nth-child(3) { align-self: flex-end; flex: 2 10 5em; order: -1; }
Recursos de aprendizagem
Flexbox pode ser uma coisa difícil de embrulhar a sua cabeça, especialmente se estiver habituado aos caprichos dos layouts tradicionais de CSS. Um site como o Codepen é uma boa maneira de aprender é apenas para experimentar e ver o que se pode arranjar.
Se não tiver a certeza de como utilizaria o Flexbox numa aplicação do mundo real,Solucionado pelo Flexbox é um grande recurso criado pela Mozilla que apresenta muitas ideias práticas.
Posição
Posicionamento dá-nos um método de layout completamente diferente. O valor padrão é static
, e faz com que o elemento se comporte normalmente.
usando position: relative
permite especificar um offset com top
bottom
left
, e right
.
.logo { position: relative; left: 1em; top: 1em; }
Isto pode ser útil para fazer uma simples compensação sem usar algo como margin
,mas torna-se realmente poderoso quando contém uma criança com position:absolute
.
Posição absoluta
Absoluto posicionamento baseia a posição dos elementos em relação ao elemento parente mais próximo que tem position: relative
set. Se não encontrar um, será relativo ao documento.
.hero { position: relative; } .hero-icon { position: absolute; left: 20px; top: 10%; }
Posicionamento absoluto não deve ser utilizado para colocar colunas de conteúdo. Porque os elementos são removidos do fluxo de documentos, o que significa que cada vez que adicionar conteúdo a uma secção, poderá ter de ajustar os tamanhos de outras secções à mão, e isso torna o design reactivo muito mais incómodo do que precisa de ser. Reserve o posicionamento absoluto para obter esses pequenos elementos de design exactamente onde quer que eles estejam. Como regra geral, se um elemento pode ser posicionado de forma simples usando flutuadores ou uma alteração aos estilos display
, é provavelmente melhor evitar o posicionamento absoluto.
Centrar usando posição absoluta
Algo que pode ser muito útil, mas muitos principiantes são os centragens com posicionamento absoluto. Se o seu elemento tem um tamanho definido, é apenas uma questão de compensação usando margens. Tomemos o último exemplo, mas centralizemos o ícone tanto horizontal como verticalmente. Para centrar um elemento usando posicionamento absoluto, basta seguir estes passos:
- Adicionar
left: 50%
ao elemento que pretende centrar. Notará que isto alinha a margem esquerda do elemento criança com a linha de 50% do elemento pai. - Adicionar uma margem esquerda negativa que é igual a metade da largura do elemento.Isto leva-nos de volta à marca de meio caminho.
- li>Next, faremos um processo semelhante para o eixo vertical. Adicionar
top: 50%
à criança - e depois adicionar uma margem superior negativa igual a metade da sua altura.
Isto significa que mesmo que o contentor possa mudar de tamanho, o elemento centrado ficará exactamente onde o queremos. O CSS resultante deve ter a seguinte aparência:
.container { position: relative; } .centered-element { height: 100px; width: 100px; position: absolute; left: 50%; margin-left: -50px; top: 50%; margin-top: -50px; }
Posição fixa
Posicionamento fixo funciona como absolute
, mas é sempre relativo ao viewport e não ao documento e permanecerá no lugar quando o utilizador se desloca. Isto pode fazer com que a sua aplicação se sinta mais como uma aplicação nativa, com um cabeçalho fixo ou navegação lateral, ou para qualquer elemento que queira manter em fácil acesso. Tal como o posicionamento absoluto, os elementos fixos serão removidos do fluxo do documento, pelo que poderá ter de adicionar acolchoamento num elemento por baixo deles para se certificar de que o seu outro conteúdo ainda será visível.
Posição pegajosa
P>Posicionamento pegajoso é o mais recente do grupo. Existem alguns grandes artigos sobre como utilizá-lo, bem como alternativas javascript, o que não deve ser confundido com a técnica sempre popular do rodapé pegajoso, que também merece uma menção especial.
Índice Z
A propriedade da posição dá-nos a vantagem de poder especificar o índicez dos nossos elementos. Se voltarmos à nossa metáfora de ver elementos aspieces de papel, a definição da propriedade z-index
permite-nos especificar se o nosso papel está acima ou abaixo das outras peças. Um número mais alto aparecerá por cima, e um número mais alto aparecerá por baixo. Também pode usar um número negativo, que pode fazer o elemento aparecer atrás do pai (ou mesmo atrás dodocumento por completo)! Isto pode levar a uma espécie de corrida armamentista com números cada vez mais altos para garantir que um elemento se senta sempre em cima. Isto pode tornar-se bastante administrável e é melhor usar o posicionamento e os índices z de forma conservadora.
Flutuadores
Flutuadores são a técnica de disposição mais comummente utilizada no CSS, mas podem ser frustrantes se não se souber como afectam os seus elementos vizinhos. Quando se estiliza um elemento com float: left
, os seguintes elementos irão refluir. O fluxo do documento é apenas a ordem do conteúdo e como os elementos se organizam à volta uns dos outros. Se o elemento flutuado não tiver a largura determinada, irá colapsar até à largura do conteúdo. Se o elemento seguinte for mais estreito do que o espaço restante, deslocar-se-á para a direita. Tenha em mente que os elementos definidos para display: block
terão de ter uma largura definida ou permanecerão na sua própria linha.
Pode evitar que um elemento volte a fluir dando-lhe uma clear
propriedade na sua folha de estilos. As opções incluem clear: both
clear: left
(que ainda permitirá o refluxo dos seguintes elementos com float: right
), e clear: right
(que faz o contrário). Também pode usar clear: none
para anular o comportamento por defeito.
porque as crianças flutuantes causarão o colapso dos seus elementos pais, sentir-se-á tentado a criar novos elementos apenas para adicionar clear: both
e prevenir este comportamento. Enquanto isso funciona, queremos manter o nosso markupsemântico, pelo que isto deve ser feito apenas usando CSS, se possível. Utilizando um::after
pseudo-elemento, pode-se criar um clearfix:
.container::after { clear: both; content: ""; display: table; }
Usando um pré-processador como o Bourbon, é fácil adicionar isto como uma mistura de Sass:
.container { @include clearfix; }
Floats funcionam melhor para recipientes grandes, mas podem não funcionar tão bem para textelementos, uma vez que será difícil de alinhar. Poderá descobrir que utilizar display:inline-block
é melhor para estas situações.