1 行の CSS で 10 種類のレイアウトを

この投稿では、負荷の大きい作業を行い、堅牢な最新のレイアウトの構築に役立つ、強力な CSS をいくつか紹介します。

最新の CSS レイアウトにより、デベロッパーは数回のキー入力だけで、実に意味のある堅牢なスタイル設定ルールを記述できます。先ほどの講演と後続の投稿では、重い作業を行う 10 の優れた CSS 行を見ていきます。

これらのデモを自分で確認したり、プレイしたりするには、上記の Glitch の埋め込みを確認するか、1linelayouts.glitch.me にアクセスしてください。

01. スーパー中央揃え: place-items: center

最初の「1 行」レイアウトでは、すべての CSS 領域における最大の謎である、物事を中央に配置するという問題を解決します。place-items: center は想像以上に簡単です。

まず、display メソッドとして grid を指定し、同じ要素に place-items: center を書き込みます。place-items は、align-itemsjustify-items の両方を一度に設定する簡略記法です。center に設定すると、align-itemsjustify-items の両方が center に設定されます。

.parent {
  display: grid;
  place-items: center;
}

これにより、本来のサイズに関係なく、コンテンツを親の内部に完全に中央に配置できます。

02. ディコンストラクト パンケーキ: flex: <grow> <shrink> <baseWidth>

次は、分解されたパンケーキです。これはマーケティング サイトで一般的なレイアウトです。たとえば、3 つのアイテムの行で、通常は画像、タイトル、その後に商品の特長を説明するテキストで構成されます。モバイルでは、これらをうまく積み重ね、画面サイズが大きくなるにつれて拡張する必要があります。

この効果に Flexbox を使用すると、画面のサイズ変更時にこれらの要素の配置を調整するためにメディアクエリを使用する必要がなくなります。

flexflex: <flex-grow> <flex-shrink> <flex-basis> の略です。

そのため、ボックスを <flex-basis> サイズまで埋める場合、小さいサイズでは縮小しますが、追加のスペースを埋めるために引き伸ばされないようにするには、flex: 0 1 <flex-basis> と記述します。この場合、<flex-basis>150px であるため、次のようになります。

.parent {
  display: flex;
}

.child {
  flex: 0 1 150px;
}

ボックスが引き伸ばされてスペースを埋めるようにして次の行にボックスを埋めるようにするには、<flex-grow>1 に設定します。たとえば次のようになります。

.parent {
  display: flex;
}

.child {
  flex: 1 1 150px;
}

現在では、画面サイズを増減すると、これらの Flex アイテムは縮小および拡大します。

03. サイドバーに表示されるメッセージ: grid-template-columns: minmax(<min>, <max>) …)

このデモでは、グリッド レイアウトに minmax 関数を使用しています。ここでは、サイドバーの最小サイズを 150px に設定していますが、大画面では 25% まで広げることができます。25%150px より小さくなるまで、サイドバーは常に親の水平方向のスペースの 25% を占めます。

これを grid-template-columns の値として追加します。minmax(150px, 25%) 1fr という値になります。最初の列(この場合はサイドバー)のアイテムは 25%150pxminmax になり、2 番目のアイテム(ここでは main セクション)が 1 つの 1fr トラックとして残りのスペースを占めます。

.parent {
  display: grid;
  grid-template-columns: minmax(150px, 25%) 1fr;
}

04. パンケーキ スタック: grid-template-rows: auto 1fr auto

Destructed Pancake とは異なり、この例では、画面サイズが変わっても子をラップしません。一般に固定フッターと呼ばれるこのレイアウトは、ウェブサイトとアプリの両方で使用されます。また、モバイルアプリ(フッターはツールバーが一般的)とウェブサイト(シングルページ アプリケーションでは、このグローバル レイアウトがよく使用されます)にわたって使用されます。

コンポーネントに display: grid を追加すると、グリッドが 1 列になりますが、メインエリアの高さは、その下にフッターがあるコンテンツと同じ高さになります。

フッターを下部に固定するには、以下を追加します。

.parent {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

これにより、ヘッダーとフッターのコンテンツが子のサイズを自動的に取得するように設定され、残りのスペース(1fr)がメイン領域に適用されます。一方、auto サイズの行はその子コンテンツの最小サイズを使用するため、コンテンツのサイズが大きくなると、行自体も調整されます。

05. 従来の聖杯のレイアウト: grid-template: auto 1fr auto / auto 1fr auto

このクラシックなレイアウトには、ヘッダー、フッター、左のサイドバー、右のサイドバー、メイン コンテンツがあります。前のレイアウトに似ていますが、サイドバーが追加されました。

1 行のコードでこのグリッド全体を書き込むには、grid-template プロパティを使用します。これにより、行と列の両方を同時に設定できます。

プロパティと値のペアは grid-template: auto 1fr auto / auto 1fr auto です。1 番目と 2 番目のスペース区切りリストの間にあるスラッシュは、行と列を区切るものです。

.parent {
  display: grid;
  grid-template: auto 1fr auto / auto 1fr auto;
}

前の例(ヘッダーとフッターのコンテンツのサイズが自動設定されていた場合)と同様に、左右のサイドバーは、子が本来備わっているサイズに基づいて自動的にサイズ設定されます。ただし、今回は縦(高さ)ではなく横のサイズ(幅)です。

06. 12 スパン グリッド: grid-template-columns: repeat(12, 1fr)

次に、もう一つの典型的な例が 12 スパン グリッドです。repeat() 関数を使用すると、CSS でグリッドを簡単に記述できます。グリッド テンプレート列に repeat(12, 1fr); を使用すると、1fr 列がそれぞれ 12 列になります。

.parent {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.child-span-12 {
  grid-column: 1 / 13;
}

12 列のトラックのグリッドができあがったので、このグリッドに子を配置できます。これを行う方法の一つは、グリッド線を使用して配置することです。たとえば、grid-column: 1 / 13 は最初の行から最後の行(13 列目)にまたがり、12 列にまたがります。grid-column: 1 / 5; は最初の 4 つにまたがります。

span キーワードを使用して記述することもできます。span では、開始線を設定し、その開始点からスパンする列の数を設定します。この場合、grid-column: 1 / span 12grid-column: 1 / 13grid-column: 2 / span 6grid-column: 2 / 8 と同等です。

.child-span-12 {
  grid-column: 1 / span 12;
}

07. RAM(繰り返し、自動、MinMax): grid-template-columns(auto-fit, minmax(<base>, 1fr))

この 7 つ目の例では、これまでに学習したコンセプトを組み合わせて、自動的に配置される柔軟な子を持つレスポンシブ レイアウトを作成します。とても便利です。ここで覚えておくべき主な用語は repeatauto-(fit|fill)minmax()' です。これらは「RAM」の頭字語で覚えています。

まとめると、次のようになります。

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

繰り返しを使用しますが、今回は明示的な数値ではなく auto-fit キーワードを使用します。これにより、これらの子要素の自動配置が可能になります。これらの子も、基本の最小値は 150px で、最大値は 1fr です。つまり、小さい画面では 1fr の幅いっぱいになり、それぞれの幅が 150px になると同じ行に流れ始めます。

auto-fit を使用すると、ボックスは水平方向のサイズが 150 ピクセルを超えて引き伸ばされ、残りのスペース全体を埋めます。ただし、これを auto-fill に変更すると、minmax 関数でベースサイズを超えても引き伸ばされません。

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

08. ラインナップ: justify-content: space-between

次のレイアウトでは、ここで示す主なポイントは justify-content: space-between です。これにより、最初と最後の子要素が境界ボックスの端に配置され、残りのスペースは要素間に均等に分配されます。これらのカードは Flexbox 表示モードに配置され、方向は flex-direction: column を使用して列に設定されます。

タイトル、説明、画像ブロックが親カード内の縦の 1 列に表示されます。次に、justify-content: space-between を適用すると、最初(タイトル)と最後(画像ブロック)の要素がフレックス ボックスの端に固定され、これらの間にある説明テキストが各端点に等間隔で配置されます。

.parent {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

09. スタイルを固定: clamp(<min>, <actual>, <max>)

ここでは、ブラウザのサポートは少ないものの、レイアウトとレスポンシブ UI デザインに大きな影響を与える手法をいくつか紹介します。このデモでは、width: clamp(<min>, <actual>, <max>) のようにクランプを使用して幅を設定します。

これにより、最小サイズと最大サイズ、実際のサイズが設定されます。値を使用すると、次のようになります。

.parent {
  width: clamp(23ch, 60%, 46ch);
}

最小サイズは 23ch(半角 23 文字)単位、最大サイズは 46ch(46 文字)です。文字幅の単位は、要素のフォントサイズ(特に 0 グリフの幅)に基づきます。「実際の」サイズは 50% で、この要素の親の幅の 50% を表します。

ここでの clamp() 関数の役割は、50% が 46ch(広いビューポートの場合)または 23ch(小さいビューポートの場合)より小さくなるまで、この要素の幅を 50% に維持することです。親サイズを拡大、縮小すると、このカードの幅がクランプされた最大ポイントまで拡大し、クランプされた最小ポイントまで減少します。その後は、追加のプロパティを適用して親の中心に配置したので、親の中心に保たれます。これにより、テキストの幅が広すぎたり(46ch 以上)、狭くなりすぎたり(23ch 未満)することがなくなるため、より読みやすいレイアウトになります。

これは、レスポンシブ タイポグラフィの実装にも最適です。たとえば、「font-size: clamp(1.5rem, 20vw, 3rem)」のように入力します。この場合、見出しのフォントサイズは常に 1.5rem3rem の間に収まりますが、20vw の実際の値に基づいて、ビューポートの幅に合わせて拡大 / 縮小します。

これは、最小サイズと最大サイズの値によって読みやすくするための優れた手法ですが、最新のすべてのブラウザでサポートされているわけではないため、代替手段を用意してテストしてください。

10. アスペクトの尊重: aspect-ratio: <width> / <height>

最後のレイアウト ツールは、最も試験運用版のツールです。最近 Chromium 84 で Chrome Canary に導入されました。Firefox ではこの機能の実装に向けて積極的な取り組みが進められていますが、現在のところ、安定したブラウザ エディションでは利用できません。

しかし、これは頻繁に直面する問題なので、そのことに言及しておきます。これは単に画像のアスペクト比を維持するだけです。

aspect-ratio プロパティを使用すると、カードのサイズを変更したときに、緑色のビジュアル ブロックでこの 16 x 9 のアスペクト比が維持されます。aspect-ratio: 16 / 9 ではアスペクト比を尊重します。

.video {
  aspect-ratio: 16 / 9;
}

このプロパティなしで 16 x 9 のアスペクト比を維持するには、padding-top ハックを使用してパディングを 56.25% とし、上と幅の比率を設定する必要があります。ハッキングを回避し、割合を計算する必要性を避けるため、まもなくこれに対応するプロパティが用意される予定です。比率 1 / 1 の正方形、2 / 1 の 2 対 1 の比率など、設定されたサイズ比率でこの画像をスケーリングするために必要なすべてのものを作成できます。

.square {
  aspect-ratio: 1 / 1;
}

この機能はまだ公開中ですが、特に動画や iframe に関しては、私が何度も直面した開発者の多くの苦労が解決してくれるので、知っておくとうれしい機能です。

まとめ

CSS の 10 行をご覧いただき、ありがとうございました。詳細については、動画全体を視聴し、ご自身でデモをお試しください。