Habillage de grille CSS

126

Est-il possible de créer une grille CSS sans utiliser de requêtes multimédias?

Dans mon cas, j'ai un nombre non déterministe d'éléments que je veux placer dans une grille et je veux que cette grille s'enroule. En utilisant Flexbox, je ne parviens pas à espacer correctement les choses de manière fiable. J'aimerais aussi éviter un tas de requêtes médiatiques.

Voici un exemple de code :

.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>

Et voici une image GIF:

Image GIF de ce que je vois

En passant, si quelqu'un peut me dire comment je pourrais éviter de spécifier la largeur de tous les éléments comme je le suis, grid-template-columnsce serait formidable. Je préférerais que les enfants spécifient leur propre largeur.

kentcdodds
la source
2
grid-template-columns: auto auto auto auto;fonctionne dans ce cas? =)
Jakub Chlebowicz

Réponses:

219

Utilisez l'un auto-fillou l' autre auto-fitcomme numéro de répétition de la repeat()notation.

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

auto-fill

Lorsque auto-fillest donné comme numéro de répétition, si le conteneur de grille a une taille définie ou une taille maximale dans l'axe concerné, alors le nombre de répétitions est le plus grand entier positif possible qui n'entraîne pas le débordement de la grille de son conteneur de grille.

.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>

La grille répétera autant de pistes que possible sans déborder de son conteneur.

Utilisation du remplissage automatique comme numéro de répétition de la notation repeat ()

Dans ce cas, étant donné l'exemple ci-dessus (voir image) , seules 5 pistes peuvent rentrer dans la grille-conteneur sans déborder. Il n'y a que 4 éléments dans notre grille, donc un cinquième est créé comme une piste vide dans l'espace restant.

Le reste de l'espace restant, la piste n ° 6, termine la grille explicite. Cela signifie qu'il n'y avait pas assez d'espace pour placer une autre piste.


auto-fit

Le auto-fitmot-clé se comporte de la même manière que auto-fill, sauf qu'après l' algorithme de placement des éléments de grille, toutes les pistes vides dans l'espace restant seront réduites en 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>

La grille répètera toujours autant de pistes que possible sans déborder de son conteneur, mais les pistes vides seront réduites en 0.

Une piste réduite est traitée comme ayant une fonction de dimensionnement de piste fixe de 0px.

Utilisation de l'ajustement automatique comme numéro de répétition de la notation repeat ()

Contrairement à l' auto-fillexemple d'image, la cinquième piste vide est réduite, mettant fin à la grille explicite juste après le quatrième élément.


auto-fill contre auto-fit

La différence entre les deux est perceptible lorsque la minmax()fonction est utilisée.

Utilisez minmax(186px, 1fr)pour étendre les éléments de 186pxà 186pxplus une fraction de l'espace restant dans le conteneur de grille.

Lors de l'utilisation auto-fill, les éléments grandiront une fois qu'il n'y aura plus d'espace pour placer des pistes vides.

.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>

Lors de l'utilisation auto-fit, les éléments grandissent pour remplir l'espace restant car toutes les pistes vides sont réduites 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>


Terrain de jeux:

CodePen

Inspection des pistes à remplissage automatique

remplissage automatique


Inspection des pistes à ajustement automatique

ajustement automatique

Ricky
la source
3
Y a-t-il un moyen de centrer ceux qui sont sur la ligne suivante?
kentcdodds
Tout comme vous le feriez avec une boîte flexible, sur l' display: gridutilisation de l' élémentjustify-content: center
Spittal
Cher @Ricky Comment faire en sorte que la première propriété de minmax, par exemple. repeat(auto-fill, minmax(186px, 1fr));n'est pas des pixels, mais aussi longtemps que le div contient du texte?
mesqueeb
1
@mesqueeb Ce n'est pas possible, une taille définie est nécessaire. Vous pouvez consulter cette réponse pour plus de détails.
Ricky
1
Existe-t-il un moyen de faire en sorte que, lorsqu'il doit passer à la ligne suivante, deux des éléments disparaissent au lieu d'un seul? Donc, comme de 4 à 2 à 1 et ne pas l'avoir 4 à 3 à 2 à 1?
sammiepls
16

Vous voulez soit auto-fitou auto-fillà l'intérieur de la repeat()fonction:

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

La différence entre les deux devient évidente si vous utilisez également a minmax()pour permettre des tailles de colonne flexibles:

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

Cela permet à vos colonnes de varier en taille, allant de 186 pixels à des colonnes de largeur égale s'étendant sur toute la largeur du conteneur. auto-fillcréera autant de colonnes que la largeur. Si, par exemple, cinq colonnes correspondent, même si vous n'avez que quatre éléments de grille, il y aura une cinquième colonne vide:

Entrez la description de l'image ici

Utiliser à la auto-fitplace empêchera les colonnes vides, étirant davantage les vôtres si nécessaire:

Entrez la description de l'image ici

Keithjgrant
la source
7

Vous recherchez peut-être auto-fill:

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

Démo: http://codepen.io/alanbuchanan/pen/wJRMox

Pour utiliser plus efficacement l'espace disponible, vous pouvez utiliser minmaxet passer autocomme deuxième argument:

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

Démo: http://codepen.io/alanbuchanan/pen/jBXWLR

Si vous ne voulez pas les colonnes vides, vous pouvez utiliser à la auto-fitplace de auto-fill.

alanbuchanan
la source
2
Y a-t-il un moyen de centrer ceux qui sont sur la ligne suivante?
kentcdodds
3

J'ai eu une situation similaire. En plus de ce que vous avez fait, je voulais centrer mes colonnes dans le conteneur sans autoriser les colonnes vides à gauche ou à droite:

.grid { 
    display: grid;
    grid-gap: 10px;
    justify-content: center;
    grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}
Farrellw
la source
Re « tout en ne permettant pas de colonnes vides pour eux » : Voulez - vous dire « tout en ne permettant pas les colonnes vides soit pour eux » ( àaussisoit )? Ou "tout en ne leur permettant pas de colonnes vides" (sans pour )? Ou autre chose (ça ne semble pas calculer)?
Peter Mortensen
1

Voici ma tentative. Excusez les peluches, je me sentais très créative.

Ma méthode est un parent divaux dimensions fixes . Le reste ajuste simplement le contenu à l'intérieur de cette div en conséquence.

Cela redimensionnera les images quel que soit le rapport hauteur / largeur. Il n'y aura pas non plus de recadrage dur .

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>

Je haz kode
la source