web-dev-qa-db-fra.com

Maçonnerie avec grille css

J'essaie de créer un modèle de maçonnerie en utilisant un modèle de grille css. Tous les éléments de la grille ont variables hauteurs. Et je ne sais pas quels articles seront. Je ne peux donc pas définir grid-row pour chaque élément. Est-il possible de commencer chaque nouvel élément juste après la fin de la colonne précédente?

Code que j'essaye:

.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 330px);
  align-items: flex-start;
  grid-column-gap: 10px;
  grid-row-gap: 50px;
}

.item {
  background: black;
  border-radius: 5px;
}
<div class="wrapper">
  <div class="item" style="height:50px"></div>
  <div class="item" style="height:100px"></div>
  <div class="item" style="height:30px"></div>
  <div class="item" style="height:90px"></div>
  <div class="item" style="height:80px"></div>
  <div class="item" style="height:50px"></div>
  <div class="item" style="height:70px"></div>
  <div class="item" style="height:40px"></div>

</div>

codepen complet ici

11
user2950602

Dans votre question, vous définissez la hauteur de chaque élément individuellement. Si vous le souhaitez, une structure en maçonnerie peut facilement être réalisée avec une grille.

Au lieu de définir une hauteur pour chaque élément, définissez grid-row-end afin que chaque élément couvre un certain nombre de lignes.

 <div class="item" style="grid-row-end: span 5"></div>

La hauteur de l'élément dépendra des valeurs de grid-auto-rows et grid-row-gap que vous avez définies pour la grille.

J'ai fait un Codepen ici: https://codepen.io/andybarefoot/pen/NaprOB

Si vous ne souhaitez pas définir individuellement la valeur grid-row-end pour chaque élément, vous pouvez utiliser un peu de JavaScript pour le faire de manière dynamique. Je mets un autre "conteneur" div à l'intérieur de chaque élément et mesure la hauteur de ce conteneur pour calculer le nombre de lignes que l'élément doit couvrir. Je le fais au chargement de la page, et encore pour chaque élément lorsque des images sont chargées (car la hauteur du contenu aura changé). Si vous combinez cette approche avec une présentation réactive, vous devez également recalculer le redimensionnement de la page, car la largeur des colonnes peut avoir changé et cela affectera la hauteur du contenu.

Voici mon exemple complet avec le redimensionnement réactif de la colonne: https://codepen.io/andybarefoot/pen/QMeZda

Si vous avez des articles de largeurs variables, vous pouvez toujours obtenir un effet similaire, mais l'emballage de la grille ne sera pas parfait et l'ordre des articles peut être modifié pour optimiser l'emballage.

J'ai écrit un blog sur Medium sur cette approche au cas où elle présenterait un intérêt: Une disposition de style maçonnerie utilisant CSS Grid

1
andybarefoot

Vous pouvez définir les valeurs span pour grid-row-end de manière dynamique (avec un peu de JS, comme celui basé sur mon expérience - Codepen dans l'exemple ci-dessous) et utiliser le mot clé dense pour grid-auto-placement:

const gridStyles = getComputedStyle(document.querySelector('.wrapper',null));
const rowHeight = parseInt(gridStyles.getPropertyValue('--grid-row-height'));
const gap = parseInt(gridStyles.getPropertyValue('--grid-Gutter'));;

let makeGrid = function() {
  let items = document.querySelectorAll('.item');
  for (let i=0, item; item = items[i]; i++) {
    // take an item away from grid to measure it
    item.classList.add('is-being-measured');
    let height = item.offsetHeight;
    // calcylate the row span
    let rowSpan = Math.ceil((height + gap)/(rowHeight + gap));
    // set the span value for grid-row-end
    item.style.gridRowEnd = 'span '+rowSpan;
    // return the item into the grid
    item.classList.remove('is-being-measured');
  }
}

window.addEventListener('load', makeGrid);
window.addEventListener('resize', () => {
  clearTimeout(makeGrid.resizeTimer);
  makeGrid.resizeTimer = setTimeout(makeGrid, 50);
});
.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 330px);
  --grid-Gutter: 10px;
  grid-gap: var(--grid-Gutter);
  --grid-row-height: 10px;
  grid-auto-rows: var(--grid-row-height);
  grid-auto-flow: row dense;
  position: relative;
}

.item {
  background: black;
  color: white;
  border-radius: 5px;
}
.item.is-being-measured {
  /* temporary styles for measuring grid items */
  position: absolute;
  width: 330px;
  top: 0;
  left: 0;
}

.item > * { margin-left: 20px; }
<div class="wrapper">
  <div class="item"><h3>1.1</h3><p>1.2</p></div>
  <div class="item"><p>2.1</p><p>2.2</p><p>2.3</p><p>2.4</p><p>2.5</p></div>
  <div class="item"><h2>3.1</h2></div>
  <div class="item"><h2>4.1</h2><p>4.2</p><p>4.3</p><p>4.4</p></div>
  <div class="item"><p>5.1</p><p>5.2</p><p>5.3</p><p>5.4</p></div>
  <div class="item"><h2>6.1</h2><p>6.2</p></div>
  <div class="item"><h2>7.1</h2><p>7.2</p><p>7.3</p></div>
  <div class="item"><p>8.1</p><p>8.2</p></div>

</div>

0
Ilya Streltsyn

C'est une façon de créer la mise en page de maçonnerie en utilisant uniquement CSS.

*,
*:before,
*:after {
  box-sizing: border-box !important;
}

article {
  -moz-column-width: 13em;
  -webkit-column-width: 13em;
  -moz-column-gap: 1em;
  -webkit-column-gap: 1em;
}

section {
  display: inline-block;
  margin: 0.25rem;
  padding: 1rem;
  width: 100%;
  background: #efefef;
}

p {
  margin: 1rem 0;
}

body {
  line-height: 1.25;
}
<article>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error aliquid reprehenderit expedita odio beatae est.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis quaerat suscipit ad.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nihil alias amet dolores fuga totam sequi a cupiditate ipsa voluptas id facilis nobis.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem ut debitis dolorum earum expedita eveniet voluptatem quibusdam facere eos numquam commodi ad iusto laboriosam rerum aliquam.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat architecto quis tenetur fugiat veniam iste molestiae fuga labore!</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit accusamus tempore at porro officia rerum est impedit ea ipsa tenetur. Labore libero hic error sunt laborum expedita.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima asperiores eveniet vero velit eligendi aliquid in.</p>
  </section>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus dolorem maxime minima animi cum.</p>
  </section>
</article>

Note: Je n'ai pas fait le code, je l'ai trouvé et fait une petite adaptation, le code original peut être trouvé ici .


Veuillez noter que, comme indiqué par Zen :

[...] les éléments sont disposés de haut en bas, de gauche à droite, alors que ce que l’on attend habituellement (hypothèses culturelles excusées) est disposition de gauche à droite, haut-en-bas. C’est le point de mire des recommandations habituelles basées sur les colonnes CSS3.

0
Paolo Forgia