Flex-box: Alinhar a última linha à grade

Eu tenho um layout simples de checkbox flexível com um contêiner como:

.grid { display: flex; flex-flow: row wrap; justify-content: space-between; } 

Agora quero que os itens da última linha estejam alinhados com o outro. justify-content: space-between; deve ser usado porque a largura e a altura da grade podem ser ajustadas.

Atualmente parece

O item no canto inferior direito deve estar no meio

Aqui, quero que o item no canto inferior direito esteja na “coluna do meio”. Qual é a maneira mais simples de conseguir isso? Aqui está um pequeno jsfiddle que mostra esse comportamento.

    Adicione um :after qual preenche automaticamente o espaço. Não há necessidade de poluir seu HTML. Aqui está um codepen mostrando isso: http://codepen.io/DanAndreasson/pen/ZQXLXj

     .grid { display: flex; flex-flow: row wrap; justify-content: space-between; } .grid:after { content: ""; flex: auto; } 

    Uma técnica seria inserir um número de elementos extras (tantos quantos o número máximo de elementos que você espera ter em uma linha) que recebem altura zero. O espaço ainda está dividido, mas linhas supérfluas colapsam em nada:

    http://codepen.io/dalgard/pen/Dbnus

     body { padding: 5%; } div { overflow: hidden; background-color: yellow; } ul { display: flex; flex-wrap: wrap; margin: 0 -4px -4px 0; list-style: none; padding: 0; } li { flex: 1 0 200px; height: 200px; border-right: 4px solid black; border-bottom: 4px solid black; background-color: deeppink; } li:empty { height: 0; border: none; } *, :before, :after { box-sizing: border-box; } 
     
    • a
    • b
    • c
    • d
    • e
    • f
    • g
    • h
    • i
    • j
    • k

    Como outros pôsteres mencionaram – não há uma maneira clara de alinhar à esquerda a última linha com o flexbox (pelo menos de acordo com a especificação atual)

    No entanto, pelo que vale: Com o CSS Grid Layout Module, é surpreendentemente fácil produzir:

    Basicamente, o código relevante se resume a isto:

     ul { display: grid; /* 1 */ grid-template-columns: repeat(auto-fill, 100px); /* 2 */ grid-gap: 1rem; /* 3 */ justify-content: space-between; /* 4 */ } 

    1) Faça do elemento contêiner um contêiner de grade

    2) Defina a grade com colunas automáticas de largura 100px. (Observe o uso do preenchimento automático (como aplicado ao auto-fit – que (para um layout de 1 linha) reduz as trilhas vazias a 0 – fazendo com que os itens sejam expandidos para ocupar o espaço restante. Isso resultaria em uma justificada ‘ espaço entre layout quando a grade tem apenas uma linha que no nosso caso não é o que queremos. (confira esta demo para ver a diferença entre eles).

    3) Defina intervalos / medianizes para as linhas e colunas da grade – aqui, uma vez que se deseja um layout ‘entre espaços’ – a lacuna será, na verdade, uma lacuna mínima, porque crescerá conforme necessário.

    4) Semelhante ao flexbox.

     ul { display: grid; grid-template-columns: repeat(auto-fill, 100px); grid-gap: 1rem; justify-content: space-between; /* boring properties */ list-style: none; background: wheat; padding: 2rem; width: 80vw; margin: 0 auto; } li { height: 50px; border: 1px solid green; } 
     

    Sem qualquer marcação extra, apenas adicionando ::after trabalhei para mim especificando a largura da coluna.

     .grid { display:flex; justify-content:space-between; flex-wrap:wrap; } .grid::after{ content: ''; width: 10em // Same width of .grid__element } .grid__element{ width:10em; } 

    Com o HTML assim:

     

    Você não pode. O Flexbox não é um sistema de grade. Ele não tem as construções de linguagem para fazer o que você está pedindo, pelo menos não se você estiver usando justify-content: space-between . O mais próximo que você pode obter com o Flexbox é usar a orientação da coluna, o que requer definir uma altura explícita:

    http://cssdeck.com/labs/pvsn6t4z (nota: prefixos não incluídos)

     ul { display: flex; flex-flow: column wrap; align-content: space-between; height: 4em; } 

    No entanto, seria mais simples usar apenas colunas, o que tem melhor suporte e não requer definir uma altura específica:

    http://cssdeck.com/labs/dwq3x6vr (nota: prefixos não incluídos)

     ul { columns: 15em; } 

    Uma possível solução é usar justify-content: flex-start; no contêiner .grid , restrições de tamanho em seus filhos e margens nos elementos filho apropriados – dependendo do número desejado de colunas.

    Para uma grade de 3 colunas, o CSS básico ficaria assim:

     .grid { display: flex; flex-flow: row wrap; justify-content: flex-start; } .grid > * { flex: 0 0 32%; margin: 1% 0; } .grid > :nth-child(3n-1) { margin-left: 2%; margin-right: 2%; } 

    É outra solução imperfeita, mas funciona.

    http://codepen.io/tuxsudo/pen/VYERQJ

    Se você quiser alinhar o último item à grade, use o seguinte código:

    Recipiente de grade

     .card-grid { box-sizing: border-box; max-height: 100%; display: flex; flex-direction: row; -webkit-box-orient: horizontal; -webkit-box-direction: normal; justify-content: space-between; align-items: stretch; align-content: stretch; -webkit-box-align: stretch; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-flow: row wrap; flex-flow: row wrap; } .card-grid:after { content: ""; flex: 1 1 100%; max-width: 32%; } 

    Item na grade

     .card { flex: 1 1 100%; box-sizing: border-box; -webkit-box-flex: 1; max-width: 32%; display: block; position: relative; } 

    O truque é definir a largura máxima do item igual à largura máxima da grade .card: depois.

    Demonstração ao vivo no Codepen

    É possível usar “flex-start” e adicionar as margens manualmente. Isso requer alguns truques matemáticos, mas é definitivamente fácil de fazer e facilita o uso com um pré-processador CSS como o LESS.

    Veja por exemplo este mixin LESS:

     .flexboxGridMixin(@columnNumber,@spacingPercent) { @contentPercent: 100% - @spacingPercent; @sideMargin: @spacingPercent/(@columnNumber*2); display: flex; flex-direction: row; flex-wrap: wrap; justify-content: flex-start; > * { box-sizing: border-box; width: @contentPercent/@columnNumber; margin-left: @sideMargin; margin-right: @sideMargin; } } 

    E então ele pode ser facilmente usado para exibir um layout de grade responsivo:

     ul { list-style: none; padding: 0; @spacing: 10%; @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); } @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); } @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); } @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); } @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); } } li { background: pink; height: 100px; margin-top: 20px; } 

    Aqui está um exemplo de

    http://codepen.io/anon/pen/YyLqVB?editors=110

    Esta é uma combinação de muitas das respostas, mas faz exatamente o que eu estava precisando – ou seja, alinhando o último filho em um contêiner flexível à esquerda, mantendo o comportamento entre espaços (neste caso, é uma coluna de três colunas). layout).

    Aqui está a marcação:

     .flex-container { display: flex; justify-content: space-between; flex-direction: row; } .flex-container:after { content: ""; flex-basis: 30%; } 

    Sim.! Nós podemos, mas com algumas consultas de mídia e no máximo de colunas são predefinidas .

    Aqui estou usando 4 colunas. Verifique meu código:

     .container { display: flex; display: -webkit-flex; display: -moz-flex; flex-flow: row wrap; -webkit-flex-flow: row wrap; -moz-flex-flow: row wrap; } .container .item { display: flex; display: -webkit-flex; display: -moz-flex; justify-content: center; -webkit-justify-content: center; -moz-justify-content: center; flex-basis: 25%; //max no of columns in %, 25% = 4 Columns } .container .item .item-child { width: 130px; height: 180px; background: red; margin: 10px; } @media (max-width: 360px) { .container .item { flex-basis: 100%; } } @media (min-width:360px) and (max-width: 520px) { .container .item { flex-basis: 50%; } } @media (min-width:520px) and (max-width: 680px) { .container .item { flex-basis: 33.33%; } } 
     
    1

    Esta versão é a melhor maneira para blocos com largura fixa:

    http://codepen.io/7iomka/pen/oxxeNE

    Em outros casos – versão de dalgard

    http://codepen.io/dalgard/pen/Dbnus

     body { padding: 5%; } div { overflow: hidden; background-color: yellow; } ul { display: flex; flex-wrap: wrap; justify-content:center; margin: 0 -4px -4px 0; list-style: none; padding: 0; } li { flex: 1 0 200px; height: 200px; max-width:200px; min-width:200px; border-right: 4px solid black; border-bottom: 4px solid black; background-color: deeppink; } li:empty { height: 0; border: none; } *, :before, :after { box-sizing: border-box; } 
     
    • a
    • b
    • c
    • d
    • e
    • f
    • g
    • h
    • i
    • j
    • k

    Parece que ninguém propôs a solução flex-grow no último item. A idéia é ter seu último item flexível para aproveitar todo o espaço possível usando flex-grow: 1.

     .grid { display: flex; flex-flow: row wrap; justify-content: space-between; } .grid > *:last-child { flex-grow: 1; } 

    Nota: Esta solução não é perfeita, especialmente se você tiver elementos centralizados dentro de seus itens flexíveis, pois eles serão centralizados no item possivelmente flexível do último flex.

    Você pode conseguir isso simplesmente com flex-start e max-width.

    https://codepen.io/moladukes/pen/NvzBrQ

     .container { display: flex; justify-content: flex-start; flex-flow: row wrap; } .item { width: 130px; max-width: 130px; height: 180px; background: red; margin: 20px; } 

    Existe uma maneira sem o flexbox, embora seja necessário atender às seguintes condições. 1) O contêiner tem preenchimento. 2) Os itens são do mesmo tamanho e você sabe exatamente quantos você quer por linha.

     ul { padding: 0 3% 0 5%; } li { display: inline-block; padding: 0 2% 2% 0; width: 28.66%; } 

    O preenchimento menor no lado direito do contêiner permite o preenchimento extra à direita de cada item da lista. Supondo que outros itens no mesmo pai como o object de lista são preenchidos com 0 5%, ele será nivelado com eles. Você também pode ajustar as porcentagens para quantas margens quiser ou usar os valores de px.

    Naturalmente, você pode fazer o mesmo sem o preenchimento no contêiner usando n-filho (IE 9+) para remover a margem em cada terceira checkbox.

    Usando o flexbox e algumas consultas de mídia, fiz esta pequena solução: http://codepen.io/una/pen/yNEGjv (é um pouco hacky, mas funciona):

     .container { display: flex; flex-flow: row wrap; justify-content: flex-start; max-width: 1200px; margin: 0 auto; } .item { background-color: gray; height: 300px; flex: 0 30%; margin: 10px; @media (max-width: 700px) { flex: 0 45%; } @media (max-width: 420px) { flex: 0 100%; } &:nth-child(3n-1) { margin-left: 10px; margin-right: 10px; } } 

    Eu fiz um mixin SCSS para isso.

     @mixin last-row-flexbox($num-columns, $width-items){ $filled-space: $width-items * $num-columns; $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1)); $num-cols-1 : $num-columns - 1; &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & { margin-left: $margin; } @for $i from 1 through $num-columns - 2 { $index: $num-columns - $i; &:nth-child(#{$num-columns}n+#{$index}):last-child{ margin-right: auto; } } } 

    Este é o link do codepen: http://codepen.io/diana_aceves/pen/KVGNZg

    Você só precisa definir a largura dos itens em porcentagem e número de colunas.

    Espero que isso possa ajudar você.

    Aqui está outro par de mixins scss.

    Estes mixins assumem que você não vai usar plugins js como Isotope (eles não respeitam a ordem de marcação HTML, bagunçando assim as regras do css nth).

    Além disso, você poderá aproveitá-las totalmente, especialmente se estiver escrevendo seus pontos de interrupção responsivos de uma maneira móvel. Você idealmente usará o flexbox_grid () no breakpoint menor e o flexbox_cell () nos seguintes breakpoints. O flexbox_cell () se encarregará de redefinir as margens previamente definidas que não são mais usadas em pontos de interrupção maiores.

    E, a propósito, desde que você configure corretamente as propriedades flexíveis do seu contêiner, você também pode usar apenas flexbox_cell () nos itens, se for necessário.

    Aqui está o código:

     // apply to the container (for ex. 
      element) @mixin flexbox_grid($columns, $gutter_width){ display: flex; flex-direction:row; flex-wrap:wrap; justify-content: flex-start; > *{ @include flexbox_cell($columns, $gutter_width); } } // apply to the cell (for ex. a
    • element) @mixin flexbox_cell($columns, $gutter_width){ $base_width: 100 / $columns; $gutters: $columns - 1; $gutter_offset: $gutter_width * $gutters / $columns; flex-grow: 0; flex-shrink: 1; flex-basis: auto; // IE10 doesn't support calc() here box-sizing:border-box; // so you can freely apply borders/paddings to items width: calc( #{$base_width}% - #{$gutter_offset} ); // remove useless margins (for cascading breakponts) &:nth-child(#{$columns}n){ margin-right: 0; } // apply margin @for $i from 0 through ($gutters){ @if($i != 0){ &:nth-child(#{$columns}n+#{$i}){ margin-right: $gutter_width; } } } }

    Uso:

     ul{ // just this: @include flexbox_grid(3,20px); } // and maybe in following breakpoints, // where the container is already setted up, // just change only the cells: li{ @include flexbox_cell(4,40px); } 

    Obviamente, cabe a você definir o preenchimento / margem / largura do contêiner e as margens de fundo da célula e similares.

    Espero que ajude!

    Isso é bem hacky, mas funciona para mim. Eu estava tentando conseguir espaçamento / margens consistentes.

     .grid { width: 1024px; display: flex; flex-flow: row wrap; padding: 32px; background-color: #ddd; &:after { content: ""; flex: auto; margin-left:-1%; } .item { flex: 1 0 24.25%; max-width: 24.25%; margin-bottom: 10px; text-align: center; background-color: #bbb; &:nth-child(4n+2), &:nth-child(4n+3), &:nth-child(4n+4) { margin-left: 1%; } &:nth-child(4n+1):nth-last-child(-n+4), &:nth-child(4n+1):nth-last-child(-n+4) ~ .item { margin-bottom: 0; } } } 

    http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/

    Se a largura dos filhos for variável (resultando em um número variável de filhos por linha), não há como fazer isso apenas com CSS . Então eu virei para JavaScript para:

    • adicione um elemento .sizer como último filho, inicialmente com flex-basis:100%
    • gradualmente reduza sua flex-basis até que “salte” na linha anterior (ou passe a flex-basis:0% )
    • Quando o acima acontece, ele empurra todos os itens na última linha no início da linha: trabalho feito!

    Exemplo genérico de trabalho:

     // first part of the script generates cards with random words, ignore it let words = [ 'interesting', 'tongue', 'excellent', 'start', 'sticky', 'lame', 'lopsided', 'ill-informed', 'terrible', 'reduce', 'near', 'order' ] for (var i = 0; i < 20; i++) { let text = ''; for (var j = 0; j < 3; j++) { text += words[parseInt(Math.random() * words.length)] + ' ' } $('.container').append($('
    ', { class: 'card', text: text })) } // the juice starts here: $('.container').append( $('
    ', { class:'sizer' })); let topSizer = $('.sizer')[0].getBoundingClientRect().top, perCent = 100; while ( $('.sizer')[0].getBoundingClientRect().top === topSizer && topSizer > 0 ) { $('.sizer').css({flexBasis:(perCent--)+'%'}); }
     .container { display: flex; flex-flow: row wrap; align-content: flex-start; } .card { flex: 1 1 0; padding: .8rem; border: 1px solid #ccc; margin: 0 -1px -1px 0; } .sizer { flex-basis: 100%; } 
      

    Se você quiser uma grade com algum espaço entre os itens e os itens que iniciam sem qualquer espaço inicial, esta solução simples funciona:

     .grid { display: flex; flex-flow: row wrap; margin: 0 -5px; // remove the inital 5px space width: auto; } .grid__item { width: 25%; padding: 0 5px; // should be same as the negative margin above. } 

    Se você quiser o espaço inicial de 5px, basta remover a margem negativa 🙂 Simples.

    A resposta aceita, apesar de boa, faz com que não haja espaço entre os elementos da segunda linha.

    Ah cara, acho que encontrei uma boa solução com CSS mínimo e sem JS. Confira:

     img {width:100%;} li { display: inline-block; width:8em; list-style:none; } ul {text-align: justify;} 
     

    Assumindo:

    • Você quer layout de grade de 4 colunas com envolvimento
    • O número de itens não é necessariamente um múltiplo de 4

    Defina uma margem esquerda em cada item, exceto 1º, 5º e 9º item e assim por diante. Se a margem esquerda for 10px, cada linha terá uma margem de 30px entre 4 itens. A largura percentual do item é calculada da seguinte forma:

     100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4 

    Esta é uma solução decente para problemas envolvendo a última linha do flexbox.

     .flex { display: flex; flex-direction: row; flex-wrap: wrap; margin: 1em 0; background-color: peachpuff; } .item { margin-left: 10px; border: 1px solid; padding: 10px; width: calc(100% / 4 - 22px - 2px - 10px * (4 - 1) / 4); background-color: papayawhip; } .item:nth-child(4n + 1) { margin-left: 0; } .item:nth-child(n + 5) { margin-top: 10px; } 
     
    1
    2
    3
    4
    1
    2
    3
    4
    5
    6
    1
    2
    3
    4
    5
    6
    7
    8
    9

    Eu consegui fazer isso com justify-content: space-between o container