web-dev-qa-db-ja.com

CSSグリッドのある組積造レイアウト

石積みのレイアウトを作成しようとしていますcssグリッドレイアウトを使用。グリッド内のすべてのアイテムは変数高さを持っています。そして、私はどんなアイテムになるかわかりません。そのため、各アイテムにgrid-rowを定義できません。列の前の項目の終わりの直後に各新しい項目を開始することは可能ですか?

私が試しているコード:

.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>

ここに完全なコードペン

13
user2950602

あなたの質問では、各アイテムの高さを個別に設定しています。これを実行してよければ、グリッドを使用してメーソンリーのレイアウトを簡単に実現できます。

各アイテムの高さを設定する代わりに、各アイテムが特定の行数にまたがるようにgrid-row-endを設定します。

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

アイテムの高さは、グリッドに設定したgrid-auto-rowsおよびgrid-row-gapの値によって異なります。

ここでCodepenを作成しました: https://codepen.io/andybarefoot/pen/NaprOB

各アイテムのgrid-row-end値を個別に設定したくない場合は、JavaScriptを少し使用して動的に行うことができます。各アイテム内に別の「コンテナー」divを配置し、このコンテナーの高さを測定して、アイテムがまたがる必要のある行数を計算します。これはページの読み込み時に行います。また、画像が読み込まれたときに各アイテムに対して再度行います(コンテンツの高さが変更されるため)。このアプローチをレスポンシブレイアウトと組み合わせる場合は、列の幅が変更されている可能性があり、これがコンテンツの高さに影響を与えるため、ページのサイズ変更時に再計算する必要があります。

以下は、レスポンシブな列のサイズ変更に関する私の完全な例です。 https://codepen.io/andybarefoot/pen/QMeZda

可変幅のアイテムがある場合でも、同様の効果を得ることができますが、グリッドのパッキングは完全ではなく、パッキングを最適化するためにアイテムの順序が変更される可能性があります。

興味がある場合に備えて、私はこのアプローチについてMediumでブログを書きました:CSSグリッドを使用したメーソンリースタイルのレイアウト

1
andybarefoot

grid-row-endspan値を動的に設定して(以下の例では、私の Codepen実験 に基づいたJSのように)、denseキーワードを使用できます。 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

これは、CSSのみを使用して組積造レイアウトを作成する1つの方法です。

*,
*: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>

注:私はコードを作成しませんでした、私はそれがいくつかの小さな適応を作ったことを発見しました、元のコードは見つけることができます ここ =。


Zen で指摘されているように、

[...]アイテムはtop-to-bottomleft-to-right、一方、通常期待されるもの(文化的な仮定は除外されます)はleft-to-right上から下のレイアウト。これは、通常のCSS3列ベースの推奨事項のショートッパーです。

0
Paolo Forgia