生成されたコンテンツとCSSグリッドレイアウトを使用した空のセルのスタイリング
公開: 2022-03-10一般的なグリッドレイアウトの落とし穴は、レイアウトメソッドの初心者が、コンテンツを含まないグリッドセルのスタイルを設定する方法を考えている場合です。 現在のレベル1仕様では、空のグリッドセルまたはグリッド領域をターゲットにしてスタイルを適用する方法がないため、これは不可能です。 つまり、スタイリングを適用するには、要素を挿入する必要があります。
この記事では、CSS生成コンテンツを使用して、冗長な空の要素を追加せずに空のセルのスタイルを設定する方法を見て、この手法が理にかなっているいくつかのユースケースを示します。
BFCを詳しく見る
CSSを使用してレイアウトを作成したことがある場合は、おそらくBFCが何であるかを知っているでしょう。 なぜそれが機能するのか、そしてそれを作成する方法を理解することは有用であり、CSSでレイアウトがどのように機能するかを理解するのに役立ちます。 関連記事を読む→
空のエリアをすでにスタイリングできないのはなぜですか?
グリッド仕様の冒頭の段落には、次のように書かれています。
「このCSSモジュールは、ユーザーインターフェイス設計用に最適化された2次元グリッドベースのレイアウトシステムを定義します。 グリッドレイアウトモデルでは、グリッドコンテナの子を、事前定義されたフレキシブルまたは固定サイズのレイアウトグリッドの任意のスロットに配置できます。」
ここでのキーワードは「グリッドコンテナの子」です。 この仕様では、子アイテムを配置できる親要素でのグリッドの作成を定義しています。 それはそのグリッドのスタイルを定義せず、Multi-columnLayoutにあるcolumn-rule
プロパティのようなものを実装することさえしません。 グリッド自体ではなく、子アイテムのスタイルを設定します。そのため、そのスタイルを適用するには、何らかの要素が必要になります。
スタイリングフックとしての冗長要素の使用
スタイルに何かを挿入する1つの方法は、スパンやdivなどの冗長要素をドキュメントに挿入することです。 開発者は、フロートを使用してグリッドレイアウトを実現するために、冗長な「行ラッパー」を何年も追加しているにもかかわらず、このアイデアを嫌う傾向があります。 おそらく、明らかに空の要素は、ラッパー要素のやや隠された冗長性よりも不快です!
この例が示すように、完全に空の要素はグリッドアイテムになり、コンテンツを含む要素と同じように背景と境界線を追加できます。
Eric Meyerは、A ListApartの記事FauxGrid Tracksで、 b
要素を冗長な要素として使用することを提唱しています。これは、意味的な意味を与えないため、短く、フックとしてのマークアップでもかなり明白です。
追加のいくつかのdiv
またはb
要素を挿入することは、これまでにコミットした優れたマークアップに対する最大の犯罪になる可能性は低いため、必要に応じてそのアプローチを選択することで眠りを失うことはありません。 Web開発では、より良いソリューションが考案されるまで、仕事を遂行するための最適ではないアプローチを選択することがよくあります。 ただし、可能であれば、スタイルシートで安全にスタイリングを1か所に保持することをお勧めします。 他に何もないとしても、追加の必要なマークアップについて心配する必要がなく、スタイルの再利用が容易になります。 このため、私は生成されたコンテンツに目を向ける傾向があります。これは、CSSを使用して本をフォーマットする作業でよく知っていることであり、ほとんどの時間をこの機能の操作に費やしています。
生成されたコンテンツをスタイリングフックとして使用する
CSSで生成されたコンテンツは、 ::before
および::after
CSS疑似クラスをcontent
プロパティとともに使用して、ある種のコンテンツをドキュメントに挿入します。 コンテンツを挿入するという考えは、これがテキストを挿入するためのものであると思わせるかもしれません。これは可能ですが、私たちの目的では、グリッドコンテナの直接の子として空の要素を挿入することに関心があります。 要素を挿入すると、スタイルを設定できます。
次の例では、グリッドコンテナになる包含要素があり、その中に別の要素がネストされています。 この単一の直接の子はグリッドアイテムになります。 コンテナに3列3行のグリッドを定義し、グリッド線を使用して単一のアイテムを配置したので、中央のグリッドセルに配置されます。
<div class="grid"> <div class="item"></div> </div>
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-gap: 10px; } .grid > * { border: 2px solid rgb(137,153,175); } .item { grid-column: 2; grid-row: 2; }
この例を見ると、Firefoxグリッドインスペクターを使用してグリッド線をオーバーレイすると、グリッドの他の空のセルがどのように存在するかを確認できますが、それらに背景または境界線を追加するには、子を追加する必要があります要素。 これはまさに生成コンテンツが可能にするものです。
CSSで、グリッドコンテナの::before
と::after
に空の文字列を追加します。 これらはすぐにグリッドアイテムになり、コンテナを埋めるためにストレッチします。 次に、ボックスに必要なスタイルを追加します。この場合は背景色を追加し、通常のグリッドアイテムと同じように配置します。
.grid::before { content: ""; background-color: rgb(214,232,182); grid-column: 3; grid-row: 1; } .grid::after { content: ""; background-color: rgb(214,232,182); grid-column: 1; grid-row: 3; }
このドキュメントにはまだ子要素が1つしかなく、冗長なスタイリング要素はCSS内に含まれています。これは、スタイリングの目的でのみ存在するため、完全に合理的と思われます。
生成コンテンツアプローチの制限
このアプローチの明らかな問題は、右上と左下のグリッドセルもスタイル設定する場合に明らかになります。 生成されたコンテンツの1つだけをコンテナーの上部と下部に適用できます。複数の::before
および::after
疑似要素は許可されていません。 CSSグリッドチェッカーボードを自分で作成する場合、このメソッドは機能しません。 多くの空のセルのスタイリングを行う必要があることがわかった場合は、当面の間、上記で説明した「フィラーB」のアプローチが最善の策となる可能性があります。
生成されたコンテンツメソッドは、プロジェクトに取り組んでいる将来の開発者を混乱させる可能性もあります。 コンテナを対象としているため、そのクラスを他の場所で再利用すると、生成されたコンテンツが一緒に表示されます。これは、必要な場合に役立ちます。 次の例では、見出しの両側に装飾的な線を追加しましたh1
のすべてのインスタンスにそれらの線があるのは合理的です。 ただし、これが発生することに気付いていなかった場合は、非常に混乱します。 コンテナルールの上のコメント行がここで役立ちます。 私は最近、パターンライブラリで作業する傾向があります。これは、これらのコンポーネントを1つの場所で適切に処理し、クラスが要素に適用されたときに何が起こるかをより明確にします。
派手な見出し
私のお気に入りの生成コンテンツのトリックの1つは、見出しのスタイルを設定することです。 以前は、達成するために追加のラッパーと絶対測位トラックを必要とする見出しスタイルを押し戻す必要がありました。 コンテンツがCMSからのものである場合、それらの冗長ラッパーを追加することはしばしば不可能です。
グリッドと生成されたコンテンツを使用すると、マークアップを追加せずに、見出しの両側に行を追加できます。 グリッドがブラウザで使用できない場合、線は使用可能なスペースに応じて拡大および縮小し、プレーンな中央のヘッダーにエレガントにフォールバックします。
マークアップは単純なh1
です。
<h1>My heading</h1>
h1
のルールでは、3列のグリッドを作成します。 grid-template-columns
の値は、 1fr
のトラックを示し、次にauto
のトラックと1fr
の最終トラックを示します。 2つの1fr
トラックは、見出しがauto
サイズのトラック内に配置する必要のあるスペースを取得した後に残った利用可能なスペースを共有します。
グリッドのないブラウザで見出しを入力するために、 center
の値でtext-align
プロパティを追加しました。
h1 { text-align: center; display: grid; grid-template-columns: 1fr auto 1fr; grid-gap: 20px; }
次に、生成されたコンテンツを追加して、見出しテキストの前後に行を追加します。 これらのルールを機能クエリでラップしているので、グリッドレイアウトのないブラウザーで奇妙な生成コンテンツを取得することはありません。
線自体は、生成されたアイテムの境界線です。
@supports (display: grid) { h1:before, h1:after { content: ""; align-self: center; border-top: 1px solid #999; } }
それがあなたがする必要があるすべてです! 同じ手法を使用して、要素の上または下の要素の両側にスタイルを追加したり、アイコンを追加したりすることもできます。 アイテムを別のトラックに配置することで、アイテムが見出しのテキストと重なる可能性がないことがわかります。これは、絶対的な位置でこの種のことを行おうとすると問題になる傾向がありました。 また、アイテムをグリッド内で互いに整列させることができる正確な方法の利点もあります。
これは、グリッドレイアウトを使用して可能な拡張機能の良い例であり、グリッドを使用した大規模な再設計に進む準備ができていない場合でも利用できます。 それは非常にわかりやすい見出しにフォールバックし、ブラウザをサポートしている人は余分なタッチを取得し、誰もがコンテンツを取得します。 同様のアプローチがEricMeyerによって採用され、生成されたコンテンツを使用して、簡単にスタイル設定および配置可能な引用符をブロック引用符要素に追加しました。
これらの小さな機能では、グリッドレイアウトを使用することを考え始めないことがよくあります。 自分のデザインをどのように実装するかを理解し始めると、それが選択するレイアウト方法であることがわかります。 このため、グリッドをコンポーネント上のページレイアウトとして考えないように勧めます。そうすると、役立つ機会をたくさん逃してしまう可能性があります。
デザインの領域に背景と境界線を追加する
生成されたコンテンツを使用してアイテムを積み上げることもできます。 実際には、複数のアイテムが特定のグリッドセルを占有する可能性があります。 これには、生成されたコンテンツとともに挿入されたアイテムを含めることができます。
次の例では、2つのコンテンツセクションと全幅のアイテムを含むデザインがあります。 コンテンツの背後には、全幅のアイテムの下にもある背景があります。
マークアップには、直接の子としてセクションと全幅要素を含むコンテナーがあり、ラインベースの配置を使用してアイテムをグリッドに配置しています。
<article class="grid"> <section class="section1"> <p>…</p> </section> <div class="full-width"> <img src=“placeholder.jpg” alt=“Placeholder”> </div> <section class="section2"> <p>…</p> </section> </article>
.grid { display: grid; grid-template-columns: 1fr 20px 4fr 20px 1fr; grid-template-rows: auto 300px auto; grid-row-gap: 1em; } .section1 { grid-column: 3; grid-row: 1; } .section2 { grid-column: 3; grid-row: 3; } .full-width { grid-column: 1 / -1; grid-row: 2; background-color: rgba(214,232,182,.5); padding: 20px 0; }
これにより、全幅の画像と2つのコンテンツセクションが配置されたレイアウトが得られます。 ただし、セクションに背景を追加すると、 section
と全幅の画像の間のrow-gap
の上で停止します。
.section { background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); }
grid-row-gap
を削除し、パディングを使用してスペースを作成した場合でも、全幅パネルの下にある背景の効果は有効になりません。
ここで、生成されたコンテンツを使用できます。 生成されたコンテンツを::before
に追加し、背景色を付けます。 他に何もしなければ、コンテンツはグリッドの最初のセルに配置されます。
.grid::before { content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); }
次に、線ベースの配置を使用してコンテンツを配置し、背景色を表示する領域に拡大します。
.grid::before { content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); grid-column: 2 / 5; grid-row: 1 / 4; }
このCodePenで完全な例を見ることができます。
z-index
スタックを制御する
上記の例では、生成されたコンテンツは::before
で挿入されます。 これは、他の要素がその後に来ることを意味します。それはスタックの一番下にあるので、残りのコンテンツの後ろに表示されます。 z-index
を使用してスタックを制御することもできます。 ::before
セレクターを::after
に変更してみてください。 生成されたコンテンツの背景は、境界線が画像の上を走る方法からわかるように、すべての上に配置されます。 これは、グリッドコンテナの最後のものになり、最後にペイントされて「上」に表示されるためです。
これを変更するには、この要素に他のすべてよりも低いz-index
プロパティを指定する必要があります。 他にz-index
値がない場合、最も簡単な方法は、生成されたコンテンツに-1
のz-index
を与えることです。 これにより、 z-index
が最も低いアイテムとして、スタックの最初のものになります。
.grid::after { z-index: -1; content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); grid-column: 2 / 5; grid-row: 1 / 4; }
この方法で背景を追加することは、コンテンツの背後に背景を完全にドロップすることに限定する必要はありません。 デザインの一部の背後にある色のブロックをポップできると、いくつかの興味深い効果が生まれる可能性があります。
これは、仕様が将来解決する可能性があるものですか?
背景と境界線を追加することは、CSSグリッド仕様の欠落している機能のように感じられ、ワーキンググループがコミュニティの多くのメンバーと話し合っています(ディスカッションスレッドはGitHubにあります)。
生成されたコンテンツでは簡単に解決できないユースケースがある場合は、そのスレッドに考えを追加してください。 コメントとユースケースは、この機能に開発者の関心があることを示し、提案があなたが行う必要のある種類のことをカバーしていることを確認するのに役立ちます。
その他の例をお願いします!
この記事で生成コンテンツを試すように勧められている場合、またはすでに例がある場合は、コメントに追加してください。 誰もが本番環境でグリッドを使用するのは初めてなので、「私はそれについて考えたことはありませんでした。 グリッドを他のレイアウト方法と組み合わせるため、必要な瞬間があります。