28112 sujets

CSS et mise en forme, CSS3

Pages :
(reprise du message précédent)

Bonjour Olivier C,

Très intéressante ta galerie d'images mais où trouver le code CSS et JS ?

Dans le code source ce n'est pas facile à lire.

Je pensais que le site était une sorte de codepen mais je ne vois pas comment afficher le code.

Autrement je continue à réfléchir à vos différentes suggestions, encore merci.
Modifié par boteha_2 (17 Mar 2023 - 19:02)
Bon. j'ai fait un Pen en simplifiant au passage le code, en enlevant notamment l'appel aux Container Queries, et donc les fallbaks associés : CodePen, masonry.

Notons qu'ici j'ai fait une grille sur 2 colonnes avec ".grid2". Le style prévoyant de 1 à 4 colonnes, je vous laisse deviner ce qu'il faut faire pour obtenir 3 ou 4 colonnes.

Et comme je ne laisserais pas ce Pen éternellement en ligne je poste le code ici pour ceux qui lirons le topic à l'avenir :
<main>
  <div class="grid2 gap masonry">
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
    <div>Du contenu...</div>
  </div>
</main>

[class^=grid] {
  display: grid;
  grid-auto-flow: dense;
  grid-template-columns: repeat(var(--n, 1), minmax(0, 1fr));
}
[class^=grid].row-defines { /* @note Option ; permet aux spans de la propriété grid-row de se caler sur les lignes. */
  grid-auto-rows: minmax(0, 1fr);
}
[class^=grid].gap { /* @note Option ; les espacements */
  gap: 1em;
}
[class^=grid].gap-bottom { /* @note Option ; espace en bas du conteneur principal */
  padding-bottom: 1em;
}
[class^=grid].vertical-gap { /* @note Option ; espace vertical uniquement */
  gap: 0 1em;
}
@media (min-width: 35em) {
  .grid2,
  .grid3,
  .grid4 {
    --n: 2;
  }
  .c2,
  .c3,
  .c4 {
    grid-column: span 2;
  }
}

/* for démo : */
html {
  background-color: #333;
}
body {
  margin: 0;
}
main {
  max-width: 90em;
  margin: 0 auto;
}
[class^=grid] * {
  padding: 1em;
  background-color: tan;
}

// masonry :
class VGrid {
  // En attendant un support masonry natif pour le module CSS Grid layout.
  // @see  https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/
 
  // @credit Vikram Soni @see  https://codepen.io/vikramsoni/pen/gOvOKNz
 
  // @note Le script fait appel à une redistribution des lignes pour la grille
  // @bugfix @affected Chrome @see  https://github.com/rachelandrew/gridbugs/issues/28  @note Une limitation à 999 lignes semble avoir été corrigée, nous avons testé avec 600 items sans bugs.
  constructor (container) {
    this.grid = container instanceof HTMLElement ? container : document.querySelector(container) // Initialise la grille et les éléments enfants.
    this.gridItems = [].slice.call(this.grid.children) // Récupère tous les enfants directs.
  }
  resizeGridItem(item) {
    const rowHeight = 1 // précision de la grille, ici la plus grande précision possible.
    const rowGap = parseInt(window.getComputedStyle(this.grid).getPropertyValue('grid-row-gap')) // Récupère les propriétés d'espacement des lignes de la grille, afin que nous puissions l'ajouter aux enfants pour ajouter de l'espace supplémentaire afin d'éviter le débordement de contenu.
    const rowSpan = Math.ceil((item.clientHeight + rowGap) / (rowHeight + rowGap))// clientheight représente la hauteur du conteneur avec le contenu. Nous le divisons par la ligne Height+row Gap pour calculer le nombre de lignes dont il a besoin.
    item.style.gridRowEnd = 'span ' + rowSpan // Définit la propriété CSS span numRow pour cet enfant avec celle calculée.
  }
  resizeAllGridItems() { // @bugfix Un premier calcul peut s'avérer insufisant, causant des bugs de rendu sur la longeur des items.
    this.grid.style.alignItems = 'start' // modification temporaire de la propriété css slign-items pour calculer la hauteur du contenu.
    this.gridItems.forEach(item => this.resizeGridItem(item)) // Appeler la fonction pour calculer le nombre de lignes dont elle a besoin.
    this.grid.style.alignItems = 'stretch' // Remettre les align-items à étirer.
  }
}

for (const masonry of document.querySelectorAll('.masonry')) {
  const grid = new VGrid(masonry)
  //window.onload = grid.resizeAllGridItems() // Lancement du calcul de la grille au chargement de la page.
  window.addEventListener('load', () => { // Lancement du calcul de la grille si resize
    grid.resizeAllGridItems()
    setTimeout(() => {grid.resizeAllGridItems()}, 200)
  })
  window.addEventListener('resize', () => { // Lancement du calcul de la grille si resize
    let resizeTimeout
    clearTimeout(resizeTimeout)
    resizeTimeout = setTimeout(() => {grid.resizeAllGridItems()}, 200) // Limitation du nombre de calculs @see  https://stackoverflow.com/questions/5836779/
 
  })
}

Modifié par Olivier C (18 Mar 2023 - 18:32)
Le javascript il ne faut pas le simplifier, on peut par contre supprimer les commentaires et il ne reste alors plus grand chose.

Pour le CSS, en gardant la possibilité de seulement deux colonnes, avec quand même l'option "gap", ont peut faire ainsi :
.grid2 {
  display: grid;
  grid-auto-flow: dense;
  grid-template-columns: repeat(var(--n, 1), minmax(0, 1fr));
}
.grid2.gap { /* @note Option pour les espacements */
  gap: 1em;
}
@media (min-width: 35em) {
  .grid2 {
    --n: 2;
  }

C'est bien pour comprendre. Evidemment, le code précédent est nettement plus polyvalent.
Modifié par Olivier C (18 Mar 2023 - 12:46)