CSSグリッドを使用して、2つの隣り合わせのdivの見かけの順序を逆にすることを望んでいました。divの1つは任意に大きくなります(フロートは使用しません)。
ここにplunkrを作成しました: http://plnkr.co/edit/6WZBnHbwhD7Sjx2ovCO7?p=preview
#container {
grid-template-columns: 240px 1fr;
display: grid;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
重要なのは、.reverse
クラスを適用すると(B | A
が表示されるように)、B
が新しい行にオフセットされるため、次のようになります。
| A
B
.a
と.b
のドキュメントの順序を逆にすると、これは通常に戻ります(ただし、もちろん.reverse
クラスを削除すると、同じ問題が発生します)。
これはなぜですか、どうすれば対処できますか?
グリッドの自動配置アルゴリズムは、コンテナ内のアイテムをレイアウトするときに、次に利用可能な空のセル( source )を使用します。
ソースコードでは、A要素がB要素の前にあります。
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
したがって、グリッドコンテナは最初にAを配置し、次に次の使用可能なスペースを使用してBを配置します。
デフォルトでは、自動配置アルゴリズムは、バックトラックせずにグリッドを直線的に調べます。より大きなアイテムを配置するためにいくつかの空のスペースをスキップする必要がある場合、それらのスペースを埋めるために戻りません。この動作を変更するには、
grid-auto-flow
でdense
キーワードを指定します。http://www.w3.org/TR/css3-grid-layout/#common-uses-auto-placement
grid-auto-flow: dense
この問題の1つの解決策( 既に述べたとおり )は、デフォルトのgrid-auto-flow: row
をgrid-auto-flow: dense
でオーバーライドすることです。
grid-auto-flow: dense
を使用すると、グリッドの自動配置アルゴリズムは、占有されていないセルを適合するアイテムで埋め戻すように見えます。
#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}
明示的に配置されていないグリッドアイテムは、自動配置アルゴリズムによってグリッドコンテナの空きスペースに自動的に配置されます。
grid-auto-flow
は、自動配置アルゴリズムがどのように機能するかを制御し、自動配置されたアイテムがグリッドにフローされる方法を正確に指定します。
dense
指定されている場合、自動配置アルゴリズムは「密な」パッキングアルゴリズムを使用します。これは、後から小さなアイテムが出てきた場合にグリッドの穴を早く埋めようとします。これにより、アイテムが乱れたように見える場合があります。そうすると、大きなアイテムによって残された穴が埋められます。
#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-row: 1;
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
grid-row: 1
別の解決策は、2番目の項目の行を単純に定義することです。
#container>.b {
grid-column: 2;
grid-row: 1; /* NEW */
}
#container {
display: grid;
grid-template-columns: 240px 1fr;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
grid-row: 1; /* NEW */
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-row: 1;
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
上記のソリューションはこの特定の例で機能しますが、質問を解決する適切な方法ではありません。グリッドレイアウトが従うdirection
というCSSプロパティがあります。 direction: rtl
は、質問に必要なものを提供します。 グリッドレイアウトをサポートするすべてのブラウザ でサポートされています。
#container {
grid-template-columns: 240px 1fr;
display: grid;
}
#container.reverse {
direction: rtl;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
<h3>direction: unset</h3>
<div id="container">
<div class="a">A</div>
<div class="b">B</div>
</div>
<h3>direction: rtl</h3>
<div id="container" class="reverse">
<div class="a">A</div>
<div class="b">B</div>
</div>
わかった:コンテナにgrid-auto-flow: dense;
を適用する必要があります:
#container {
grid-template-columns: 240px 1fr;
display: grid;
grid-auto-flow: dense;
}
MDNによる の場合、このアルゴリズムはグリッド内の早い段階で穴を埋めようとします。