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

この記事では、強力な CSS の行をいくつか紹介します。これらの行は、重い処理を担い、堅牢でモダンなレイアウトの構築に役立ちます。

最新の CSS レイアウトでは、デベロッパーは数回のキー入力で、本当に意味のある堅牢なスタイル設定ルールを記述できます。上記の講演とこの投稿では、重い処理を担う強力な CSS の 10 行について説明します。

これらのデモを自分で試すには、上記の Glitch 埋め込みをチェックするか、1linelayouts.glitch.me にアクセスしてください。

01. スーパー センター: place-items: center

最初の「単一行」レイアウトでは、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 を使用すると、画面のサイズ変更時にこれらの要素の配置を調整するためにメディアクエリを使用する必要がなくなります。

flex の省略形は flex: <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 です。スペース区切りの最初のリストと 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));
}

repeat を再度使用していますが、今回は明示的な数値ではなく 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 です。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 の場合に、私自身が何度も直面した多くの開発者の悩みを解決できるため、知っておくことをおすすめします。

まとめ

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