レイアウト

CSS ポッドキャスト - 009: レイアウト

あなたが開発者として働いており、デザイナーの同僚から新しいウェブサイトのデザインを渡されました。このデザインには、ビューポートの幅と高さを考慮した 2 次元レイアウトや、可変性と柔軟性が求められるレイアウトなど、あらゆる種類の興味深いレイアウトと構成が用意されています。CSS でこれらのスタイルを設定する最良の方法を決定するにはどうすればよいでしょうか。

CSS では、横軸、縦軸、またはその両方でのレイアウトの問題を解決するためのさまざまな方法が提供されます。コンテキストに適したレイアウト方法を選択するのは困難であり、多くの場合、問題を解決するために複数のレイアウト方法が必要になることがあります。そのために、以降のモジュールでは、そのような判断に役立つ各 CSS レイアウト メカニズムに固有の機能について説明します。

レイアウト: 簡単な歴史

ウェブの初期の頃は、<table> 要素を使用して、単純なドキュメントよりも複雑なデザインでレイアウトする必要がありました。90 年代後半に CSS がブラウザに広く採用されたことで、HTML とビジュアル スタイルを区別しやすくなりました。CSS により、デベロッパーが HTML に触れることなくウェブサイトのデザインを完全に変更できるようになりました。 この新機能は、The CSS Zen Garden などのプロジェクトに影響を与えました。これは、より多くのデベロッパーに CSS の学習を促す能力を示す目的で作成されました。

CSS は、ウェブデザインとブラウザ テクノロジーに対するニーズの進化に伴い進化してきました。CSS レイアウトとレイアウトに対する Google のアプローチが時間の経過とともにどのように進化してきたかについては、Rachel Andrew によるこちらの記事をご覧ください。

1996 年から 2021 年までの CSS の進化の推移を示すタイムライン

レイアウト: 現在と未来

最新の CSS には、極めて強力なレイアウト ツールが用意されています。 Google にはレイアウト専用のシステムがあり、使用できる機能の概要を確認してから、Flexbox と Grid の詳細について次のモジュールで説明します。

display プロパティについて

display プロパティは 2 つのことを行います。まず、適用するボックスがインラインかブロックかを判断します。

.my-element {
  display: inline;
}

インライン要素は文中の単語のように動作します。 これらはインラインの方向に並んで配置されます。<span><strong> などの要素は、通常、<p>(段落)のような要素内のテキストのスタイル設定に使用されます。デフォルトでは、インライン化されています。また、周囲の空白も保持されます。

さまざまなサイズの箱と、各サイズ調整セクションの始点と終点を示した図

インライン要素に明示的に幅と高さを設定することはできません。ブロックレベルのマージンとパディングは、周囲の要素によって無視されます。

.my-element {
    display: block;
}

ブロック要素は互いに並んで配置されません。 ユーザーは新しい行を作成します。他の CSS コードで変更されない限り、ブロック要素はインライン ディメンションのサイズに拡張されるため、横書きの場合は全幅に展開されます。ブロック要素の上下左右のマージンが優先されます。

.my-element {
    display: flex;
}

display プロパティは、要素の子の動作も決定します。たとえば、display プロパティを display: flex に設定すると、ボックスがブロックレベルのボックスになり、その子も Flex アイテムに変換されます。これにより、アライメント、順序、フローを制御する Flex プロパティが有効になります。

Flexbox および Grid

複数の要素のレイアウト ルールを作成する主なレイアウト メカニズムには、flexboxgrid の 2 つがあります。両者は共通点がありますが、異なるレイアウトの問題を解決するように設計されています。

フレックスボックス

.my-element {
    display: flex;
}

Flexbox は、1 次元レイアウトのレイアウト メカニズムです。1 つの軸(水平方向または垂直方向)をまたぐレイアウト。 デフォルトでは、Flexbox は、要素の子をインライン方向の隣り合わせに揃え、ブロック方向に引き伸ばすため、すべて同じ高さになります。

アイテムは、スペースが足りなくなっても折り返しずに同じ軸上に配置されます。 代わりに、互いに同じ行に押し寄せようと試みます。この動作は、align-itemsjustify-contentflex-wrap プロパティを使用して変更できます。

また、子要素は Flex アイテムに変換されます。つまり、Flex コンテナ内で子要素がどのように動作するかに関するルールを記述できます。個々のアイテムで配置、順序、理由を変更できます。 flex プロパティを使用して、縮小または拡大の方法を変更することもできます。

.my-element div {
    flex: 1 0 auto;
}

flex プロパティは、flex-growflex-shrinkflex-basis の省略形です。上記の例は次のように展開できます。

.my-element div {
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: auto;
}

デベロッパーはこれらの低レベルのルールを提供することで、コンテンツとビューポートの寸法が要求されるときにレイアウトがどのように動作するかをブラウザに伝えることができます。そのため、レスポンシブ ウェブ デザインの非常に便利なメカニズムとなります。

グリッド

.my-element {
    display: grid;
}

グリッドは Flexbox と多くの点で類似していますが、単軸レイアウト(垂直または水平方向のスペース)ではなく、多軸レイアウトを制御するように設計されています。

グリッドを使用すると、display: grid を持つ要素にレイアウト ルールを記述できます。また、レイアウト スタイル設定用の新しいプリミティブ(repeat() 関数や minmax() 関数など)もいくつか導入されます。便利なグリッド ユニットの 1 つが fr ユニット(残りのスペースの一部)です。従来の 12 列のグリッドを作成し、各項目の間にギャップを設け、次の 3 つの CSS プロパティを設定できます。

.my-element {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

上記の例は、単軸のレイアウトを示しています。 フレックスボックスでは主にアイテムをグループとして扱いますが、グリッドを使用すると 2 次元でアイテムの配置を正確に制御できます。このグリッドの最初のアイテムは 2 行 3 列と定義できます。

.my-element :first-child {
  grid-row: 1/3;
  grid-column: 1/4;
}

grid-row プロパティと grid-column プロパティは、グリッド内の最初の要素が最初の列から 4 列目の始まり、最初の行から 3 行目までスパンするように設定します。

Flow レイアウト

グリッドや Flexbox を使用しない場合、要素は通常のフローで表示されます。通常のフローのときに、アイテムの動作と位置を調整するために使用できるレイアウト メソッドがいくつかあります。

インライン ブロック

インライン要素の周囲の要素では、ブロック マージンとパディングが無視されることを覚えていますか?inline-block では、これを行えます。

p span {
    display: inline-block;
}

inline-block を使用すると、ブロックレベルの要素の特性を含みながら、テキストに合わせてインラインで移動するボックスが作成されます。

p span {
    margin-top: 0.5rem;
}

浮動小数点

テキストを 1 段落程度に収める画像がある場合、そのテキストは新聞のように画像を囲むことが便利ではないでしょうか。これは浮動小数点数で行うことができます。

img {
    float: left;
    margin-right: 1em;
}

float プロパティは、指定された方向に「浮動」するように要素に指示します。この例の画像は左にフロートするように指示されており、これにより兄弟要素を囲むことができます。leftrightinherit をフロートするように要素に指示できます。

複数列レイアウト

世界の国々のリストなど、非常に長い要素のリストがある場合、スクロールの回数が多くなり、ユーザーにとっては多くのスクロール時間が無駄になる可能性があります。また、ページに余分な空白が生じることもあります。 CSS 複数列を使用すると、これらを複数の列に分割して、この両方の問題に対処できます。

<h1>All countries</h1>
<ul class="countries">
  <li>Argentina</li>
  <li>Aland Islands</li>
  <li>Albania</li>
  <li>Algeria</li>
  <li>American Samoa</li>
  <li>Andorra</li>
  …
</ul>
.countries {
    column-count: 2;
    column-gap: 1em;
}

これにより、長いリストが自動的に 2 つの列に分割され、2 つの列の間にギャップが追加されます。

.countries {
    width: 100%;
    column-width: 260px;
    column-gap: 1em;
}

コンテンツを分割する列の数を設定する代わりに、column-width を使用して必要な最小幅を定義することもできます。ビューポートのスペースが増えると、自動的により多くの列が作成され、スペースが減ると列も減ります。これは、レスポンシブ ウェブ デザインの文脈で非常に役立ちます。

位置付け

最後は、レイアウト メカニズムの概要です。position プロパティは、ドキュメントの通常のフローでの要素の動作と、他の要素との関係を変更します。使用できるオプションは relativeabsolutefixedsticky で、デフォルト値は static です。

.my-element {
  position: relative;
  top: 10px;
}

この要素は、ドキュメント内の現在の位置に基づいて、自身に対して相対的に配置されるため、10 ピクセル下に移動されます。要素に position: relative を追加すると、その要素は position: absolute を持つすべての子要素の包含ブロックにもなります。つまり、子に絶対位置が適用されている場合、子は最上位の相対親ではなく、この特定の要素に再配置されます。

.my-element {
  position: relative;
  width: 100px;
  height: 100px;
}

.another-element {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 50px;
    height: 50px;
}

positionabsolute に設定すると、要素が現在のドキュメント フローから切り離されます。つまり、次の 2 つの意味があります。

  1. この要素は、最も近い相対親で toprightbottomleft を使用すると、任意の場所に配置できます。
  2. 絶対要素の周囲のすべてのコンテンツがリフローされ、その要素が残った残りのスペースを埋めます。

position の値が fixed の要素は absolute と同様に動作し、親がルートの <html> 要素です。固定位置要素は、設定した toprightbottomleft の値に基づいて左上から固定されたままになります。

sticky を使用することで、fixed の固定的な側面と、relative の予測可能なドキュメント フローに従うことを実現できます。この値を使用すると、ビューポートが要素を通過してスクロールする際、設定した toprightbottomleft の値に固定されたままになります。

まとめ

CSS レイアウトには多くの選択肢があり、柔軟性も備えています。CSS の FlexboxGrid の機能の詳細については、以降のモジュールに進みましょう。

理解度チェック

レイアウトに関する知識をテストする

display プロパティの機能は何ですか。2 つ選択してください。

inlineblocknone のいずれかになります。
レイアウト エンジンは、このボックスが全幅であるかどうかを認識する必要があり、また改行が必要です。
グリッド レイアウトのフレームを決定します。
display プロパティでは、display を grid に設定できますが、レイアウト フレームとは関係ありません。
子をどのように動作させるかを決定します。
Flexbox とグリッドには、お子様向けの意見や新機能があります。
ボックスをスクロールするかどうかを決定します。
それが overflow プロパティです。

複数の段落を列に並べるための最適な CSS プロパティは、次のうちどれですか。

display: grid
グリッドでは複数の段落を列に配置できますが、それらの列はそれぞれの列として機能し、ある段落から次の段落へ流れるわけではありません。
column-count
雑誌や新聞のように、段落の最後から次の列の始まりに向かって段落が流れます。
display: flex
flex では複数の段落を列に配置できますが、それらの列は独自の列になるため、1 つの列から次の列へと流れるような方法は必要ありません。
float
もう一度考えてみましょう。

ブロックがフローされていない状態とは、どういう意味でしょうか。

川のほとりに詰まっている。
ここでは、コンテキストは地理ではなく CSS です。
top または left の位置値が付与されている。
これらのプロパティだけでは、フローから外に出る必要はありません。
兄弟ノードに基づく位置付けは行われなくなりました。
たとえば、position: absolute のボックスは、他の兄弟要素の順序ではなく、含まれるブロックに基づいて x 座標と y 座標で配置されます。

Flexbox と Grid はデフォルトで子をラップしますか?

正しい
flex-wrap: wrap または repeat(auto-fit, 30ch) で有効にする必要があります。
誤り
Flexbox と Grid には、適用するために追加のスタイルを必要とする特別なラップ機能があります。