かなりすぐに使える石積みのレイアウトを実装する必要があります。ただし、いくつかの理由から、JavaScriptを使用してそれを行いたくありません。
パラメーター:
これには、最新のブラウザで機能する簡単な解決策があります column-count
プロパティ。
その解決策の問題は、要素が列で順序付けられていることです:
要素を行単位で並べる必要がありますが、少なくともおよそ:
私が試したアプローチはうまくいきません:
display: inline-block
: 垂直方向のスペースを無駄にしますfloat: left
: lol、no。今私はcouldサーバー側のレンダリングを変更し、アイテムの数を列の数で割ってアイテムを並べ替えますが、それは複雑で、エラーが発生しやすい(ベースブラウザがアイテムリストを列に分割する方法について)、可能な限り避けたいと思います。
これを可能にするいくつかの新しいflexboxマジックがありますか?
動的な石積みレイアウトは、少なくともクリーンで効率的な方法ではなく、flexboxでは不可能です。
Flexboxは1次元のレイアウトシステムです。これは、水平OR垂直線に沿ってアイテムを整列できることを意味します。フレックスアイテムは、その行または列に限定されます。
真のグリッドシステムは2次元です。つまり、水平線と垂直線に沿ってアイテムを整列できます。コンテンツアイテムは行と列に同時にまたがることができますが、フレックスアイテムではできません。
これが、flexboxがグリッドを構築する能力に制限がある理由です。また、W3Cが別のCSS3テクノロジー Grid Layout を開発した理由でもあります。
row wrap
flex-flow: row wrap
を持つflexコンテナでは、flexアイテムは新しいrowsにラップする必要があります。
これは、同じ行の別のアイテムの下にフレックスアイテムをラップできないことを意味します。
div#3がdiv#1の下でどのように折り返され、新しい行が作成されるかに注意してください。div#2の下にラップすることはできません。
その結果、アイテムが行の中で最も高くない場合、空白が残り、見苦しいギャップが生じます。
column wrap
flex-flow: column wrap
に切り替えると、グリッドのようなレイアウトがより実現可能になります。ただし、列方向のコンテナーには、すぐに4つの潜在的な問題があります。
その結果、この場合、および他の多くの場合、列方向コンテナはオプションではありません。
グリッドレイアウトは、コンテンツアイテムのさまざまな高さを事前に決定できる場合は、問題に対する完璧なソリューションになります。他のすべての要件は、グリッドの能力の範囲内です。
周囲のアイテムとのギャップを埋めるために、グリッドアイテムの幅と高さがわかっている必要があります。
そのため、水平に流れる石積みレイアウトを構築するためにCSSが提供しなければならないグリッドは、この場合には不十分です。
実際、CSSテクノロジーが自動的にギャップを埋める機能を備えて登場するまで、CSSには一般に解決策がありません。このようなものはおそらくドキュメントをリフローする必要があるので、それがどれほど有用か効率的かはわかりません。
スクリプトが必要になります。
JavaScriptソリューションは、絶対配置を使用する傾向があります。これは、ギャップなしでコンテンツアイテムを再配置するために、ドキュメントフローからコンテンツアイテムを削除します。以下に2つの例を示します。
石積みは、JavaScriptグリッドレイアウトライブラリです。壁に石をはめ込む石工のように、利用可能な垂直方向のスペースに基づいて要素を最適な位置に配置することで機能します。
[Pinterest]は本当にクールなサイトですが、興味深いのは、これらのピンボードがどのようにレイアウトされているかです。したがって、このチュートリアルの目的は、このレスポンシブブロックエフェクトを自分で再作成することです...
ソース: https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html
コンテンツアイテムの幅と高さがわかっているレイアウトの場合、純粋なCSSの水平方向に流れる石積みレイアウトを次に示します。
grid-container {
display: grid; /* 1 */
grid-auto-rows: 50px; /* 2 */
grid-gap: 10px; /* 3 */
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); /* 4 */
}
[short] {
grid-row: span 1; /* 5 */
background-color: green;
}
[tall] {
grid-row: span 2;
background-color: crimson;
}
[taller] {
grid-row: span 3;
background-color: blue;
}
[tallest] {
grid-row: span 4;
background-color: gray;
}
grid-item {
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3em;
font-weight: bold;
color: white;
}
<grid-container>
<grid-item short>01</grid-item>
<grid-item short>02</grid-item>
<grid-item tall>03</grid-item>
<grid-item tall>04</grid-item>
<grid-item short>05</grid-item>
<grid-item taller>06</grid-item>
<grid-item short>07</grid-item>
<grid-item tallest>08</grid-item>
<grid-item tall>09</grid-item>
<grid-item short>10</grid-item>
<grid-item tallest>etc.</grid-item>
<grid-item tall></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
</grid-container>
仕組み
inline-grid
は他のオプションです)grid-auto-rows
プロパティは、自動生成された行の高さを設定します。このグリッドでは、各行の高さは50ピクセルです。grid-gap
プロパティは、grid-column-gap
およびgrid-row-gap
の省略形です。このルールは、10pxギャップbetweenグリッドアイテムを設定します。 (アイテムとコンテナの間の領域には適用されません。)grid-template-columns
プロパティは、明示的に定義された列の幅を設定します。
repeat
表記は、繰り返し列(または行)のパターンを定義します。
auto-fill
関数は、可能な限り多くの列(または行)をオーバーフローさせずに整列するようにグリッドに指示します容器。 (これにより、flexレイアウトのflex-wrap: wrap
と同様の動作を作成できます。)
minmax()
関数は、各列(または行)の最小および最大サイズ範囲を設定します。上記のコードでは、各列の幅はコンテナーの最小30%で、使用可能な空きスペースの最大になります。
fr
unit は、グリッドコンテナの空き領域の一部を表します。 flexboxのflex-grow
プロパティに匹敵します。
CSSグリッドのブラウザサポート
完全な画像は次のとおりです。 http://caniuse.com/#search=grid
Firefoxのクールグリッドオーバーレイ機能
Firefox開発ツールでは、グリッドコンテナを調べると、CSS宣言に小さなグリッドアイコンがあります。クリックすると、ページ上のグリッドのアウトラインが表示されます。
詳細はこちら: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts
これは最近発見されたフレックスボックスを含むテクニックです: https://tobiasahlin.com/blog/masonry-with-css/ 。
この記事は私には理にかなっていますが、私はそれを使用しようとしませんでしたので、マイケルの答えに記載されている以外の警告があるかどうかはわかりません。
order
プロパティを:nth-child
と組み合わせて使用した記事のサンプルを次に示します。
スタックスニペット
.container {
display: flex;
flex-flow: column wrap;
align-content: space-between;
/* Your container needs a fixed height, and it
* needs to be taller than your tallest column. */
height: 960px;
/* Optional */
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
width: 60%;
margin: 40px auto;
counter-reset: items;
}
.item {
width: 24%;
/* Optional */
position: relative;
margin-bottom: 2%;
border-radius: 3px;
background-color: #a1cbfa;
border: 1px solid #4290e2;
box-shadow: 0 2px 2px rgba(0,90,250,0.05),
0 4px 4px rgba(0,90,250,0.05),
0 8px 8px rgba(0,90,250,0.05),
0 16px 16px rgba(0,90,250,0.05);
color: #fff;
padding: 15px;
box-sizing: border-box;
}
/* Just to print out numbers */
div.item::before {
counter-increment: items;
content: counter(items);
}
/* Re-order items into 3 rows */
.item:nth-of-type(4n+1) { order: 1; }
.item:nth-of-type(4n+2) { order: 2; }
.item:nth-of-type(4n+3) { order: 3; }
.item:nth-of-type(4n) { order: 4; }
/* Force new columns */
.break {
flex-basis: 100%;
width: 0;
border: 1px solid #ddd;
margin: 0;
content: "";
padding: 0;
}
body { font-family: sans-serif; }
h3 { text-align: center; }
<div class="container">
<div class="item" style="height: 140px"></div>
<div class="item" style="height: 190px"></div>
<div class="item" style="height: 170px"></div>
<div class="item" style="height: 120px"></div>
<div class="item" style="height: 160px"></div>
<div class="item" style="height: 180px"></div>
<div class="item" style="height: 140px"></div>
<div class="item" style="height: 150px"></div>
<div class="item" style="height: 170px"></div>
<div class="item" style="height: 170px"></div>
<div class="item" style="height: 140px"></div>
<div class="item" style="height: 190px"></div>
<div class="item" style="height: 170px"></div>
<div class="item" style="height: 120px"></div>
<div class="item" style="height: 160px"></div>
<div class="item" style="height: 180px"></div>
<div class="item" style="height: 140px"></div>
<div class="item" style="height: 150px"></div>
<div class="item" style="height: 170px"></div>
<div class="item" style="height: 170px"></div>
<span class="item break"></span>
<span class="item break"></span>
<span class="item break"></span>
</div>