Quebra de grade CSS

126

É possível fazer um envoltório de grade CSS sem usar consultas de mídia?

No meu caso, tenho um número não determinístico de itens que desejo colocados em uma grade e quero que essa grade seja quebrada. Usando o Flexbox, não consigo espaçar bem as coisas de maneira confiável. Eu gostaria de evitar um monte de consultas de mídia também.

Aqui está um exemplo de código :

.grid {
  display: grid;
  grid-gap: 10px;
  grid-auto-flow: column;
  grid-template-columns: 186px 186px 186px 186px;
}

.grid > * {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

E aqui está uma imagem GIF:

Imagem GIF do que estou vendo

Como uma observação lateral, se alguém puder me dizer como eu poderia evitar especificar a largura de todos os itens como estou com grid-template-columnsisso, seria ótimo. Eu prefiro que os filhos especifiquem sua própria largura.

kentcdodds
fonte
2
grid-template-columns: auto auto auto auto;funciona neste caso? =)
Jakub Chlebowicz

Respostas:

219

Use auto-fillou auto-fitcomo o número de repetição da repeat()notação.

repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )

auto-fill

Quando auto-fillé dado como o número de repetição, se o contêiner de grade tem um tamanho definido ou tamanho máximo no eixo relevante, então o número de repetições é o maior inteiro positivo possível que não faz com que a grade transborde de seu contêiner de grade.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, 186px);
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

A grade irá repetir tantas trilhas quanto possível sem estourar seu contêiner.

Usando o preenchimento automático como o número de repetição da notação repeat ()

Neste caso, dado o exemplo acima (veja a imagem) , apenas 5 trilhas podem caber no contêiner da grade sem transbordar. Existem apenas 4 itens em nossa grade, então um quinto é criado como uma trilha vazia dentro do espaço restante.

O resto do espaço restante, faixa # 6, termina a grade explícita. Isso significa que não havia espaço suficiente para colocar outra faixa.


auto-fit

A auto-fitpalavra-chave se comporta da mesma forma que auto-fill, exceto que após o algoritmo de posicionamento do item da grade, quaisquer trilhas vazias dentro do espaço restante serão reduzidas para 0.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, 186px);
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

A grade ainda irá repetir tantas trilhas quanto possível sem estourar seu contêiner, mas as trilhas vazias serão recolhidas 0.

Uma pista colapsada é tratada como tendo uma função fixa de dimensionamento de pista 0px.

Usando o ajuste automático como o número de repetição da notação repeat ()

Ao contrário do auto-fillexemplo de imagem, a quinta faixa vazia é recolhida, terminando a grade explícita logo após o 4º item.


auto-fill vs auto-fit

A diferença entre os dois é perceptível quando o minmax() função é usada.

Use minmax(186px, 1fr)para variar os itens de186px a 186pxmais uma fração do espaço restante no contêiner da grade.

Ao usar auto-fill, os itens vão crescer, uma vez que não há espaço para colocar faixas vazias.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

Ao usar auto-fit, os itens crescerão para preencher o espaço restante, pois todas as trilhas vazias serão reduzidas 0px.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>


Parque infantil:

CodePen

Inspecionando faixas de preenchimento automático

preenchimento automático


Inspecionando faixas de ajuste automático

ajuste automático

Ricky
fonte
3
Existe alguma maneira de centralizá-los aqueles que estão na próxima linha?
kentcdodds
Assim como você faria com a flex box, no display: griduso do elementojustify-content: center
Spittal
Caro @Ricky, como fazer para que a primeira propriedade de minmax, por exemplo. repeat(auto-fill, minmax(186px, 1fr));não é pixels, mas contanto que o div tenha texto dentro?
mesqueeb
1
@mesqueeb Não é possível, é necessário um tamanho definido . Você pode dar uma olhada nesta resposta para mais detalhes.
Ricky
1
Existe alguma maneira de fazer com que, quando tiver que ir para a próxima linha, dois dos itens caiam em vez de apenas um? Então gosta de 4 para 2 para 1 e não tem de 4 para 3 para 2 para 1?
sammiepls
16

Você quer uma auto-fitou auto-filldentro da repeat()função:

grid-template-columns: repeat(auto-fit, 186px);

A diferença entre os dois se torna aparente se você também usar um minmax()para permitir tamanhos de coluna flexíveis:

grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));

Isso permite que suas colunas sejam flexíveis em tamanho, variando de 186 pixels a colunas de largura igual que se estendem por toda a largura do contêiner. auto-fillcriará tantas colunas quantas caber na largura. Se, digamos, caber cinco colunas, mesmo que você tenha apenas quatro itens de grade, haverá uma quinta coluna vazia:

Insira a descrição da imagem aqui

Usar em auto-fitvez disso evitará colunas vazias, estendendo ainda mais as suas, se necessário:

Insira a descrição da imagem aqui

Keithjgrant
fonte
7

Você pode estar procurando por auto-fill:

grid-template-columns: repeat(auto-fill, 186px);

Demo: http://codepen.io/alanbuchanan/pen/wJRMox

Para usar o espaço disponível com mais eficiência, você pode usar minmaxe passar autocomo o segundo argumento:

grid-template-columns: repeat(auto-fill, minmax(186px, auto));

Demo: http://codepen.io/alanbuchanan/pen/jBXWLR

Se você não quiser as colunas vazias, pode usar em auto-fitvez de auto-fill.

alanbuchanan
fonte
2
Existe alguma maneira de centralizá-los aqueles que estão na próxima linha?
kentcdodds
3

Eu tive uma situação semelhante. Além do que você fez, eu queria centralizar minhas colunas no contêiner, embora não permitisse que colunas vazias fossem para a esquerda ou direita:

.grid { 
    display: grid;
    grid-gap: 10px;
    justify-content: center;
    grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}
Farrellw
fonte
Re "enquanto não permitindo que colunas vazias para para eles" : você quer dizer "enquanto não permitindo que colunas vazias , quer para eles" ( a demasiado quer )? Ou "enquanto não permite colunas vazias para eles" (sem para )? Ou algo mais (não parece computar)?
Peter Mortensen
1

Aqui está minha tentativa. Com licença, eu estava me sentindo extremamente criativo.

Meu método é um pai divcom dimensões fixas . O resto é apenas ajustar o conteúdo dentro dessa div de acordo.

Isso redimensionará as imagens, independentemente da relação de aspecto. Não haverá corte difícil também.

body {
    background: #131418;
    text-align: center;
    margin: 0 auto;
}

.my-image-parent {
    display: inline-block;
    width: 300px;
    height: 300px;
    line-height: 300px; /* Should match your div height */
    text-align: center;
    font-size: 0;
}

/* Start demonstration background fluff */
    .bg1 {background: url(https://unsplash.it/801/799);}
    .bg2 {background: url(https://unsplash.it/799/800);}
    .bg3 {background: url(https://unsplash.it/800/799);}
    .bg4 {background: url(https://unsplash.it/801/801);}
    .bg5 {background: url(https://unsplash.it/802/800);}
    .bg6 {background: url(https://unsplash.it/800/802);}
    .bg7 {background: url(https://unsplash.it/802/802);}
    .bg8 {background: url(https://unsplash.it/803/800);}
    .bg9 {background: url(https://unsplash.it/800/803);}
    .bg10 {background: url(https://unsplash.it/803/803);}
    .bg11 {background: url(https://unsplash.it/803/799);}
    .bg12 {background: url(https://unsplash.it/799/803);}
    .bg13 {background: url(https://unsplash.it/806/799);}
    .bg14 {background: url(https://unsplash.it/805/799);}
    .bg15 {background: url(https://unsplash.it/798/804);}
    .bg16 {background: url(https://unsplash.it/804/799);}
    .bg17 {background: url(https://unsplash.it/804/804);}
    .bg18 {background: url(https://unsplash.it/799/804);}
    .bg19 {background: url(https://unsplash.it/798/803);}
    .bg20 {background: url(https://unsplash.it/803/797);}
/* end demonstration background fluff */

.my-image {
    width: auto;
    height: 100%;
    vertical-align: middle;
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
}
<div class="my-image-parent">
    <div class="my-image bg1"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg2"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg3"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg4"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg5"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg6"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg7"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg8"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg9"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg10"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg11"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg12"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg13"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg14"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg15"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg16"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg17"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg18"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg19"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg20"></div>
</div>

I haz kode
fonte