354 votes

Empêcher le contenu de développer les éléments de la grille

TL;DR : Y a-t-il quelque chose comme table-layout: fixed pour les grilles CSS ?


J'ai essayé de créer un calendrier annuel avec une grande grille 4x3 pour les mois et des grilles 7x6 imbriquées pour les jours.

Le calendrier doit remplir la page, donc le conteneur de la grille de l'année reçoit une largeur et une hauteur de 100% chacune.

.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);
}

Voici un exemple concret : https://codepen.io/loilo/full/ryXLpO/

Pour simplifier, chaque mois de ce stylo compte 31 jours et commence un lundi.

J'ai également choisi une taille de police ridiculement petite pour démontrer le problème :

Les éléments de la grille (= cellules de jour) sont assez condensés car il y en a plusieurs centaines sur la page. Et dès que les étiquettes des numéros de jour deviennent trop grandes (n'hésitez pas à jouer avec la taille de la police dans le stylo en utilisant les boutons en haut à gauche), la grille s'agrandit et dépasse la taille du corps de la page.

Existe-t-il un moyen d'empêcher ce comportement ?

J'ai initialement déclaré que ma grille d'année devait avoir une largeur et une hauteur de 100 %, c'est donc probablement le point de départ, mais je n'ai trouvé aucune propriété CSS liée à la grille qui aurait pu répondre à ce besoin.

Avis de non-responsabilité : Je suis conscient qu'il existe des moyens assez simples de styliser ce calendrier sans utiliser la grille CSS. Cependant, cette question concerne davantage les connaissances générales sur le sujet que la résolution d'un exemple concret.

0 votes

Que voulez-vous qu'il se passe à la place ? La police de chaque cellule peut être de n'importe quelle taille et la taille de la cellule de la grille n'augmente jamais ?

1 votes

Exactement. En fait, c'est une façon plus pratique de faire ce qui se passerait si je définissais les tailles des éléments de la grille en fonction de valeurs en pourcentage au lieu de fractions.

0 votes

Je suis essentiellement à la recherche d'une version grid-layouty de table-layout : fixed (voir : codepen.io/loilo/pen/dvxpvq?editors=1100 )

627voto

Michael_B Points 15556

Par défaut, un élément de la grille ne peut pas être plus petit que la taille de son contenu.

Les éléments de la grille ont une taille initiale de min-width: auto y min-height: auto .

Vous pouvez remplacer ce comportement en donnant aux éléments de la grille la valeur suivante min-width: 0 , min-height: 0 o overflow avec toute autre valeur que visible .

De la spécification :

6.6. Taille minimale automatique de la grille Éléments

Afin de fournir une taille minimale par défaut plus raisonnable pour les éléments de la grille, ce spécification définit que l'élément auto valeur de min-width / min-height applique également une taille minimale automatique dans l'axe spécifié aux éléments de la grille dont les overflow es visible . (L'effet est analogue à la taille minimale automatique imposée aux articles flexibles).

Voici une explication plus détaillée concernant les éléments flexibles, mais elle s'applique également aux éléments de la grille :

Ce post couvre également les problèmes potentiels avec conteneurs imbriqués et connu les différences de rendu entre les principaux navigateurs .


Pour corriger votre mise en page, apportez les modifications suivantes à votre code :

.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 */
}

Démonstration de jsFiddle


1fr vs minmax(0, 1fr)

La solution ci-dessus fonctionne au niveau des éléments de la grille. Pour une solution au niveau du conteneur, voir ce billet :

10 votes

Wow. C'est fascinant et intéressant à la fois, et je n'aurais certainement pas trouvé ça en essayant simplement. Vous avez juste jeté un coup d'oeil sur les spécifications pour trouver cette information ? Parce qu'après ne pas avoir su quoi chercher sur Google, c'est ce que j'ai essayé avant, mais j'ai fini par lire la mauvaise section (après avoir conclu à la mauvaise cause du problème).

2 votes

J'avais déjà rencontré ce problème avec articles flexibles . Comme il existe de nombreuses similitudes entre les éléments flexibles et les éléments de la grille, j'ai pensé que le comportement pourrait être le même et je me suis concentré sur cette section de la spécification.

3 votes

Il fixe la hauteur, mais il continue à croître dans le sens horizontal, min-width: 0; n'aide pas. Est-ce que quelque chose m'échappe ?

184voto

FremyCompany Points 639

La réponse précédente est assez bonne, mais je voulais aussi mentionner qu'il y a es un équivalent de mise en page fixe pour les grilles, il suffit d'écrire minmax(0, 1fr) au lieu de 1fr comme la taille de votre piste.

19 votes

Je recommande cette approche plutôt que la réponse précédente, acceptée.

2 votes

Bien que cela fonctionne, je ne comprends pas grand-chose... Pourriez-vous m'expliquer pourquoi cela fonctionne ? Que fait minmax(0, 1fr) ? Ne devrait-il pas toujours être égal à 0 ? Je suis confus :(

15 votes

minmax(0, 1fr) fonctionne car 1fr est en fait un raccourci pour minmax(auto,1fr) ce qui n'est pas la valeur correcte pour la question originale.

14voto

bjnsn Points 53

Les réponses existantes permettent de résoudre la plupart des cas. Cependant, j'ai rencontré un cas où le contenu de la cellule de la grille devait être overflow: visible . Je l'ai résolu par un positionnement absolu dans un wrapper (pas idéal, mais le meilleur que je connaisse), comme ceci :

.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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X