シンプルなCSSで実装できる!記事は中央に固定幅、画像は幅いっぱいに、フルブリードレイアウトを実装するテクニック
Post on:2020年10月16日
記事のテキストが多いサイトで見かけるレイアウト、記事は中央に固定幅、画像は幅いっぱいに表示するフルブリードレイアウトをシンプルなHTMLとCSSで実装するテクニックを紹介します。
記事の固定幅は自由自在、画像の幅いっぱいも最大値を制限するなども簡単にでき、いろいろな応用も効く実装テクニックです。
Full-Bleed Layout Using CSS Grid
by Josh Comeau
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
以前、誰もが実装しようと努力したゴールドスタンダードのレイアウトがありましたが、そのレイアウトを正しく実装するのは非常に困難でした。
そのレイアウトとは、聖杯レイアウト(Holy Grail Layout)です。
聖杯レイアウト(Holy Grail Layout)
ぱっと見、難しいことではないように思いますよね。しかし、当時はFlexboxがない時代で、tableとfloatだけでした。どちらもこのタスクには適していません。一応、技術的には可能でしたが、トリッキーなテクニックが必要でした。
主要なブラウザがFlexboxをサポートするようになると、このレイアウトは「聖杯」からドリンクバー的な気軽な存在になりました。優れたユーザーエクスペリエンスを提供し、すべてのデベロッパーに手が届くようになったため、今では多くのWebサイトで見かけます。
Webが進化するにつれて、意欲的なレイアウトが増えてきました。特にニュース記事やドキュメントのような長文のテキストコンテンツに対して、素晴らしいユーザーエクスペリエンスを提供します。しかし、その前身のレイアウトと同様に、実装するのは意外と難しく、あいまいなハックや直感的ではないトリックが必要でした。
しかし、私は最近、CSS Gridでこの問題を解決する洗練された方法を発見しました。この記事ではそれがどのように機能するかを解説します。
CSSのレイアウトにおける問題
Wikipediaを大きなスクリーンで表示したことはありますか?
こんな感じに表示されます。
一行の幅が長すぎます!
Wikipediaはコンテナの幅を制限していないため、一行の長さは何百文字にもなるかもしれません。
テキストを読み始め、行の終わりに到達したときに、次の行の先頭に移動するのは困難です。どの行が次の行なのか、すぐに分かりますか?
私ならマウスを使って補助するでしょう。
次の行の先頭が分からないから、マウスでハイライトする
行の折り返しの問題に加えて、一般的には行が長いテキストを読むのは難しく、目を疲れさせます。
調査によると、理想的な行の長さは約65文字です。英語であれば、45-85文字が適切であると言われています。読むことは複雑なプロセスであり、わたし達デベロッパーはそれをできるだけ簡単にするように努めるべきです。
この問題の一般的な解決策は、ページの中央に固定幅の単一カラムを作成することです。このレイアウトは、オンラインマガジン、ドキュメント、ニュースサイト、ブログなど、どこでも見たことがあると思います。
私のブログも固定幅の単一カラムです。
ただし、すべてのコンテンツを制限すべきではないという複雑な要素もあります。画像や動画などは利用可能な幅いっぱいに表示されるようにしています。
画像や動画は幅いっぱいに表示される
これは「フルブリード(full-bleed)」と呼ばれるものです。フルブリードは出版用語で、フルブリードで印刷すると、用紙の端まで広がります。
このレイアウトは、実装をかなり複雑にします。すべての子を制限するのは簡単ですが、一部の子だけを制限するCSSのメカニズムはありません。
解決策
さっそく、始めてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.wrapper { display: grid; grid-template-columns: 1fr min(65ch, 100%) 1fr; } .wrapper > * { grid-column: 2; } .full-bleed { width: 100%; grid-column: 1 / 4; } |
上記のスタイルシートは、下記のマークアップに割り当てられます。
1 2 3 4 5 |
<main class="wrapper"> <h1>Some Heading</h1> <p>Some content and stuff</p> <img class="full-bleed" alt="cute meerkat" src="/meerkat.jpg" /> </main> |
ここで使用しているテクニックはいくつかあるので、順番に解説します。
CSS Grid
1 2 3 4 5 6 7 |
.wrapper { display: grid; grid-template-columns: 1fr min(65ch, 100%) 1fr; } |
CSS Gridに慣れていない場合、ランダムな文字やキーワードがたくさんあるように感じるかもしれません。
心配はいりません、すべて説明します。
display: grid;はCSS Gridを使用する時に親要素に定義するただの決まり文句です。
grid-template-columnsプロパティは、グリッドの形状を定義するためのプロパティです。3つの値を定義することで、3つのカラムが必要であることを示しています。
3つの値は各カラムの幅を定義します。最初のカラムは1frで、最後のカラムと同じです。単位のfrは、利用可能なスペースを占める柔軟な単位です。原理的にはflex-growと似ていますが、これはカラムがどのくらいの空きスペースを消費するかの比率となります。
中央のカラムの幅は固定です。min()を使用して、どちらか小さい方の値が使用されます。大きなスクリーンでは65chになり、65文字のスペースがない小さなスクリーンでは利用可能なコンテナ幅の100%が使用されます。
実際にどのように見えるか確認しておきましょう。
grid-template-columnsで実装した3カラムのレイアウト
単位のchとは
前述したように、各行の幅が65文字になるようにテキストの長さを固定したいと思います。pxを単位にして幅を「推測」することはできますが、CSSにはもっと便利な単位があります。
1 2 3 4 5 6 |
.wrapper { /* 🙅♀️ 65文字だと800pxくらい?推定の幅 */ width: 800px; /* 🙆♀️ 65文字分ぴったりの理想的な幅 */ width: 65ch; } |
chは、pxやremと同じ単位です。現在使用しているフォントの指定されたサイズで0文字の幅になります。幅をピクセルで推定するのはなく、文字の数で指定できます。
実際には多少の調整が必要になるかもしれません。例えば、フォントの0文字だけの幅が狭い場合は、値を少し大きくする必要があります。
子カラムの割り当て方
3カラムのグリッドを定義したので、次に子を割り当てます。
デフォルトでは、子は最初に利用可能なグリッドセルに配置されます。しかし、このデフォルトを上書きし、2番目を中央カラムにし、1と3番目は空のままにします。
1 2 3 |
.wrapper > * { grid-column: 2; } |
このスタイルシートで、2番目が中央カラムになります。
アスタリスク(*)はワイルドカードで、すべての子要素に一致します。このセレクタで、.wrapperのすべての子を2番目の中央のカラムに割り当てることができます。これで、見出しも記事もすべての子は中央カラムに配置されます。
*で、すべての子を中央に割り当て
ワイルドカードのパフォーマンス
ワイルドカードセレクタ(*)を使用するのは、悪い習慣だと聞いたことがあるかもしれません。遅いし、ページ全体のパフォーマンスに影響を与える可能性があると言う人もいるでしょう。
しかし、それは事実ではありません。何度も何度も論破されています。コンピュータの速度が遅く、ブラウザの最適化が不十分だった2009年でも、問題ではありませんでした。ワイルドカードセレクタのパフォーマンスに関する懸念は、都市伝説です。
子をフルブリードにする
グリッドがあらゆるタイプの要素を制約する方法を見てきました。では、子要素を自由にして利用可能な幅を占めたい場合はどうすればよいでしょうか?
いよいよ、登場です!
1 2 3 4 |
.full-bleed { width: 100%; grid-column: 1 / 4; } |
この特別な.full-bleedは、特定の子要素がカラムから抜け出して、3つのカラムすべてにまたがることを可能にします。1 / 4は、開始/終了の構文です。つまり、要素はカラム1(包括的)から始まり、カラム4(排他的)までの範囲を指定しています。
.full-bleedを与えたカラムだけが幅いっぱいに表示される
このテクニックは、各子要素が自分のグリッド行になり、その行を必要なだけ占めることができます。ほとんどの要素はその中央のカラムのみを占有しますが、その代わりに3つのカラムすべてにまたがる要素もあります。
相反するスタイル
.full-bleedの子要素が、grid-columnの値と矛盾していることに気がついたかもしれません。
1 2 3 4 |
/* ワイルドカード(*)セレクターから */ grid-column: 2; /* .full-bleedクラスから */ grid-column: 1 / 4; |
これはCSSの詳細度により、問題なく機能します。
.full-bleedはワイルドカードセレクタ(*)よりも詳細度が高いため、優先されます。.full-bleedが勝つことが分かっているので、意図的に競合を設定しています。
ワイルドカードセレクタの利点は、常にこれらの戦闘に負けることです。したがって、デフォルト値を定義する時に便利です。
まとめ
このテクニックの素晴らしいところは、非常に柔軟なことです。
もしかすると、子要素がフルブリードになることを望まないかもしれません。例えば、超ワイドスクリーンでは、かなり大きくなる可能性があります。少し調整するだけで、一定の幅に固定することもできます。
1 2 3 4 5 6 7 8 9 |
.pseudo-full-bleed { width: 100%; grid-column: 1 / 4; /* 非常に大きなスクリーンの幅を制限する */ max-width: 1500px; /* 要素を中央に配置 */ margin-left: auto; margin-right: auto; } |
超ワイドスクリーンに対応したフルブリード
CSS Gridは非常に強力で、現在では幅広いブラウザのサポートが実現されているため、多くの問題を解決できます。
CSS Gridについてもっと詳しく書くつもりですので、もっと知りたい場合はニュースレターに参加してください 💖
sponsors