Considere o eixo principal e o eixo transversal de um contêiner flexível:
Fonte: W3C
Para alinhar itens flexíveis ao longo do eixo principal, existe uma propriedade:
Para alinhar itens flexíveis ao longo do eixo transversal, existem três propriedades:
Na imagem acima, o eixo principal é horizontal e o eixo transversal é vertical. Essas são as direções padrão de um contêiner flexível.
No entanto, essas instruções podem ser facilmente trocadas com a flex-direction
propriedade.
/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;
/* main axis is vertical, cross axis is horizontal */
flex-direction: column;
flex-direction: column-reverse;
(O eixo transversal é sempre perpendicular ao eixo principal.)
Meu argumento ao descrever como os eixos funcionam é que não parece haver nada de especial em nenhuma das direções. Eixo principal, eixo transversal, ambos são iguais em termos de importância e flex-direction
facilitam a alternância.
Então, por que o eixo transversal obtém duas propriedades de alinhamento adicionais?
Por que align-content
e são align-items
consolidados em uma propriedade para o eixo principal?
Por que o eixo principal não obtém uma justify-self
propriedade?
Cenários em que essas propriedades seriam úteis:
colocando um item flexível no canto do contêiner flexível
#box3 { align-self: flex-end; justify-self: flex-end; }
alinhando um grupo de itens flexíveis à direita (
justify-content: flex-end
), mas com o primeiro item alinhado à esquerda (justify-self: flex-start
)Considere uma seção de cabeçalho com um grupo de itens de navegação e um logotipo. Com
justify-self
o logotipo pode ser alinhado à esquerda, enquanto os itens de navegação ficam à direita, e tudo se ajusta suavemente ("flexiona") para diferentes tamanhos de tela.em uma linha de três itens flexíveis, afixe o item do meio ao centro do contêiner (
justify-content: center
) e alinhe os itens adjacentes às bordas do contêiner (justify-self: flex-start
ejustify-self: flex-end
).Observe que os valores
space-around
espace-between
ajustify-content
propriedade não manterão o item do meio centralizado sobre o contêiner se os itens adjacentes tiverem larguras diferentes.
No momento da redação deste documento, não há menção justify-self
ou justify-items
na especificação do flexbox .
No entanto, no Módulo de alinhamento de caixas CSS , que é a proposta inacabada do W3C de estabelecer um conjunto comum de propriedades de alinhamento para uso em todos os modelos de caixas, existe o seguinte:
Fonte: W3C
Você notará isso justify-self
e justify-items
está sendo considerado ... mas não para o flexbox .
Terminarei reiterando a questão principal:
Por que não existem propriedades "justify-items" e "justify-self"?
fonte
justify-self
trabalhar para um item flexível? Suponha que você tenha os itens a, b, c, d com espaço extra para distribuir em torno deles, e o contêiner flex tenhajustify-content: space-between
, portanto eles acabam como | abcd |. O que significaria adicionar, por exemplo,justify-self: center
ou 'justificar-se: flex-end', apenas ao item 'b' lá? Para onde você esperaria que fosse? (Eu vejo algumas demos em uma das respostas aqui, mas eu não vejo uma forma clara que ele iria trabalhar em geral.)justify-content: flex-start
, para que os itens estão lotados no início como | abcd | O que você espera que ele faça, se você colocar.justify-self: [anything]
Do item 'b' lá?)justify-self
trabalhar para um item flexível? Eu diria que não tão diferente do que asauto
margens já funcionam em itens flex. No seu segundo exemplo, ojustify-self: flex-end
item d o moveria para a extremidade. Isso por si só seria um ótimo recurso, que asauto
margens já podem fazer. Postei uma resposta com uma demonstração.justify-content
ejustify-self
são especificados, para que casos com conflitos (como os cenários perguntei sobre) são definidos de forma clara e sensata. Como observei na minha resposta aqui,{justify|align}-self
trata-se de alinhar itens dentro de uma caixa maior, dimensionada independentemente do{justify|align}-self
valor - e não existe essa caixa, no eixo principal, para alinhar um item flexível.justify-self
ejustify-content
interage, nos casos em que elas conflitam (como os cenários apresentados). As margens automáticas simplesmente não interagemjustify-content
- elas roubam todo o espaço da embalagem antes que vocêjustify-content
possa usá-lo. Portanto, as margens automáticas não são realmente um bom análogo de como isso funcionaria.Respostas:
Métodos para alinhar itens flexíveis ao longo do eixo principal
Como afirmado na pergunta:
A pergunta então pergunta:
Uma resposta pode ser: porque eles não são necessários.
A especificação flexbox fornece dois métodos para alinhar itens flexíveis ao longo do eixo principal:
justify-content
propriedade da palavra-chave eauto
margensjustificar conteúdo
o
justify-content
propriedade alinha itens flexíveis ao longo do eixo principal do contêiner flexível.É aplicado ao contêiner flexível, mas afeta apenas itens flexíveis.
Existem cinco opções de alinhamento:
flex-start
~ Os itens flexíveis são compactados no início da linha.flex-end
~ Os itens flexíveis são compactados no final da linha.center
~ Os itens flexíveis são compactados em direção ao centro da linha.space-between
~ Os itens flexíveis são espaçados igualmente, com o primeiro item alinhado a uma borda do contêiner e o último item alinhado à borda oposta. As bordas usadas pelos primeiros e últimos itens dependeflex-direction
e modo de escrita (ltr
ourtl
).space-around
~ O mesmo quespace-between
com espaços de meio tamanho nas duas extremidades.Margens automáticas
Com
auto
margens , os itens flexíveis podem ser centralizados, espaçados ou agrupados em subgrupos.Diferentemente
justify-content
, aplicado ao contêiner flexível, asauto
margens continuam nos itens flexíveis.Eles trabalham consumindo todo o espaço livre na direção especificada.
Alinhar o grupo de itens flexíveis à direita, mas o primeiro item à esquerda
Cenário da pergunta:
Outros cenários úteis:
Coloque um item flexível no canto
Cenário da pergunta:
Centralize um item flexível na vertical e na horizontal
margin: auto
é uma alternativa parajustify-content: center
ealign-items: center
.Em vez deste código no contêiner flex:
Você pode usar isso no item flexível:
Essa alternativa é útil ao centralizar um item flexível que transborda o contêiner .
Centralize um item flexível e centralize um segundo item flexível entre o primeiro e a borda
Um contêiner flexível alinha itens flexíveis distribuindo espaço livre.
Portanto, para criar equilíbrio igual , para que um item do meio possa ser centralizado no contêiner com um único item ao lado, um contrapeso deve ser introduzido.
Nos exemplos abaixo, os terceiros itens flexíveis invisíveis (casas 61 e 68) são introduzidos para equilibrar os itens "reais" (casas 63 e 66).
Obviamente, esse método não é ótimo em termos de semântica.
Como alternativa, você pode usar um pseudoelemento em vez de um elemento DOM real. Ou você pode usar o posicionamento absoluto. Todos os três métodos são abordados aqui: Itens flexíveis de alinhamento central e inferior
NOTA: Os exemplos acima funcionarão apenas - em termos de verdadeira centralização - quando os itens mais externos tiverem altura / largura iguais. Quando os itens flexíveis tiverem comprimentos diferentes, consulte o próximo exemplo.
Centralizar um item flexível quando itens adjacentes variarem de tamanho
Cenário da pergunta:
Conforme observado, a menos que todos os itens flexíveis tenham largura ou altura iguais (dependendo
flex-direction
), o item do meio não poderá ser verdadeiramente centralizado. Esse problema justifica umajustify-self
propriedade (projetada para lidar com a tarefa, é claro).Mostrar snippet de código
Aqui estão dois métodos para resolver esse problema:
Solução 1: posicionamento absoluto
A especificação flexbox permite o posicionamento absoluto de itens flex . Isso permite que o item do meio seja perfeitamente centralizado, independentemente do tamanho de seus irmãos.
Lembre-se de que, como todos os elementos absolutamente posicionados, os itens são removidos do fluxo de documentos . Isso significa que eles não ocupam espaço no contêiner e podem se sobrepor aos irmãos.
Nos exemplos abaixo, o item do meio é centralizado com posicionamento absoluto e os itens externos permanecem em fluxo. Mas o mesmo layout pode ser obtido de maneira inversa: centralize o item do meio
justify-content: center
e posicione absolutamente os itens externos.Solução 2: recipientes flexíveis aninhados (sem posicionamento absoluto)
Veja como funciona:
.container
) de é um contêiner flexível..box
) filho agora é um item flexível..box
item é fornecidoflex: 1
para distribuir o espaço do contêiner igualmente.justify-content: center
.span
elemento é um item flexível centralizado.auto
margens flexíveis para deslocar os botões externos paraspan
a esquerda e direita.Você também pode renunciar
justify-content
e usarauto
margens exclusivamente.Mas
justify-content
pode funcionar aqui porque asauto
margens sempre têm prioridade. Das especificações:justify-content: space-same (conceito)
Voltando a
justify-content
um minuto, aqui está uma idéia para mais uma opção.space-same
~ Um híbrido despace-between
espace-around
. Os itens flexíveis são espaçados uniformemente (comospace-between
), exceto que, em vez de espaços de meio tamanho nas duas extremidades (comospace-around
), há espaços em tamanho total nas duas extremidades.Esse layout pode ser alcançado com
::before
e::after
pseudoelementos no contêiner flex.(crédito: @oriol para o código e @crl para o rótulo)
ATUALIZAÇÃO: Os navegadores começaram a implementar
space-evenly
, o que faz o acima. Consulte esta publicação para obter detalhes: Espaço igual entre itens flexíveisPLAYGROUND (inclui código para todos os exemplos acima)
fonte
justify-content
eauto
margens. Para o outro lado da moeda - o eixo transversal ,align-items
,align-self
ealign-content
- veja este post: stackoverflow.com/q/42613359/3597276justify-self
propriedade ... asauto
margens são úteis, masjustify-self: center
seriam ideais. A maneira de resolver o problema que você apresentou seria criar itens duplicados invisíveis no lado oposto. Veja minha resposta aqui: stackoverflow.com/q/38948102/3597276space-same
conceito é real agora. É chamadospace-evenly
, mas ele só é suportado pelo Firefox no momento: developer.mozilla.org/en-US/docs/Web/CSS/justify-contentspace-evenly
em outras respostas: stackoverflow.com/q/45134400/3597276space-evenly
era suportado no Chrome 57-60, mas apenas para o layout de grade. Foi um bug que foi corrigido e, desde o Chrome 61, ele também é compatível com o Flexbox. Além disso, não é o caminho a imitá-lo sem pseudo-elementos:.item { margin-right: auto } .item:first-child { margin-left: auto }
.Sei que isso não é uma resposta, mas gostaria de contribuir com esse assunto para o que vale a pena. Seria ótimo se eles pudessem liberar o
justify-self
flexbox para torná-lo realmente flexível.É minha convicção que, quando houver vários itens no eixo, a maneira mais lógica de
justify-self
se comportar é alinhar-se aos vizinhos (ou arestas) mais próximos, conforme demonstrado abaixo.Eu realmente espero que o W3C tome conhecimento disso e pelo menos o considere. =)
Dessa forma, você pode ter um item realmente centralizado, independentemente do tamanho da caixa esquerda e direita. Quando uma das caixas atinge o ponto da caixa central, simplesmente a empurra até que não haja mais espaço para distribuir.
A facilidade de criar layouts impressionantes é interminável, dê uma olhada neste exemplo "complexo".
fonte
justify-self
ejustify-items
.auto
margens não são um substituto completojustify-self
. Tomei o cuidado de redigir meu comentário anterior dizendo que asauto
margens cobrirão alguns dos casos de uso . Como você observou, ele não pode centralizar um item no local quando itens adjacentes são de tamanhos diferentes. No entanto, fornece mais opções para alinhar itens flexíveis. Quando comecei a aprender sobre o flexbox, pensei quejustify-content
itens espaçadores invisíveis eram a única maneira.Isso foi solicitado na lista de estilos www, e Tab Atkins (editor de especificações) forneceu uma resposta explicando o porquê . Vou elaborar um pouco aqui.
Para começar, vamos assumir inicialmente que nosso contêiner flex é uma linha (
flex-wrap: nowrap
). Nesse caso, há claramente uma diferença de alinhamento entre o eixo principal e o eixo transversal - há vários itens empilhados no eixo principal, mas apenas um item empilhado no eixo transversal. Portanto, faz sentido ter um "auto-alinhamento" personalizável por item no eixo cruzado (já que cada item é alinhado separadamente, por si só), enquanto não faz sentido no eixo principal (pois lá, o itens são alinhados coletivamente).Para caixa flexível de várias linhas, a mesma lógica se aplica a cada "linha flexível". Em uma determinada linha, os itens são alinhados individualmente no eixo transversal (já que há apenas um item por linha, no eixo transversal), versus coletivamente no eixo principal.
Aqui está outra maneira de expressar isso: então, todas as propriedades
*-self
e*-content
são sobre como distribuir espaço extra em torno das coisas. Mas a principal diferença é que as*-self
versões são para casos em que há apenas uma coisa nesse eixo , e as*-content
versões são para quando há potencialmente muitas coisas nesse eixo . Os cenários de uma coisa versus muitas coisas são tipos diferentes de problemas e, portanto, eles têm tipos diferentes de opções disponíveis - por exemplo, os valoresspace-around
/space-between
fazem sentido para*-content
, mas não para*-self
.SO: No eixo principal de uma caixa flexível, há muitas coisas para distribuir espaço. Portanto, uma
*-content
propriedade faz sentido lá, mas não uma*-self
propriedade.Por outro lado, no eixo transversal, temos
*-self
uma*-content
propriedade e uma . Um determina como distribuiremos o espaço em torno das muitas linhas flexíveis (align-content
), enquanto o outro (align-self
) determina como distribuir o espaço em torno dos itens individuais flexíveis no eixo transversal, dentro de uma determinada linha flexível.(Estou ignorando
*-items
propriedades aqui, pois elas simplesmente estabelecem padrões para*-self
.)fonte
justify-self
problema pode ser em um eixo com vários itens em oposição a um item. No entanto, eu realmente espero que eles estudem mais, em uma situação de vários itens, como sejustify-self
comportaria, porque há algumas situações em que isso pode ser realmente útil. Por exemplo ( stackoverflow.com/questions/32378953/… ).justify-self
.*-self
é o caso de casos em que só temos uma coisa a alinhar, enquanto que os*-content
casos em que temos muitas coisas a alinhar. Isso torna um pouco mais claro?auto
margens, também parte da especificação, permitem o alinhamento * com vários itens na linha. Não há razão clara para que as propriedades da palavra-chave também não possam.Sei que isso não usa o flexbox, mas, para o simples caso de uso de três itens (um à esquerda, um no centro e outro à direita), isso pode ser feito facilmente usando
display: grid
o pai,grid-area: 1/1/1/1;
os filhos e ojustify-self
posicionamento dessas crianças.fonte
Acabei de encontrar minha própria solução para esse problema, ou pelo menos meu problema.
Eu estava usando em
justify-content: space-around
vez dejustify-content: space-between;
.Dessa forma, os elementos finais permanecerão na parte superior e inferior e você poderá ter margens personalizadas, se desejar.
fonte