Bien que je n'aie pas encore trouvé de réponse, la question est simple : Y a-t-il un moyen, autre que la force brute, pour compter le nombre de colonnes dans une grille réactive ?

#grid-container {
  width: 100%;
  height: 85%;
  position: relative;
  padding: var(--gap); /* adjusted with JS to make var(--gap) responsive */
  display: grid;
  grid-gap: var(--gap); /* adjusted with JS to make var(--gap) responsive */
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  box-sizing: border-box;
  background: skyblue;
}

.grid-item {
  width: 100%;
  min-width: 120px;
  max-width: 450px;
  height: ; /* adjusted with JS on resize events to roughly maintain proportions */
  min-height: 192px;
  border-radius: 10px;
  background: #333;
}

La raison pour laquelle je demande est parce que j'ai donné aux éléments de la grille un max-width qui provoque un écart massif au tout dernier point d'arrêt, que j'aimerais pouvoir détecter au lieu de définir une requête média explicite.

enter image description here

12
oldboy 17 mars 2019 à 08:43

2 réponses

Meilleure réponse

Je pense que le moyen le plus simple sans force brute est de considérer une simple division. Vous pouvez facilement trouver la largeur du conteneur et chaque colonne est définie par minmax(300px,1fr) et nous connaissons le gap. En utilisant toutes ces informations, le calcul doit être effectué comme ci-dessous :

Si nous aurons N colonnes, nous aurons alors N-1 espaces. Nous savons également que W doit au moins être 300px et ne peut pas être plus qu'une valeur (nous appellerons Wmax).

Supposons que l'écart est égal à 10px.

Si N=2 et que chaque colonne est égale à 300px, nous aurons la largeur du conteneur égale à 300px*2 + 10px*1 = 610px.

Si N=3 et que chaque colonne est égale à 300px nous aurons 300px*3 + 10px*2=920px.

Maintenant, il est clair que si la largeur du conteneur est comprise entre 610px et 920px, nous aurons 2 colonnes car il n'y a pas d'espace pour contenir 3 colonnes mais suffisamment d'espace pour contenir 2 colonnes que nous développons pour remplir l'espace restant (en utilisant 1fr) donc Wmax dans ce cas est (920px - 10px)/2 = 455px. En d'autres termes, la largeur variera de 300px à 455px en ayant 2 colonnes.

Donc, si nous prenons la formule 300px*N + 10px*(N-1) = Wc avec Wc notre largeur de conteneur, vous verrez que N est égal à 2 lorsque Wc=610px et 3 lorsque Wc=920px et entre nous aurons un résultat dans [2,3] donc nous arrondissons simplement la valeur à la plus petite (2 dans ce cas) et nous aurons notre numéro de colonne.

Voici un exemple de base:

var gap = 10;
var minW = 200;

var Wc = document.querySelector('.grid').offsetWidth;
var N = Math.floor((Wc+gap)/(minW+gap));
console.log(N);


window.addEventListener('resize', function(event){
   Wc = document.querySelector('.grid').offsetWidth;
   N = Math.floor((Wc+gap)/(minW+gap));
   console.log(N);
});
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  grid-gap:10px;
}
span {
  min-height:50px;
  background:red;
}
<div class="grid">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

Si vous ne connaissez pas la valeur de l'écart et de la largeur minimale, vous pouvez envisager getComputedStyle() pour obtenir les différentes valeurs. Dans ce cas, le N devrait déjà être un entier car grid-template-columns nous donnera la largeur calculée de chaque colonne (en pratique, nous aurons toujours une fraction en raison de l'arrondi ).

var grid = document.querySelector('.grid');

var gap = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("column-gap"));
var minW = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("grid-template-columns"));

var Wc = document.querySelector('.grid').offsetWidth;
var N = (Wc+gap)/(minW+gap);
console.log(N);


window.addEventListener('resize', function(event){
   Wc = document.querySelector('.grid').offsetWidth;minW = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("grid-template-columns"))
   N = (Wc+gap)/(minW+gap);
   console.log(N);
});
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  grid-gap:10px;
}
span {
  min-height:50px;
  background:red;
}
<div class="grid">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>
4
Temani Afif 19 mars 2019 à 14:45

Une façon d'obtenir le nombre de lignes/colonnes d'une grille CSS consiste à utiliser grid-template-rows ou grid-template-columns à partir du style calculé de la grille window.getComputedStyle(grid).

Les valeurs renvoyées sont toujours transformées en valeurs de pixels séparées (par exemple 20px 20px 50px), où chaque valeur représente la taille de la colonne/ligne respective. Il ne reste plus qu'à diviser la chaîne en un tableau et à compter le nombre de valeurs.

const gridComputedStyle = window.getComputedStyle(grid);

// get number of grid rows
const gridRowCount = gridComputedStyle.getPropertyValue("grid-template-rows").split(" ").length;

// get number of grid columns
const gridColumnCount = gridComputedStyle.getPropertyValue("grid-template-columns").split(" ").length;

console.log(gridRowCount, gridColumnCount);

Visitez l'exemple Codepen

11
Robbendebiene 17 oct. 2019 à 11:29