Skip to content
This page has been auto-translated and may contain errors.View in English

表示とノーマルフロー

docs.scrimba.com

CSS をまったく使わないページに 3 つの段落とリンクを 2 つ配置すると、それでも自動的にレイアウトされます。段落はページ下方に積み重なり、リンクはあなたが書いたテキストの中に配置されます。ブラウザに指示を出したわけではありません。最初の 1 つのレイアウトルールを書く前に、すでにレイアウトが存在しており、後で使用するすべてのテクニックは無からの開始ではなく、それへの変更です。この章はその開始点とそれを管理する 1 つのプロパティについてです。

ノーマルフロー

ブラウザが独自のレイアウト CSS なしでページをレイアウトするとき、ノーマルフロー を使用します。これは要素が自動的に配置される方法です。段落や見出しなどのブロック要素は上から下へスタックし、それぞれが独自の行に配置されます。テキストとリンクは行内を左から右へ実行され、スペースが足りなくなると次の行に折り返されます。

フロー周辺の部分はすでに紹介しました。この章は ボックスモデル に基づいて構築されています。なぜなら、それらのボックスがフローするからです。ノーマルフローは名前を付ける価値があります。なぜなら、レイアウト内のすべてのほかのもので定義されているからです。Flexbox、グリッド、ポジショニングはすべて「デフォルトと異なる配置」を意味しているので、デフォルトを知ることが変更を理解するのに役立ちます。

ノーマルフロー は、ブラウザのデフォルトレイアウトです。flex、グリッド、float、またはポジショニングが登場する前に取得する配置です。ブロックボックスはソース順でページを下方に垂直にスタックし、各ボックスは新しい行で始まり、利用可能な幅全体を占めます。インラインボックスは行に沿って左から右へ流れ、現在の行がいっぱいになると次の行に折り返されます。

これに名前を付ける理由は、レイアウトツールがそれからの逸脱として定義されているからです。コンテナーに display: flex を設定すると、ブラウザにそのコンテナーの子をノーマルフローの代わりに flex ルールでレイアウトするように指示しています。デフォルトは決して消えません。個々のコンテナーをそこから外します。これは、スタイルシートなしのドキュメントが読みやすい理由でもあります。ノーマルフローは実際のレイアウトであり、存在しないわけではありません。

ノーマルフロー は、float、ポジショニング、flex、またはグリッドが何かを変更する前に、ブラウザが適用するデフォルトレイアウトモードです。2 つのサブモードが一緒に機能します。ブロックレイアウト はブロックレベルボックスをソース順でページの下方に垂直にスタックし、インラインレイアウト はインラインレベルボックスを行内で水平に配置し、行ボックス全体にラップします。ノーマルフロー内でレイアウトされたブロックボックスは、利用可能な幅全体を占め、新しい行で始まります。インラインボックスは、そのコンテンツとしてのみ幅を取り、現在の行内に配置されます。

正確に名前を付けることが重要です。なぜなら、レイアウトシステム全体がそれに対する代替のセットとして構築されているからです。display: flexdisplay: grid はコンテナーの 内部 レイアウトを flex または grid ルールに置き換え、position: absolute または float はボックスをノーマルフロー外に完全に引き出すため、周囲のコンテンツはそれが存在しないかのようにレイアウトされます。すべての場合において、ノーマルフロー は発散している基準線です。明示的に外に出されたり、別のレイアウトモードに渡されたりしないボックスは、まだ流れています。これは、スタイルシートなしのドキュメントが賢明な順序でレンダリングされる理由です。ブロックおよびインラインフローはデフォルトであり、フォールバックではありません。

Junoノーマルフロー ノーマルフローは無料で取得するレイアウトです。ブロックはページを下へスタックし、テキストとリンクは行に沿って実行されます。誰もそれをオンにしません。CSS を書く前に、すでにそこに存在します。レイアウト内のすべてのほかのもので、このデフォルトを変更するので、最初にデフォルトを考えるのが役立ちます。
Junoノーマルフロー ノーマルフローはブラウザのデフォルトです。ブロックはソース順で上から下へスタックし、インラインボックスは行に沿って実行され、ラップされます。Flex、グリッド、ポジショニングはすべてそこから外に出す方法であり、一度に全体への置き換えではありません。スタイルシートなしのページは、ノーマルフローが実際のレイアウトであり、1 つの不足しているため、問題なく読みます。
Junoノーマルフロー ノーマルフローは垂直にスタックするブロックレイアウトと行に沿って実行されるインラインレイアウトであり、他のものが ボックスに触れる前にデフォルトで適用されます。display: flexdisplay: grid はコンテナーの内部レイアウトを入れ替え、float または position: absolute はボックスをフロー外に引き出し、兄弟要素がそれを無視するようにします。転用されないもはすべてフロー内に留まります。スタイルシートなしのドキュメントが順番にレンダリングされるのはこのためです。

ブロックボックスとインラインボックス

ノーマルフロー内の要素には、主に 2 つの種類があります。ブロックボックス はそのコンテナーの幅全体を占め、独自の行にスタックして、次の要素を下に押します。段落 <p>、見出し <h1><div> はすべてブロックであり、これが 1 つずつ下に並ぶ理由です。

インラインボックス は異なります。テキストの行内に配置され、コンテンツに必要な分だけスペースを占めるため、複数が 1 行を共有できます。リンク <a> または <span> はインラインであり、これが文内のリンクが独自の行にジャンプするのではなく、単語のフロー内に留まる理由です。

html
<p>この段落はブロックであり、独自の行に配置されます。</p>
<p><a href="/css/box-model">ボックスモデル</a> の詳細を読んでください。</p>
<!-- リンクはインラインであり、文内に留まります -->

ノーマルフロー内のすべてのボックスはブロックレベルまたはインラインレベルとしてレイアウトされ、2 つは異なるルールに従います。ブロックボックス は新しい行で始まり、デフォルトで利用可能な幅を埋め、垂直にスタックします。<div><p><h1><section> はデフォルトでブロックです。インラインボックス は行内でテキストと一緒にフローし、そのコンテンツの幅のみを占め、行が折り返されるまで隣人の隣に配置されます。<span><a><strong> はデフォルトでインラインです。

人々を困らせる違いは、インラインボックスが何を無視するかです。インラインボックスは widthheight、および上下マージンを無視します。 <span>width: 200px を設定しても、インラインボックスはコンテンツによってサイズされるため、何も起こりません。左右の padding とマージンは適用されますが、垂直の間隔はブロック上のようにを周囲の行を離しません。

css
.tag {
  width: 200px;        /* 無視: span はインラインであり、コンテンツによってサイズされます */
  padding: 0 8px;      /* 水平 padding は動作します */
  margin-top: 40px;    /* 無視: インラインボックスで垂直マージンなし */
}

ノーマルフロー内では、ボックスはその display タイプ に基づいて、ブロックレイアウトまたはインラインレイアウトによってレイアウトされます。2 つは「スタックまたはラップ」を超えた方法で異なります。ブロックボックス はそれ自身の前後に改行を生成し、幅が与えられていない限り、それを含むブロックのインラインサイズ全体を消費し、すべての 4 つのマージンと両方の次元を尊重します。インラインボックス は行ボックスに参加し、そのコンテンツによってサイズが決定され、そのレイアウトは widthheight ではなく、行高とベースライン配置によって制御されます。

正確な部分は、インラインボックスがどのプロパティをドロップするかです。widthheight は、<span> または <a> などの置換されないインラインボックスに適用されません。そのサイズはそのコンテンツと周囲の行から来ているため。上下マージンは計算されていますが、行の高さに影響を与えないため、隣接する行を離しません。上下の padding は視覚的にレンダリングされていますが、行ボックスの高さを変更しません。そのため、隣接する行と重なる可能性があります。左右のマージンと padding は適用され、インラインの隣人をシフトさせます。<img> などの置換されたインライン要素は例外です。それらは固有の次元を持つため、インラインレベルであっても widthheight が適用されます。

css
.badge {              /* .badge は <span> であり、デフォルトではインラインです */
  width: 120px;       /* 無効: width はインラインボックスに適用されません */
  height: 40px;       /* 同じ理由で無効 */
  padding: 12px;      /* 左右が隣人をシフトします。上下は行と重なる可能性があります */
  margin: 8px 0;      /* 垂直の 8px は無視されます。水平の 0 は適用されます */
}
Junoブロックボックスとインラインボックス<p><div> などのブロックボックスは幅全体を占め、独自の行にスタックします。<span><a> などのインラインボックスは行内に配置され、必要なスペースのみを占めます。これが、リンクが独自の行に段落するのではなく、文内に留まる理由です。
Junoブロックボックスとインラインボックス ブロックボックスは幅を埋め、スタックされます。インラインボックスはコンテンツに沿って、そのコンテンツに対してフローします。落とし穴は、インラインボックスが widthheight、および垂直マージンを無視するため、<span>width を設定しても何も起こりません。水平の padding と margin はまだ機能するため、それが人々を困らせる理由です。
Junoブロックボックスとインラインボックス インラインボックスはそのコンテンツとそのラインボックスによってサイズされるため、widthheight は適用されず、垂直の margin と padding は隣接する行を離しません。水平の margin と padding は適用され、隣人をシフトさせます。例外は <img> などの置換要素です。独自の次元を持っているため、インラインの場合でも widthheight を受け入れます。

display プロパティ

すべての要素にはデフォルトの種類、ブロック、またはインラインがありますが、それに限定されません。display プロパティを使用すると、要素がどのように動作するかを変更できます。リンクに display: block を設定すると、独自の行を占めるようになります。リストアイテムに display: inline を設定すると、1 行で並べます。

3 番目の値が一般的な問題を解決します。display: inline-block です。行内のインラインボックスのようにフローしますが、ブロックのように幅、高さ、垂直 padding を受け入れます。ボタンやナビゲーション ピルなど、隣人の隣に配置する必要があるが、設定されたサイズを必要とするもの用です。

css
.nav-link {
  display: inline-block;   /* 行内にフローしますが、幅と padding を受け入れます */
  padding: 8px 16px;       /* 垂直 padding は、プレーンインラインとは異なり、機能するようになりました */
}

display プロパティはボックスがどのようにレイアウトされるかを設定し、3 つのフロー値は blockinlineinline-block です。display: block はボックスを独自の行で開始させ、要素のデフォルトに関係なく幅を埋めます。display: inline はそれを行内でフローさせ、widthheight、および垂直マージンをドロップさせます。どちらも要素の意味を変更せず、レイアウトのみを変更します。

inline-block は便利なハイブリッドです。ボックスは行内のインラインボックスのようにフローするため、複数が並べて配置されますが、ブロックのように widthheight、および垂直 padding と margin を受け入れます。flexbox に移動することなく、1 行に実際のサイズを必要とするもの(ボタンのセットまたはナビゲーション リンク)を配置します。1 行全体またはアイテムのグリッドをアライメントと間隔でレイアウトする必要がある場合、flexboxdisplay: flex がより良いツールです。inline-block はより小さなケース用です。

css
.stat {
  display: inline-block;   /* 兄弟要素と一緒に行に配置されます */
  width: 120px;            /* ただし、固定幅を使用します。これをインラインは無視します */
  padding: 12px;           /* 完全な padding が適用されます。上下を含む */
}

display はボックスのレイアウトモードを選択し、ノーマルフロー内に保つ 3 つの値は blockinlineinline-block です。block はそれ自身の前後に改行を生成して、含まれるブロックのインラインサイズを埋めるボックスを与えます。inline は行ボックスに参加し、widthheight、および垂直マージンをドロップするボックスを与えます。display を設定することは、セマンティクスに決して影響を与えません。レイアウトのみです。<div>display: inline に設定すると、DOM とアシスティブテクノロジーに対して <div> のままですが、インラインのみをレイアウトします。

inline-block は意図的なハイブリッドです。ボックスはインラインレベルであり、行ボックスに参加してインラインの隣人の隣に配置されますが、その内部はブロックとしてレイアウトされるため、widthheight、および すべての 4 つのマージンと padding が適用され、実際のレイアウトスペースを占めます。これは、flex コンテナーを使用したくない行に少数の サイズ設定されたボックス、たとえば固定幅の統計ブロックまたはナビゲーション ピルに適しています。注意点は、インラインレベルであるため、HTML 内の 2 つの inline-block 要素間のホワイトスペースが、それらの間の実際のスペースとしてレンダリングされることです。これについては、以下の詳細セクションで説明します。アライメント、分散、または完全な行全体のラップを使用する場合は、flexbox の flex レイアウトを優先します。inline-block は狭いツールであり、一般的なツールではありません。

css
.pill {
  display: inline-block;   /* インラインレベルボックス、ブロックレベルの内側 */
  width: 96px;             /* 適用されます。内部がブロックとしてレイアウトされるため */
  padding: 10px 14px;      /* すべての 4 辺がレイアウトスペースを占めます */
  margin: 0 4px;           /* 垂直マージンが適用される場合 */
}
Junodisplay プロパティdisplay プロパティは、要素がブロックまたはインラインボックスとして動作するかを変更します。block は独自の行を占め、inline はテキスト行に配置されます。便利な中間オプションは inline-block であり、行内にフローしながら、幅と padding を受け入れるため、ボタンとナビゲーション リンク用です。
Junodisplay プロパティdisplay はセマンティクスではなく、レイアウトを設定します。blockinline、またはハイブリッド inline-block。いくつかのサイズ設定されたボックスを 1 行に配置したい場合は inline-block を使用します。これは、行内でフローしますが、widthheight、および完全な padding を受け入れるためです。全体の行がアライメントと間隔を必要とする場合は、flexbox を代わりに使用します。
Junodisplay プロパティdisplay はレイアウトモードを選択し、セマンティクスは決して選択しません。そのため、インライン <div> は DOM に対して <div> のままです。inline-block はインラインレベルボックスの場合、ブロックレベルの内側であり、行内に配置されますが、widthheight、および全マージンを尊重します。サイズが設定されたボックスの少数を保持し、実際の行を flexbox に渡し、隣接するボックス間のホワイトスペースギャップに注意してください。

要素を非表示にする: display none vs visibility hidden

要素が表示されないようにする必要がある場合があります。2 つの方法があり、異なる動作をします。display: none は要素を完全に削除します。消えて、ギャップが残りません。ページに存在しないかのようです。visibility: hidden は見えなくしますが、スペースを保ちます。つまり、かつてあった場所に空の穴があります。

どちらを使用するかは、スペースを戻すかどうかに依存します。display: none を使用して、閉じたメニューのようなものを完全に削除します。visibility: hidden を使用して、レイアウトがジャンプしたくない場合、そのボックスは予約されたままです。

css
.closed-menu {
  display: none;          /* 消えた。後ろにギャップなし */
}
.placeholder {
  visibility: hidden;     /* 見えない。ただし、スペースを占め続ける */
}

要素を非表示にする 2 つの方法は交換可能ではありません。display: none は要素を完全にノーマルフローから外します。ボックスを生成せず、スペースを占めず、周囲の要素は、それが存在しないかのように閉じます。visibility: hidden はボックスをフロー内に保ち、スペースを予約するため、レイアウトは変わりません。要素は見えないのみでペイントされます。

視覚的な差と同等に重要なアクセシビリティの違いがあります。display: none の要素は、アクセシビリティツリーからも削除されるため、スクリーンリーダーはそれをスキップします。これは、折りたたまれたパネルのように、完全に存在しないコンテンツの場合は正しいです。visibility: hidden も、スペースを保持しながら、アシスティブテクノロジーからコンテンツを非表示にします。視覚的に消えたが、アシスティブテクノロジーに対して発表されるには、これらのどちらも正しくありません。これは、CSS がどのように機能するか に沿ったセマンティクスで読むことができる、見える見えないユーティリティクラスです。

css
.tab-panel[hidden] {
  display: none;          /* フローから削除され、アクセシビリティツリーから削除 */
}
.spacer {
  visibility: hidden;     /* スペースを保ちます。スクリーンリーダーに隠された状態 */
}

display: nonevisibility: hidden は両方とも非表示にしますが、フロー、ボックスツリー、アクセシビリティで異なります。display: none はボックスをまったく生成しません。要素はレイアウトから欠落し、スペースを占めず、その子孫はそれら自身の display に関係なく消えます。visibility: hidden はボックスを通常生成するため、フロー内の全スペースを占め、ペイントのみを抑制します。子孫は、display: none が決して許さない場合でも、見える見えない祖先内で visibility: visible を設定して再表示することもできます。

行動とアクセシビリティの結果が、意図的に選択する理由です。display: nonevisibility: hidden の両方要素をアクセシビリティツリーから削除するため、スクリーンリーダーはいずれも発表しません。これは、視覚的に消えたが、声が大きく読まれるコンテンツには間違っています。古典的なケースは「コンテンツにスキップ」リンクまたはスクリーンリーダーのみのラベルです。それらには、いずれかのプロパティではなく、ボックスを 1 ピクセルにクリップしながら、アクセシビリティツリーに残すことで、視覚的に非表示なパターンが必要です。さらに 2 つの実践的なメモ。display: none は、opacityvisibility の場合、状態間でアニメーション化または遷移できず、display: none に設定された要素はフォーカス可能ではなく、そのフォームコントロールは送信されません。一方、visibility: hidden コントロールも スキップされていますが、スペースが保持されています。display: none を選択して完全に削除し、visibility: hidden を選択してレイアウトを保持したまま非表示にし、アシスティブテク がまだ到達する必要がある場合はクリッピング ユーティリティを使用します。

css
.dropdown[aria-expanded="false"] .menu {
  display: none;          /* 完全に削除: ボックスなし、スペースなし、フォーカス不可 */
}
.avatar-slot {
  visibility: hidden;     /* ボックスとスペース保持。ペイント抑制 */
}
Juno要素を非表示にする: display none vs visibility hidden 2 つの隠し方: display: none は要素を削除して、ギャップを残しません。visibility: hidden は見えなくしますが、スペースを保ちます。閉じたメニューのように、スペースも消えたい場合は display: none を選択します。レイアウトがジャンプしてほしくない場合は visibility: hidden を選択します。
Juno要素を非表示にする: display none vs visibility hiddendisplay: none は要素をフロー外に引き出すため、何もスペースを予約しません。visibility: hidden はボックスとそのスペースを保ち、ペイントのみを非表示にします。どちらもスクリーンリーダーから要素を非表示にするため、視覚的に消えたが、依然として発表される場合は、どちらも正しくありません。その仕事は見える見えないユーティリティクラスに属します。
Juno要素を非表示にする: display none vs visibility hiddendisplay: none はボックスを生成せず、スペースを占めません。visibility: hidden はボックスとスペースを保ち、ペイントのみを抑制し、子供は visibility: visible を設定して再表示されることができます。どちらもアクセシビリティツリーから削除されるため、スキップリンクまたはスクリーン リーダー ラベルは、どちらのオプションではなく、クリッピング ユーティリティが必要です。display: none はアニメーション化できず、そのコントロールはフォーカス可能ではなく、送信されていません。

display が内部レイアウトを変更する方法

display がブロックとインラインを切り替えることは既に確認しています。より深いレベルでそれ以上のことを行います。同じプロパティは、コンテナーを flexbox またはグリッドに変えるもので、子要素を行と列に配置する 2 つのモダンツールです。今のところ、重要なのは、display がボックスのレイアウト方法とその内部の子要素がレイアウトされる方法を決定する 1 つのダイアルであることです。

レイアウトは、一度にオンにする 1 つの大きなスイッチではありません。異なる配置が必要な特定のコンテナーで display を変更し、残しているすべてのものはノーマルフロー内に留まります。flexbox および positioning の章は、ここから選び上げられます。

display は実際に 2 つのことを一度に制御します。ボックスがその兄弟間でどのように配置されるか、およびボックスが独自の子要素をレイアウトする方法。display: blockdisplay: inline はほぼ最初に話しています。display: flexdisplay: grid は 2 番目を変更します。コンテナーはまだ正常なフロー内でブロックとして参加しますが、その内部では、子要素はブロックおよびインラインフロー代わりに、flex または grid ルールによってレイアウトされます。

これが flexbox に移動する理由は、フロー について知っているすべてを捨てません。Flex コンテナーは、その親のノーマルフロー内ではまだブロックボックスです。その子のみがレイアウトモードを切り替えます。ノーマルフローはその周囲でデフォルトのままであり、異なる配置が必要な特定のコンテナーで flex または grid にオプトインします。positioning の章は、フロー内の完全にボックスを取得する別の方法をカバーしています。むしろ子が配置する方法を変更します。

display の値は実際に 2 つの種類を一度に示しています。外側 種類は、ボックスが親のレイアウトに参加する方法を述べ、内側 種類は、ボックスが独自の子要素をレイアウトする方法を述べています。display: block は外側ブロック、内側フロー。display: flex は外側ブロック、内側フロー。display: inline-flex は外側インライン、内側 flex。これが、flex コンテナーが外側の種類を変更せず、ブロックとしてノーマルフロー内に配置される理由であり、その子は flex ルールを実行します。

もう 1 つの値がここで位置します。display: flow-root。これは、ボックスに通常の内側フロー を与えますが、それは新しい ブロック フォーマット コンテキスト (BFC: 自己完結型レイアウト領域の内側が外側と相互作用しないため、内側のフロートが含まれ、内側のマージンがそのエッジを介して折りたたまれません。flow-root が存在する前に、人々は overflow: hidden または clearfix ハック使用して浮くchildren を含むために BFC をトリガーします。flow-root は、「これを含める」と言うための明示的で副作用のない方法です。また、ボックス モデル で説明されている親と子のマージン折りたたみを停止します。flexbox 内で display: flex または display: grid にコンテナーを移動する場合、同様に新しいフォーマット コンテキストを確立しており、これがモダン レイアウト内のマージンが float 時代内部のマージンよりも予測可能である理由の一部です。

css
.media {
  display: flow-root;     /* 浮くChildren を含み、clearfix ハックなし */
}
.gallery {
  display: flex;          /* ノーマルフロー内の外側ブロック、子の内側 flex */
}
Junodisplay が内部レイアウトを変更する方法 ブロックとインラインを切り替える同じ display プロパティは、コンテナーを flexbox またはグリッドに変えて、子要素を配置するのも出ています。レイアウトは、一度にオンにする 1 つのスイッチではありません。それが必要なコンテナーで display を変更し、残りはノーマルフロー内に留まります。Flexbox と positioning の章はここから続きます。
Junodisplay が内部レイアウトを変更する方法display は、ボックスがその兄弟の中にどのように配置されるか、およびそれが独自の子要素をどのように配置するかの両方を管理します。display: flexdisplay: grid は 2 番目を変更するため、flex コンテナーは子が flex ルールに切り替わる場合にもノーマルフロー内のブロックのままです。それは、flexbox を学習がフロー を置き換える代わりに、フロー に基づいている理由です。
Junodisplay が内部レイアウトを変更する方法display の値には、ボックスが親に参加する方法である外側の種類と、子をレイアウトする方法である内側の種類が含まれます。これが、flex コンテナーが外側を変更しないために、フロー内のブロックとして留まり、その子が flex に向かう理由です。display: flow-root は通常の内側フロー を保ちますが、新しいブロック フォーマット コンテキストを開始するため、古い overflow または clearfix ハック なしにフロート を含み、マージン折りたたみを停止します。Flex と grid コンテナーは、マージンがそれら内でモダン レイアウト内で浮く時代より予測可能である理由の一部であるそれら自身のコンテキストも確立します。