Ajuste de cuadrícula CSS

126

¿Es posible hacer un ajuste de cuadrícula CSS sin usar consultas de medios?

En mi caso, tengo un número no determinista de elementos que quiero colocar en una cuadrícula y quiero que esa cuadrícula se ajuste. Usando Flexbox, no puedo espaciar bien las cosas de manera confiable. También me gustaría evitar un montón de consultas de medios.

Aquí hay un código de muestra :

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

Y aquí hay una imagen GIF:

Imagen GIF de lo que estoy viendo

Como nota al margen, si alguien puede decirme cómo podría evitar especificar el ancho de todos los elementos como yo grid-template-columns, sería genial. Preferiría que los niños especificaran su propio ancho.

kentcdodds
fuente
2
grid-template-columns: auto auto auto auto;funciona en este caso? =)
Jakub Chlebowicz

Respuestas:

219

Utilice auto-fillo auto-fitcomo número de repetición de la repeat()notación.

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

auto-fill

Cuando auto-fillse da como número de repetición, si el contenedor de cuadrícula tiene un tamaño definido o tamaño máximo en el eje relevante, entonces el número de repeticiones es el entero positivo más grande posible que no hace que la cuadrícula se desborde de su contenedor de cuadrícula.

.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 cuadrícula repetirá tantas pistas como sea posible sin desbordar su contenedor.

Usar autocompletar como el número de repetición de la notación repeat ()

En este caso, dado el ejemplo anterior (ver imagen) , solo 5 pistas pueden caber en el contenedor de rejilla sin desbordarse. Solo hay 4 elementos en nuestra cuadrícula, por lo que se crea un quinto como una pista vacía dentro del espacio restante.

El resto del espacio restante, pista # 6, finaliza la cuadrícula explícita. Esto significa que no había suficiente espacio para colocar otra pista.


auto-fit

La auto-fitpalabra clave se comporta igual que auto-fill, excepto que después del algoritmo de ubicación de elementos de la cuadrícula, las pistas vacías dentro del espacio restante se contraerán a 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 cuadrícula seguirá repitiendo tantas pistas como sea posible sin desbordar su contenedor, pero las pistas vacías se contraerán a 0.

Una pista colapsada se considera que tiene una función de tamaño de pista fija de 0px.

Usando auto-ajuste como el número de repetición de la notación repeat ()

A diferencia del auto-fillejemplo de la imagen, la quinta pista vacía se contrae, terminando la cuadrícula explícita justo después del cuarto elemento.


auto-fill vs auto-fit

La diferencia entre los dos se nota cuando minmax()se utiliza la función.

Úselo minmax(186px, 1fr)para clasificar los elementos de 186pxa 186pxmás una fracción del espacio sobrante en el contenedor de la cuadrícula.

Cuando se usa auto-fill, los elementos crecerán una vez que no haya espacio para colocar pistas vacías.

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

Cuando se usa auto-fit, los elementos crecerán para llenar el espacio restante porque todas las pistas vacías se contraen a 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>


Patio de recreo:

CodePen

Inspeccionar pistas de llenado automático

autocompletar


Inspección de pistas de ajuste automático

autoajuste

Ricky
fuente
3
¿Hay alguna forma de hacer que centre los que están en la siguiente línea?
kentcdodds
Al igual que lo haría con la caja flexible, en el display: griduso del elementojustify-content: center
Spittal
Estimado @Ricky ¿Cómo hacerlo para que la primera propiedad de minmax, por ejemplo. repeat(auto-fill, minmax(186px, 1fr));no son píxeles, pero siempre y cuando el div tenga texto dentro?
mesqueeb
1
@mesqueeb No es posible, se necesita un tamaño definido . Puede echar un vistazo a esta respuesta para obtener más detalles.
Ricky
1
¿Hay alguna forma de hacerlo de modo que cuando tenga que pasar a la siguiente línea, dos de los elementos bajen en lugar de solo uno? Entonces, ¿de 4 a 2 a 1 y no tener 4 a 3 a 2 a 1?
sammiepls
16

Quieres cualquiera auto-fito auto-filldentro de la repeat()función:

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

La diferencia entre los dos se hace evidente si también usa a minmax()para permitir tamaños de columna flexibles:

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

Esto permite que sus columnas se flexionen en tamaño, que van desde 186 píxeles hasta columnas de igual ancho que se extienden por todo el ancho del contenedor. auto-fillcreará tantas columnas como quepan en el ancho. Si, digamos, caben cinco columnas, aunque solo tenga cuatro elementos de cuadrícula, habrá una quinta columna vacía:

Ingrese la descripción de la imagen aquí

Usar en su auto-fitlugar evitará columnas vacías, estirando aún más la suya si es necesario:

Ingrese la descripción de la imagen aquí

keithjgrant
fuente
7

Puede que estés buscando auto-fill:

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

Demostración: http://codepen.io/alanbuchanan/pen/wJRMox

Para utilizar el espacio disponible de manera más eficiente, puede usar minmaxy pasar autocomo segundo argumento:

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

Demostración: http://codepen.io/alanbuchanan/pen/jBXWLR

Si no desea las columnas vacías, puede usar en auto-fitlugar de auto-fill.

Alanbuchanan
fuente
2
¿Hay alguna forma de hacer que centre los que están en la siguiente línea?
kentcdodds
3

Tuve una situación similar. Además de lo que hiciste, quería centrar mis columnas en el contenedor sin permitir que las columnas vacías se desplazaran hacia la izquierda o hacia la derecha:

.grid { 
    display: grid;
    grid-gap: 10px;
    justify-content: center;
    grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}
Farrellw
fuente
Re "mientras que no permite a las columnas vacías para ellos" : Qué quiere decir "mientras que no permite columnas vacías o bien para ellos" ( ademasiadoya sea )? ¿O "sin permitirles columnas vacías" (sin hacerlo )? ¿O algo más (no parece computar)?
Peter Mortensen
1

Este es mi intento. Disculpe la pelusa, me sentía muy creativo.

Mi método es un padre divcon dimensiones fijas . El resto es simplemente ajustar el contenido dentro de ese div en consecuencia.

Esto cambiará la escala de las imágenes independientemente de la relación de aspecto. Tampoco habrá recortes difíciles .

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>

Yo haz kode
fuente