Evitar que el contenido expanda elementos de cuadrícula

153

TL; DR: ¿Hay algo parecido table-layout: fixeda las cuadrículas CSS?


Traté de crear un calendario de vista anual con una gran cuadrícula de 4x3 para los meses y en él cuadrículas anidadas de 7x6 para los días.

El calendario debe llenar la página, por lo que el contenedor de cuadrícula de año obtiene un ancho y una altura del 100% cada uno.

.year-grid {
  width: 100%;
  height: 100%;

  display: grid;
  grid-template: repeat(3, 1fr) / repeat(4, 1fr);
}

.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
}

Aquí hay un ejemplo de trabajo: https://codepen.io/loilo/full/ryXLpO/

Para simplificar, cada mes en ese bolígrafo tiene 31 días y comienza un lunes.

También elegí un tamaño de fuente ridículamente pequeño para demostrar el problema:

Los elementos de la cuadrícula (= celdas de día) están bastante condensados, ya que hay varios cientos de ellos en la página. Y tan pronto como las etiquetas de número de día se vuelvan demasiado grandes (siéntase libre de jugar con el tamaño de fuente en el lápiz usando los botones en la parte superior izquierda) la cuadrícula crecerá en tamaño y excederá el tamaño del cuerpo de la página.

¿Hay alguna forma de prevenir este comportamiento?

Inicialmente declaró que mi cuadrícula de año tenía un ancho y una altura del 100%, por lo que probablemente ese sea el punto de partida, pero no pude encontrar ninguna propiedad CSS relacionada con la cuadrícula que se ajustara a esa necesidad.

Descargo de responsabilidad: Soy consciente de que hay formas bastante sencillas de diseñar ese calendario sin usar CSS Grid Layout. Sin embargo, esta pregunta es más sobre el conocimiento general sobre el tema que la solución del ejemplo concreto.

Loilo
fuente
¿Qué quieres que suceda en su lugar? ¿La fuente en cada celda puede ser del tamaño que sea y nunca aumenta el tamaño de la celda de la cuadrícula?
Michael Coker
1
Exactamente. Básicamente, es una forma más conveniente de lo que sucedería si estableciera los tamaños de los elementos de la cuadrícula en valores porcentuales de acuerdo en lugar de fracciones.
Loilo
Básicamente estoy buscando una versión de diseño de tabla de diseño de tabla: fija (ver: codepen.io/loilo/pen/dvxpvq?editors=1100 )
Loilo
77
Este es el mayor dolor en toda la especificación CSS Grid. ¡Deben ser un entorno donde las áreas de cuadrículas no puedan escapar de las dimensiones de ninguno de sus contenedores de cuadrícula principal! Como es, es una pesadilla para las estructuras de cuadrícula profundamente anidadas.
Lonnie Best

Respuestas:

263

De manera predeterminada, un elemento de cuadrícula no puede ser más pequeño que el tamaño de su contenido.

Los elementos de cuadrícula tienen un tamaño inicial de min-width: autoy min-height: auto.

Puede anular este comportamiento estableciendo elementos de cuadrícula en min-width: 0, min-height: 0o overflowcon cualquier valor que no sea visible.

De la especificación:

6.6. Tamaño mínimo automático de elementos de cuadrícula

Para proporcionar un tamaño mínimo predeterminado más razonable para los elementos de la cuadrícula, esta especificación define que el autovalor de min-width/ min-heighttambién aplica un tamaño mínimo automático en el eje especificado a los elementos de la cuadrícula de quién overflowes visible. (El efecto es análogo al tamaño mínimo automático impuesto a los artículos flexibles).

Aquí hay una explicación más detallada que cubre los elementos flexibles, pero también se aplica a los elementos de la cuadrícula:

Esta publicación también cubre problemas potenciales con contenedores anidados y diferencias de representación conocidas entre los principales navegadores .


Para arreglar su diseño, realice estos ajustes en su código:

.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
  background: #fff;
  grid-gap: 2px;
  min-height: 0;  /* NEW */
  min-width: 0;   /* NEW; needed for Firefox */
}

.day-item {
  padding: 10px;
  background: #DFE7E7;
  overflow: hidden;  /* NEW */
  min-width: 0;      /* NEW; needed for Firefox */
}

codepen revisado


1fr vs minmax(0, 1fr)

La solución anterior funciona a nivel de elemento de cuadrícula. Para una solución a nivel de contenedor, vea esta publicación:

Michael Benjamin
fuente
3
Guau. Eso es fascinante e interesante al mismo tiempo, y definitivamente no habría tenido eso solo probando. ¿Acabas de echar un vistazo a las especificaciones para esa información? Porque después de no saber para qué buscar en Google, eso es lo que intenté antes, pero terminé leyendo la sección incorrecta (después de concluir la causa incorrecta del problema).
Loilo
1
Me había encontrado con este problema antes con elementos flexibles . Dado que hay muchas similitudes entre los elementos flexibles y de cuadrícula, supuse que el comportamiento podría ser el mismo y me concentré en esa sección de la especificación.
Michael Benjamin
1
Fija la altura, pero continúa creciendo en dirección horizontal, min-width: 0;no ayuda. ¿Me estoy perdiendo de algo?
usuario
2
Para las cuadrículas anidadas, debemos aplicar esto a todos los niveles. Pero realmente vine aquí para votar y gracias ..
Knack
2
@PragyAgarwal .. stackoverflow.com/users/3597276/michael-b?tab=answers :-)
Michael Benjamin
57

La respuesta anterior es bastante bueno, pero también quería mencionar que no es un equivalente de diseño fijo para las redes, sólo tiene que escribir minmax(0, 1fr)en lugar de 1frcomo su tamaño de la pista.

FremyCompany
fuente
66
Recomiendo este enfoque sobre la respuesta anterior aceptada.
Thierry Prost
Aunque esto funciona, no entiendo un poco ... ¿Podría explicar por qué esto funciona? ¿Qué está haciendo minmax (0, 1fr)? ¿No debería ser siempre 0? Estoy confundido :(
BAERUS
2
minmax(0, 1fr)funciona porque 1fres realmente una abreviatura de minmax(auto,1fr), que no es el valor correcto para la pregunta original.
Mikko Rantalainen
Para obtener detalles adicionales, visite github.com/w3c/csswg-drafts/issues/1777
Mikko Rantalainen
1

Las respuestas existentes resuelven la mayoría de los casos. Sin embargo, me encontré con un caso en el que necesitaba que estuviera el contenido de la celda de cuadrícula overflow: visible. Lo resolví colocando absolutamente dentro de un contenedor (no ideal, pero lo mejor que sé), así:


.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
  background: #fff;
  grid-gap: 2px;  
}

.day-item-wrapper {
  position: relative;
}

.day-item {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px;

  background: rgba(0,0,0,0.1);
}

https://codepen.io/bjnsn/pen/vYYVPZv

bjnsn
fuente
0

una cosa más fácil de hacer es establecer el ancho máximo del elemento de cuadrícula de esta manera:

//for the container
.gridContainer{
    display: grid;
    grids-templates-column: repeat (12, 1fr);
 }

 //for the grid item
 .gridItem{
       max-width: 100%;
       grid-column: span 4  //4 can be any number from1-12 as we specified in the grid template
  }
Pedro JR
fuente
Estoy un poco confundido para ser honesto. Su código no se parece en absoluto a la pregunta original, y aplicar max-width: 100% a los elementos de la cuadrícula (en lugar de min-width: 0 de la solución aceptada) no resolverá el problema ...
Loilo
max-width evitará que se reajuste en relación con su ancho secundario
Pedro JR
He intentado reproducir su código, y en realidad funciona, pero no parece ser por el ancho máximo: 100%, sino por la columna de cuadrícula: span 4; sin definir una columna de inicio. Defina una columna de inicio (por ejemplo, usando grid-column: 1 / span 4;) y se romperá el diseño nuevamente. (Ese comportamiento es un poco extraño, pero estoy seguro de que hay una esquina en algún lugar de la especificación donde se define).
Loilo
bueno suena bien. pero todavía no consideras un voto a favor para mí
Pedro JR
Para ser sincero: 1. Este ha sido un problema resuelto por más de tres años. 2. su respuesta no se ha probado correctamente (su CSS contiene varios errores tipográficos que deben corregirse antes de que el navegador reconozca su grilla). Y 3. su respuesta en realidad no se ajustaba al ejemplo en mi pregunta (de lo contrario, se habría dado cuenta de que su solución no funcionaba con ella). - Entonces no, lo siento, pero no estoy considerando un voto a favor.
Loilo