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

この投稿では、負担の大きい作業を行い、堅牢でモダンなレイアウトを構築するための優れた CSS 行をいくつか紹介します。

最新の CSS レイアウトでは、わずか数回のキー入力だけで、非常に意味のある堅牢なスタイル設定ルールを作成できます。上記の講演とこの投稿では、重い処理を担う強力な CSS の 10 行について説明します。

これらのデモを自分で試すには、上記の 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 つのアイテムが 1 行に並べられ、通常は画像、タイトル、商品の特徴を説明するテキストが表示されます。モバイルでは、それらの要素がきれいに積み重なり、画面サイズが大きくなるにつれて拡大されるようにする必要があります。

このエフェクトに 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

分解パンケーキとは異なり、このサンプルでは、画面サイズが変更されても子要素はラップされません。このレイアウトは一般に「固定フッター」と呼ばれます。ウェブサイトやアプリ、モバイルアプリ(フッターは通常ツールバーです)、ウェブサイト(シングルページ アプリケーションでは、このグローバル レイアウトがよく使用されます)でよく使用されます。

コンポーネントに display: grid を追加すると、1 列のグリッドが作成されますが、メイン領域はコンテンツの高さのみで、その下にフッターが表示されます。

フッターを下部に固定するには、次のように追加します。

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

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

05. 従来の「Holy Grail」レイアウト: 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 列のトラック グリッドが作成されました。このグリッドに子を配置できます。グリッド線を使用して配置するのが 1 つの方法です。たとえば、grid-column: 1 / 13 は最初の行から最後の行(13 列目)までをカバーし、12 列になります。grid-column: 1 / 5; は最初の 4 つにまたがります。

span キーワードを使用する方法もあります。span では、開始線と、その開始点から延びる列数を設定します。この場合、grid-column: 1 / span 12grid-column: 1 / 13 と同等で、grid-column: 2 / span 6grid-column: 2 / 8 と同等です。

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

07. RAM(繰り返し、自動、最小最大): 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 px を超えると、残りのスペース全体を埋めるようにボックスが引き延ばされます。ただし、これを 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 を使用して方向が列に設定されます。

これにより、タイトル、説明、画像ブロックが親カード内の縦列に配置されます。次に、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 に関する問題など、私自身が何度も直面してきた多くの開発者の悩みを解決できるため、知っておくことをおすすめします。

まとめ

ここまでお付き合いいただきありがとうございました。詳しくは、動画全体を視聴し、デモをお試しください。