css - guide - flexbox guia origamid




No CSS Flexbox, por que não existem propriedades “justificar itens” e “justificar-se”? (4)

Métodos para alinhar itens flexíveis ao longo do eixo principal

Como afirmado na pergunta:

Para alinhar os itens flexíveis ao longo do eixo principal, existe uma propriedade: justify-content

Para alinhar itens flexíveis ao longo do eixo cruzado, existem três propriedades: align-content , align-items .

A pergunta então pergunta:

Por que não há justify-items justify-self propriedades justify-self ?

Uma resposta pode ser: porque eles não são necessários.

A especificação do flexbox fornece dois métodos para alinhar itens flexíveis ao longo do eixo principal:

  1. A propriedade de palavra justify-content chave justify-content e
  2. margens auto

justificar-conteúdo

A propriedade justify-content alinha os itens flexíveis ao longo do eixo principal do contêiner flexível.

Ele é aplicado ao contêiner de flexão, mas afeta apenas os itens flexíveis.

Existem cinco opções de alinhamento:

  • flex-start ~ Os itens Flex são colocados no início da linha.

  • flex-end ~ Os itens Flex são colocados no final da linha.

  • center ~ Os itens Flex são colocados na direção do centro da linha.

  • space-between itens Flex são uniformemente espaçados, com o primeiro item alinhado a uma borda do contêiner e o último item alinhado à borda oposta. As bordas usadas pelo primeiro e último item dependem do modo de flex-direction e escrita ( ltr ou rtl ).

  • space-around ~ O mesmo que o space-between exceto com espaços de meio tamanho nas duas extremidades.

Margens Automáticas

Com auto margens auto , os itens flexíveis podem ser centralizados, espaçados ou agrupados em subgrupos.

Ao contrário do justify-content , que é aplicado ao contêiner flexível, auto margens auto são 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:

  • fazer um grupo de itens flexíveis alinhar à direita ( justify-content: flex-end ) mas ter 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 a justify-self o logotipo pode ser alinhado à esquerda, enquanto os itens de navegação ficam bem à direita, e tudo se ajusta suavemente ("flexiona") a diferentes tamanhos de tela.

Outros cenários úteis:

Coloque um item flexível no canto

Cenário da pergunta:

  • colocando um item flexível em um canto .box { align-self: flex-end; justify-self: flex-end; } .box { align-self: flex-end; justify-self: flex-end; }

Centralizar um item flexível na vertical e na horizontal

margin: auto é uma alternativa para justify-content: center e align-items: center .

Em vez desse código no contêiner flexível:

.container {
    justify-content: center;
    align-items: center;
}

Você pode usar isso no item flexível:

.box56 {
    margin: auto;
}

Essa alternativa é útil ao centralizar um item flexível que transborda o contêiner .

Centralizar um item flexível e centralizar um segundo item flexível entre o primeiro e o limite

Um contêiner flexível alinha os itens flexíveis distribuindo o espaço livre.

Assim, a fim de criar equilíbrio igual , de modo que um item do meio possa ser centrado no contêiner com um único item ao lado, um contrapeso deve ser introduzido.

Nos exemplos abaixo, os itens invisíveis da terceira flexão (caixas 61 e 68) são introduzidos para equilibrar os itens "reais" (caixa 63 e 66).

Claro, esse método não é nada bom 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 de centro e de fundo

NOTA: Os exemplos acima só funcionarão - em termos de verdadeira centralização - quando os itens mais externos forem iguais em altura / largura. Quando itens flexíveis são comprimentos diferentes, veja o próximo exemplo.

Centralizar um item flexível quando itens adjacentes variam em tamanho

Cenário da pergunta:

  • em uma linha de três itens flexíveis, cole o item do meio no centro do contêiner ( justify-content: center ) e alinhe os itens adjacentes às bordas do contêiner ( justify-self: flex-start e justify-self: flex-end ).

    Note que os valores de space-around e space-between a propriedade justify-content não manterão o item do meio centralizado em relação ao container se os itens adjacentes tiverem larguras diferentes ( veja a demonstração ).

Como observado, a menos que todos os itens flexíveis sejam de largura ou altura iguais (dependendo flex-direction ), o item do meio não pode ser verdadeiramente centrado. Esse problema é um forte argumento para uma propriedade justify-self (projetada para lidar com a tarefa, é claro).

#container {
  display: flex;
  justify-content: space-between;
  background-color: lightyellow;
}
.box {
  height: 50px;
  width: 75px;
  background-color: springgreen;
}
.box1 {
  width: 100px;
}
.box3 {
  width: 200px;
}
#center {
  text-align: center;
  margin-bottom: 5px;
}
#center > span {
  background-color: aqua;
  padding: 2px;
}
<div id="center">
  <span>TRUE CENTER</span>
</div>

<div id="container">
  <div class="box box1"></div>
  <div class="box box2"></div>
  <div class="box box3"></div>
</div>

<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>

Aqui estão dois métodos para resolver este problema:

Solução # 1: Posicionamento Absoluto

A especificação flexbox permite o posicionamento absoluto de itens flexíveis . Isso permite que o item do meio seja perfeitamente centrado, independentemente do tamanho de seus irmãos.

Apenas tenha em mente que, como todos os elementos posicionados de forma absoluta, 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 justify-content: center o item do meio com justify-content: center e posicione absolutamente os itens externos.

Solução 2: Recipientes de Flexão Aninhados (sem posicionamento absoluto)

.container {
  display: flex;
}
.box {
  flex: 1;
  display: flex;
  justify-content: center;
}
.box71 > span { margin-right: auto; }
.box73 > span { margin-left: auto;  }

/* non-essential */
.box {
  align-items: center;
  border: 1px solid #ccc;
  background-color: lightgreen;
  height: 40px;
}
<div class="container">
  <div class="box box71"><span>71 short</span></div>
  <div class="box box72"><span>72 centered</span></div>
  <div class="box box73"><span>73 loooooooooooooooong</span></div>
</div>

Veja como isso funciona:

  • O div de nível superior ( .container ) é um contêiner flexível.
  • Cada filho div ( .box ) agora é um item flexível.
  • Cada item da .box é dado flex: 1 para distribuir o espaço do contêiner igualmente.
  • Agora os itens estão consumindo todo o espaço na linha e são de largura igual.
  • Torne cada item um contêiner flex (aninhado) e adicione justify-content: center .
  • Agora, cada elemento de span é um item flexível centrado.
  • Use auto margens auto flex para deslocar a span externa s para a esquerda e para a direita.

Você também pode abrir mão justify-content e usar exclusivamente margens auto .

Mas justify-content pode funcionar aqui porque auto margens auto sempre têm prioridade. A partir da especificação:

8.1. Alinhando com margens auto

Antes do alinhamento via justify-content e align-self , qualquer espaço livre positivo é distribuído para as margens automáticas nessa dimensão.

justificar-conteúdo: espaço-mesmo (conceito)

Voltando para justify-content por um minuto, aqui está uma ideia para mais uma opção.

  • space-same ~ Um híbrido de space-between e space-around . Itens de flexão são uniformemente espaçados (como space-between ), exceto em vez de espaços de meio tamanho em ambas as extremidades (como space-around ), há espaços de tamanho completo em ambas as extremidades.

Esse layout pode ser obtido com os pseudoelementos ::before e ::after no contêiner flexível.

(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 que foi mencionado acima. Veja este post para detalhes: espaço igual entre itens flexíveis

PLAYGROUND (inclui código para todos os exemplos acima)

Considere o eixo principal e o eixo cruzado 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 cruzado, existem três propriedades:

Na imagem acima, o eixo principal é horizontal e o eixo transversal é vertical. Estas são as direções padrão de um contêiner flexível.

No entanto, essas direções podem ser facilmente intercambiadas com a propriedade de flex-direction .

/* 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 ponto em descrever como o trabalho dos eixos é que não parece haver nada de especial em nenhuma direção. O eixo principal, o eixo cruzado, ambos são iguais em termos de importância e flex-direction facilita a mudança para frente e para trás.

Então, por que o eixo cruzado tem duas propriedades adicionais de alinhamento?

Por que o align-content align-items consolidados em uma propriedade para o eixo principal?

Por que o eixo principal não obtém uma propriedade justify-self ?

Cenários onde 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; }

  • fazer um grupo de itens flexíveis alinhar à direita ( justify-content: flex-end ) mas ter 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 a justify-self o logotipo pode ser alinhado à esquerda, enquanto os itens de navegação ficam bem à direita, e tudo se ajusta suavemente ("flexiona") a diferentes tamanhos de tela.

  • em uma linha de três itens flexíveis, cole o item do meio no centro do contêiner ( justify-content: center ) e alinhe os itens adjacentes às bordas do contêiner ( justify-self: flex-start e justify-self: flex-end ).

    Observe que os valores de space-around e de space-between a propriedade justify-content não manterão o item do meio centralizado em relação ao contêiner se os itens adjacentes tiverem larguras diferentes.

#container {
  display: flex;
  justify-content: space-between;
  background-color: lightyellow;
}
.box {
  height: 50px;
  width: 75px;
  background-color: springgreen;
}
.box1 {
  width: 100px;
}
.box3 {
  width: 200px;
}
#center {
  text-align: center;
  margin-bottom: 5px;
}
#center > span {
  background-color: aqua;
  padding: 2px;
}
<div id="center">
  <span>TRUE CENTER</span>
</div>

<div id="container">
  <div class="box box1"></div>
  <div class="box box2"></div>
  <div class="box box3"></div>
</div>

<p>note that the middle box will only be truly centered if adjacent boxes are equal width</p>

jsFiddle version

Como desta escrita, não há menção de justify-self ou justify-items na especificação do flexbox .

No entanto, no CSS Box Alignment Module , que é a proposta inacabada do W3C para estabelecer um conjunto comum de propriedades de alinhamento para uso em todos os modelos de caixa, existe o seguinte:

Fonte: W3C

Você notará que os justify-items justify-self e justify-items estão sendo considerados ... mas não para o flexbox .

Vou terminar reiterando a questão principal:

Por que não há propriedades "justificar-itens" e "justificar-se"?


Eu sei que isso não é uma resposta, mas eu gostaria de contribuir com esse assunto para o que vale a pena. Seria ótimo se eles pudessem liberar justify-self para flexbox para torná-lo verdadeiramente flexível.

Acredito que, quando há vários itens no eixo, a maneira mais lógica de justify-self a se comportar é se alinhar aos vizinhos (ou borda) mais próximos, conforme demonstrado abaixo.

Eu realmente espero que o W3C perceba isso e pelo menos considere isso. =)

Dessa forma, você pode ter um item realmente centrado, independentemente do tamanho da caixa esquerda e direita. Quando uma das caixas atinge o ponto da caixa central, ela simplesmente a empurra até que não haja mais espaço para distribuir.

A facilidade de criar layouts impressionantes é infinita, dê uma olhada neste exemplo "complexo".


justify-self , mas no Chrome Canary, não na versão estável do Chrome. Há até justify-items :

Mas tanto quanto eu posso dizer essas propriedades não funcionam também. Então, provavelmente, o Google salvou de antemão para futuras versões CSS. Só espero que eles adicionem as propriedades em breve.


Isso foi perguntado na lista de estilos www, e Tab Atkins (editor de especificações) forneceu uma resposta explicando o porquê . Eu vou elaborar isso um pouco aqui.

Para começar, vamos supor inicialmente que nosso contêiner flexível seja de linha única ( flex-wrap: nowrap ). Nesse caso, há claramente uma diferença de alinhamento entre o eixo principal e o eixo cruzado - há vários itens empilhados no eixo principal, mas apenas um item empilhado no eixo transversal. Então, faz sentido ter um customizable-per-item "auto-alinhamento" no eixo cruzado (uma vez que cada item é alinhado separadamente, por conta própria), enquanto que não faz sentido no eixo principal (uma vez que, o itens são alinhados coletivamente).

Para flexbox multilinha, a mesma lógica se aplica a cada "flex line". Em uma determinada linha, os itens são alinhados individualmente no eixo cruzado (uma vez que há apenas um item por linha, no eixo transversal), vs. coletivamente no eixo principal.

Aqui está outra maneira de formular: assim, todas as propriedades *-self e *-content são sobre como distribuir espaço extra ao redor das coisas. Mas a principal diferença é que as versões de *-self são para casos em que há apenas uma única coisa nesse eixo , e as versões de *-content são para quando há potencialmente muitas coisas nesse eixo . Os cenários de uma coisa contra muitas coisas são tipos diferentes de problemas e, portanto, eles têm tipos diferentes de opções disponíveis - por exemplo, os valores de space-around / space-between fazem sentido para *-content , mas não para *-self .

SO: No eixo principal de um flexbox, há muitas coisas para distribuir o espaço. Portanto, uma propriedade *-content faz sentido lá, mas não uma propriedade *-self .

Em contraste, no eixo cruzado, temos ambas as propriedades *-self e *-content . Uma determina como distribuiremos espaço em torno das várias linhas flexíveis ( align-content ), enquanto a outra ( align-self ) determina como distribuir o espaço em torno de itens flexíveis individuais no eixo transversal, dentro de uma determinada linha flexível.

(Eu estou ignorando *-items propriedades *-items aqui, já que elas simplesmente estabelecem padrões para *-self .)





w3c