ホームページ  >  記事  >  ウェブフロントエンド  >  CSS_html/css_WEB-ITnose のビジュアル書式設定モデル

CSS_html/css_WEB-ITnose のビジュアル書式設定モデル

WBOY
WBOYオリジナル
2016-06-24 11:34:05951ブラウズ

ビジュアル フォーマット モデル

1. はじめに

ビジュアル フォーマット モデルでは、ドキュメント ツリー内の各要素がボックス モデルに従って 0 から複数のボックスを生成します。これらのボックスのレイアウトは次によって決定されます:

  • ボックスのサイズとタイプ
  • 配置戦略 (通常のドキュメント フロー、フローティングまたは絶対配置)
  • ドキュメント ツリー内の他の要素との関係
  • 追加情報 (例:ビューポートのサイズ、画像の元のサイズなど)
  • 1.1 ビューポート

    連続メディアの UA (ユーザー エージェント) は通常、ユーザーにビューポート、通常はウィンドウまたはスクリーンの可視領域を提供します。ユーザーはこのビューポートを通じてドキュメントを表示します。ビューポートのサイズが変更されると、UA はドキュメントのレイアウトを変更する場合があります。
    ビューポートのサイズがドキュメントがレンダリングされる領域 (キャンバス) より小さい場合、UA はスクロール メカニズムを提供する必要があります。各キャンバスには最大 1 つのビューポートしか持てませんが、UA はドキュメントを複数のキャンバスにレンダリングできます (同じドキュメントの異なる表示方法を提供するなど)。

    1.2 包含ブロック

    CSS2.1 では、多くのボックスの位置とサイズは、包含ブロックと呼ばれる長方形のボックスの辺に基づいて計算されます。通常、生成されたボックスは子孫ボックスの包含ブロックとして機能します。つまり、ボックスはその背景ボックスの包含ブロックを生成します。 「ボックスの収容ブロック」とは、ボックスによって生成された収容ブロックではなく、収容ボックスの収容ブロックを指します。
    各ボックスは、含まれるブロックに従って配置されますが、含まれるブロックによって制限されず、オーバーフローする可能性があります。

    2. ボックスの生成を制御する

    以下のセクションでは、CSS2.1 で生成されるボックスの種類について説明します。ビジュアルフォーマットモデルでは、ボックスのタイプがボックスの動作に部分的に影響します。 CSS2.1では「display」属性でボックスの種類を指定できます。

    2.1 ブロックレベルの要素とブロックレベルのボックス

    ブロックレベルの要素は、段落など、ソース文書内で目に見えるブロックにフォーマットされる要素です。 「display」属性の次の値は、要素をブロックレベルの要素に変換します:「block」、「list-item」、および「table」。
    ブロックレベルのボックスは、ブロック書式設定コンテキスト内のボックスです。各ブロックレベルの要素は、メインのブロックレベルのボックスを作成します。このメイン ブロック レベルのボックスには、子孫ボックスおよびその他の生成されたコンテンツが含まれており、あらゆる配置戦略にも関与します。一部のブロック レベル要素は、メインのブロック レベル ボックスに加えて、「list-item」要素などの他のボックスを生成します。これらの追加のボックスは、メインのブロックレベルのボックスに基づいてレイアウトされます。
    テーブル ボックスや交換可能な要素ボックスに加えて、ブロックレベルのボックスも通常はブロック コンテナ ボックスです。ブロック コンテナ ボックスには、ブロック レベルのボックスのみを含めることも、インライン フォーマット コンテキストを確立して行レベルのボックスを含めることもできます。すべてのブロック コンテナ ボックスがブロック レベル ボックスであるわけではありません。ブロックコンテナボックスであるブロックレベルのボックスをブロックボックスと呼びます。
    ブロックレベルのボックス、ブロックコンテナボックス、およびブロックボックスは、文脈から意味が明らかな場合には、単にブロックと呼ばれることもあります。

    2.1.1 匿名ブロックボックス

    以下のドキュメント内:

    <DIV>  Some text  <P>More text</DIV>

    DIV 要素と P 要素の両方に "display:block" が設定されていると仮定します。 DIV 要素には、インライン コンテンツとブロック コンテンツの両方が含まれます。書式設定を定義しやすくするために、「テキスト」の周囲に匿名のブロック ボックスがあると仮定します。

    上の写真は例の 3 つのボックスを示しており、その中に匿名のボックスがあります。
    言い換えると: ブロック コンテナ ボックス (上記の DIV ボックスなど) にブロックレベルのボックスがある場合、このブロック コンテナ ボックス内のすべてのボックスが強制的にブロックレベルのボックスになります。
    インライン ボックスにインフロー ブロック レベル ボックスが含まれる場合、インライン ボックス (および同じインライン ボックス内のその祖先) は 2 つのボックスに分割され、このブロック レベル ボックスの両側に配置されます (片側は可能です)。空であること)。このブロックレベルボックスの前後の行ボックスは匿名ブロックボックスに封入されている。このブロックレベルボックスと匿名ボックスは兄弟である。このようなインライン ボックスが相対位置に設定されている場合、位置の変更はインライン ボックス内のブロック レベルのボックスに影響します。
    例を見てください:
    次の HTML ドキュメントを与えます。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HEAD><TITLE>Anonymous text interrupted by a block</TITLE></HEAD><BODY><P>This is anonymous text before the SPAN.<SPAN>This is the content of SPAN.</SPAN>This is anonymous text after the SPAN.</P></BODY>

    次のスタイルを適用します:

    p    { display: inline }span { display: block }

    这个P元素包含一个匿名文本块(C1)、一个块级元素以及另一个匿名文本块(C2)。最终的效果是一个显示在BODY中的块盒子,这个盒子包含一个匿名块盒子(包含C1)、一个SPAN块盒子和另一个匿名块盒子(包含C2)。
    匿名盒子的属性继承自包含它的非匿名盒子。非继承的属性将使用初始值。例如,之前的DIV的例子,匿名盒子的font属性继承自DIV,但是margin属性为0。
    当涉及到百分比值计算的时候,匿名盒子将会被忽略,直到找到最近的非匿名盒子祖先为止。例如之前的DIV,如果匿名盒子的孩子需要知道它的包含块的高度来计算一个百分比的高度时,将会使用DIV产生的包含块的高度,而不是匿名盒子的高度。

    2.2 行级元素和行内盒子

    行级元素就是那些源文档中不会导致新块的产生的元素,元素的内容分布在行内。例如段落的强调文字部分、行内图片等。"display"属性的如下属性值指定一个元素为行级元素:"inline"、"inline-table"和"inline-block"。行级元素产生行级盒子,这些行级盒子存在于行内格式化上下文中。
    一个行级盒子既表现在它是行级的,又表现在它的内容存在于包含他的行内格式化上下文中。设置了"display:inline"的不可替代元素将会产生一个行盒子。不是行盒子的行级盒子(如可替代的行级元素、行内块元素和行内表格元素)被称为原子行级元素,因为这些盒子在他们的行内格式化上下文中表现为一个单一的不透明盒子。

    2.2.1 匿名行盒子

    任何直接包含在块容器元素(该元素不包含在行元素内)的文本都应该被当成匿名行元素对待。
    例如:

    <p>Some <em>emphasized</em> text</p>

    P元素产生一个块盒子,包含几个行盒子。包含"emphasized"文本的盒子是一个有行元素(907fae80ddef53131f3292ee4f81644b)产生的行盒子。但是另外的两个行盒子("Some"和"text")由块级元素(P)产生。后者被称为匿名行盒子,因为他们没有一个相关的行级元素。
    这样的匿名行盒子从他们的块级父盒子继承可继承的属性。不可继承的属性将使用初始值。在例子中,匿名盒子的文本颜色继承自P,但是背景确实透明的。
    只有空白字符并且可以通过"white-space"属性设置的策略合并的内容不会产生任何的匿名行盒子。

    2.3 "display"属性

    "display"属性的取值范围是: inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit
    "display"属性的初始值为"inline"。
    一下是每种取值的具体含义:

  • block 应用该属性值的元素将会产生一个块盒子。
  • inline-block 应用该属性值的元素将产生一个行级块容器。inline-block的内部被格式化成一个块盒子,元素本身被格式化成一个原子行级盒子。
  • inline 应用该属性值的元素将会产生一到多个行盒子。
  • list-item 应用该属性值的元素(比如html中的li)将会产生一个主块级盒子和一个标签盒子。
  • none 应用该属性值的元素将不会出现在格式化结构(formatting structure)中,也就是说,元素不产生任何盒子,对布局没有任何影响。元素的后代元素也不产生盒子,元素和元素的内容被从格式化结构中完全删除。通过设置后代元素的"display"属性值也不能改变。
    请注意,"display"为"none"时不产生任何不可见的盒子,实际上,根本不产生任何盒子。如果想产生既不可见又影响格式化结构的盒子,请参考visibility属性。
  • table,inline-table,table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, and table-caption
    应用以上属性值的元素将表现得像一个表格元素。
  • 注意,尽管"display"属性的初始值为"inline",但是UA的默认样式表可能覆盖这个值。
    以下是一些display属性的例子:

    p   { display: block }em  { display: inline }li  { display: list-item } img { display: none }      /* 不显示图片 */

    3. 定位策略(Positioning schemes)

    在css 2.1中,一个盒子将经过定位策略来进行定位:

    1. 通常の流れ。 CSS 2.1 では、通常のドキュメント フローには、ブロック レベル ボックスのブロック フォーマット コンテキスト、行レベル ボックスの行フォーマット コンテキスト、およびブロック レベル ボックスと行レベル ボックスの相対的な位置が含まれます。
    2. 浮きます。 フローティング モデルでは、ボックスは最初に通常のドキュメント フローに従って配置され、次にドキュメント フローから外されて、可能な限り左/右に配置されます。コンテキスト内の他のコンテンツはフローティング要素の片側に流れます。
    3. 絶対的な位置決め。 絶対配置モデルでは、ボックスは通常のドキュメント フローから完全に削除され (削除されたボックスは元の兄弟ボックスに影響を与えなくなります)、そのボックスを含むブロックに従って配置されます。

    要素がフローティング要素、絶対配置されている要素、またはルート要素である場合、その要素はフロー外であると言われます。要素がドキュメント フローから出ていない場合、その要素はインフローであると言われます。ドキュメント フローから切り離された要素 A の場合、そのドキュメント フローには、要素 A 自体と、ドキュメント フロー内の A のすべての子孫要素が含まれます。

    3.1 位置属性

    位置属性の値の範囲は次のとおりです: static 相対 | 固定 | 初期値は static | です。各値の意味は次のとおりです。

    static この属性値が適用されるボックスは通常のボックスであり、通常のドキュメント フローに従って配置されます。 top、right、bottom、left 属性は無効です。


  • relative この属性値が適用されるボックスの位置は、通常のドキュメント フロー内のボックスの初期位置とオフセットに基づいて計算されます。つまり、ボックスの最終位置は、元の位置に対して一定量だけオフセットされます。ボックス B が相対配置を採用している場合、ボックス B が相対配置を採用していない場合と同様、ボックス B の背後にある他のボックスの配置は影響を受けません。

  • absolute この属性値が適用されるボックスの位置は、top、right、bottom、left 属性によって決まります。これらの属性は、ボックスを含むブロックに従ってオフセットを決定します。絶対配置されたボックスは通常のドキュメント フローから完全に分離されます。つまり、絶対配置されたボックスは他のボックスに影響を与えなくなります。絶対配置されたボックスのマージンは、他のボックスのマージンと一緒に崩れません。

  • fixed この属性値を適用するボックスの位置は、絶対位置に基づいて計算されます。また、ボックスは特定の参照オブジェクトに対して固定されます。たとえば、ビジュアル メディアでは、固定位置のボックスはビューポートに対して固定されます。
  • UA は、ルート要素の位置をデフォルトで静的位置に設定できます。
  • 3.2 ボックスのオフセット: 上、右、下、左

    要素の位置属性値が静的でない場合、要素は位置決めされていると言われます。位置指定された要素は、位置指定されたボックスを生成し、次の 4 つの属性に従って配置します:

    top
    top 属性の値の範囲は次のとおりです: 絶対長値 | パーセント値 | 初期値は auto | です。 このプロパティは、絶対に配置されたボックスの上マージンの端とボックスを含むブロックの上端の間のオフセット (距離) を指定します。相対位置を使用するボックスの場合、このオフセットはボックス自体の上部境界に基づいて計算されます。つまり、ボックスは最初に通常のドキュメント フロー内の位置を取得し、次に、それに基づく属性値に基づいて位置を調整します。その位置。

    right
    right 属性の値の範囲は次のとおりです: 絶対長値 | パーセント値 | 初期値は auto | です。 top 属性と同様に、この属性は、絶対位置のボックスの右マージン端とボックスを含むブロックの右端の間のオフセット (距離) を指定します。相対的に配置されたボックスの場合、このオフセットはボックス自体の右端から計算されます。

    bottom
    botton 属性の値の範囲は次のとおりです: 絶対長値 | パーセント値 | 初期値は auto | です。 top 属性と同様に、この属性は、絶対位置のボックスの下マージン エッジとボックスを含むブロックの下端の間のオフセット (距離) を指定します。相対的に配置されたボックスの場合、このオフセットはボックス自体の下限から計算されます。

    left
    left 属性の値の範囲は次のとおりです: 絶対長値 | パーセント値 | 初期値は auto | です。 top 属性と同様に、この属性は、絶対位置のボックスの左マージンの端とボックスを含むブロックの左端の間のオフセット (距離) を指定します。相対的に配置されたボックスの場合、このオフセットはボックス自体の左端から計算されます。

    上記の 4 つの属性の特定の値は次の意味を持ちます:

  • 绝对长度值 相对于参考边的偏移量是个固定的距离且可以为负。
  • 百分比 偏移量是盒子包含块宽度(left、right)或高度(top、bottom)的百分比,可以为负。
  • auto 自动。
  • 4. 正常文档流(Normal flow)

    在正常文档流中的盒子都属于一个格式化上下文(formatting context)。这个格式化上下文既可以是块级的,也可以是行级的,但不能两者都是。块级盒子在块格式化上下文(block formatting context)中,行级盒子在行格式化上下文(inline formatting context)中。

    4.1 块格式化上下文

    浮动的元素、采用绝对定位的元素、不是块盒子的块容器(比如inline-block,table-cell和table-caption)以及设置了overflow且值不为visible(设置了visible的viewport除外)的块盒子将会为他们的内容建立新的块格式化上下文。

    在块格式化上下文中,各个盒子从他们的包含块的顶部开始,竖直的顺次放置。相邻的两个盒子的竖直距离有margin属性决定。在同一个格式化上下文中的两个相邻的块级盒子的竖直外边距将会合并。

    在块格式化上下文中,每个盒子的左外边界与盒子的包含块的左边界相接(对于从右到左的情况,右外边界与右边界相接)。 即使当有浮动元素存在是也依然使用,除非这个盒子产生了新的块格式化上下文(这样的话,由于浮动,盒子的宽度将变小)。

    4.2 行格式化上下文

    在行格式化上下文中,每个盒子从他们的包含块的顶部开始,依据每个盒子的水平margin,border和padding,水平的依次放置。这些盒子在竖直方向上,可能依据顶部或者底部对其,也可能依据盒子内部文本的基准线对其。包含这些盒子的来形成行的这个长方形区域就叫行盒子(line box)。

    一个行盒子总要有足够的高度来包含它的所有后代盒子。因此,它可能比它包含的最高的盒子还要高(比如,行盒子内部的盒子都依据文本基准线对其)。当盒子B的高度比行盒子低的时候,盒子B在行盒子里的对其方式就由vertical-align属性决定。如果多个行级盒子无法在单一的行盒子中水平放置,那么这些盒子将会被分放到二到多个竖直堆叠(vertically-stacked)的行盒子中。因此,一个段落就是一个行盒子的竖堆。堆叠的行盒子之间没有分隔(除非指定),并且从不重叠。

    通常,行盒子的左边界与包含块的左边界相接,右边界与包含块的右边界相接。但是,如果有浮动元素存在的话,那浮动元素将会介乎两者之间。因此,尽管在同一个行格式化上下文中的行盒子通常都与包含块同宽,但是他们的宽度也会因为受到浮动元素的影响而有所差异。在同一个行格式化上下文中的行盒子高度各不相同,比如一个行盒子包含一个较高的图片,而另一个仅仅包含文本。

    当行级盒子的宽度小于包含他们的行盒子时,他们水平方向的对其方式将由text-align属性决定。如果text-align属性取值为justify,那么UA可能拉伸和盒子中的文字和间距,但是inline-table和inline-block盒子除外。

    如果一个行内盒子的宽度超出了行盒子的宽度,那它将被拆断为多个行内盒子,然后放到多个行盒子中。如果行内盒子不能被拆断(比如行内盒子仅包含单个字符,或者定语言单子截断规则不允许截断,或者使用了white-space,且取值为nowrap或pre),那这个行内盒子将会溢出行盒子。
    当行内盒子被拆断时,margin、border和padding对拆断处没有任何视觉上的影响。

    当在行格式化上下文中需要包含行内级内容时就会创建行盒子。不包含任何文本、任何保留的空白字符、任何拥有非零margin、padding和border的行内元素以及任何其他在流中的内容(例如图片、行内块或行内表格)并且不以保留的换行符结束的行盒子,它将被视作没有高度的行盒子,以此来保证盒子里的任何元素的的位置计算。

    如下是行内盒子构建的一个例子。

    <P>Several <EM>emphasized words</EM> appear<STRONG>in this</STRONG> sentence, dear.</P>

    P元素产生一个块盒子,包含五个行内盒子,其中三个是匿名盒子:

  • 匿名盒子: "Several"
  • EM: "emphasized words"
  • 匿名盒子: "appear"
  • STRONG: "in this"
  • 匿名盒子: "sentence, dear"
    为了将段落进行格式化,UA将这五个盒子顺序放进一个行盒子中。在这个例子中,P元素产生的盒子产生了行盒子的包含块。如果包含块的宽度足够宽,所有的行内盒子都会在一行里面:

    Several emphasized words appear in this sentence, dear.

    如果宽度不够,那么这些行内盒子将会被拆断放进多个行盒子里去。之前的段落可能会被这样拆断:

    Several emphasized words appearin this sentence, dear

    也有可能这样:

    Several emphasized  words appear in this sentence, dear.

    在这个例子中,EM盒子将被拆断成两个EM盒子(暂成为split1 和split2)。margin、border、padding或者文字装饰在split1之后和split2之前没有任何视觉上的影响。

  • 再看下面的例子:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HTML>  <HEAD>    <TITLE>Example of inline flow on several lines</TITLE>    <STYLE type="text/css">      EM {        padding: 2px;         margin: 1em;        border-width: medium;        border-style: dashed;        line-height: 2.4em;      }    </STYLE>  </HEAD>  <BODY>    <P>Several <EM>emphasized words</EM> appear here.</P>  </BODY></HTML>

    由于P元素宽度的限制,各个盒子可能像如下放置:

  • margin被插入在"emphasized"的前面和"words"的后面。
  • padding被插入在"emphasized"的前面、上面、下面和"words"的后面、上面、下面。虚线的边框也同样被渲染在了两个单词的三边。
  • 4.3 相对定位(Relative positioning)

    一旦一个盒子被定位或者浮动,它可以相对于这个位置进行一定的偏移。这就叫做相对定位。偏移的盒子(B1)对紧跟着它的盒子(B2)没有任何影响:B2的位置就像B1没有发生偏移一样。因此,相对定位可能导致盒子重叠(overlap)。但是,如果相对定位导致了"overflow:auto"或者"overflow:scroll"的盒子溢出了,那么UA必须允许用户(通过滚动条等)能够访问到盒子的内容。

    一个相对定位的盒子保持原有的正常大小,包括换行和一开始就保有的空间。

    对于相对定位的元素来说,left和right将盒子不改变大小的水平移动。left将盒子右移,right将盒子左移。因为left或right的结果都不会导致盒子被分隔或拉伸,所以实际上最终使用的值总是: left=-right。

    如果left和right的取值都是auto,那最终生效的值都为0(也就是说盒子呆在原来的位置)。
    如果left取值为auto,那么最终使用的值是-right(也就是说盒子最终左移了right的数值)。
    如果right取值为auto,那么最终使用的值是-left。
    如果left和right都不是auto,那么二者之中必须要忽略一个。如果包含块的direction属性值为ltr,那么使用left,right的值为-left;如果包含块的direction为rtl,那么使用right,left的值为-right。

    如下几条规则效果相同:

    div.a8 { position: relative; direction: ltr; left: -1em; right: auto }div.a8 { position: relative; direction: ltr; left: auto; right: 1em }div.a8 { position: relative; direction: ltr; left: -1em; right: 5em }

    top和bottom属性将盒子不改变大小的上下移动。top将盒子下移,bottom将盒子上移。因为盒子不会被分隔或者拉伸,所有最终使用的值总是:top=-bottom。如果两个都是auto,那么最终使用的值都为0。如果其中之一为auto,那么设为auto的那个属性最终使用的值是另一个的负值。如果都不是auto,那么bottom被忽略(也即是说bottom最终使用的值是-top)。

    5.浮动

    浮动的盒子会被移动到当前行的左边或者右边。浮动最有趣的特点就是其他内容会在浮动的元素的旁边依次放置(或者通过设置clear属性禁止),或者说其他盒子会流动到浮动盒子的旁边。也就是说,其他盒子将沿着向左浮动的盒子的右边、向右浮动的盒子的左边依次放置。

    一个浮动的盒子将会一直向左或向右移动,一直到触碰到包含块的边界或者其他浮动盒子的外边界。如果是行盒子的话,那么浮动盒子的外边界的顶部将与当前行盒子的顶部对其。
    如果没有足够的水平空间,那么浮动的盒子将移至下一行直到有足够的空间或者行内已经没有其他浮动元素为止。

    因为浮动盒子不在文档流中,所以在浮动盒子前后的未定位的块盒子将像浮动盒子不存在一样的竖直依次放置。但是,浮动盒子所在的当前行以及后面相邻的行盒子都会根据浮动盒子缩短宽度来给浮动盒子留下空间。
    如果有个竖直的位置满足如下四个条件: (a)在行盒子的顶部或者顶部之下(b)在行盒子的底部或底部之上(c)在浮动盒子的外边界的顶部或者顶部之下(d)在浮动盒子的外边界的底部或者底部之上,那么行盒子将会换行。也就是说,如果浮动的盒子的外边界高度为0或者为负,那么行盒子不会缩短。

    如果缩短的行盒子太短而不能包含任何内容,那么这个行盒子将会换行(并且高度会重新计算)直到有足够的空间或者没有浮动盒子为止。当前行内的任何在浮动盒子之前的盒子都将重新流动到浮动盒子的另一边。换句话说,如果一个行内盒子放在了一个向左浮动盒子的前面,那么,向左浮动的盒子将会放在这一行的开始,与行盒子的顶部对其,之前的行内盒子将会移动到浮动盒子的右边。对于rtl和向右浮动的盒子同理。

    table、块级可替换元素或者正常文档流中建立新的块格式化上下文的元素的border盒不能与任何在同一个格式化上下文中的浮动盒子的margin盒重叠。

    例如,如下片段中,包含块太窄,不能包含浮动盒子的右边的内容,因此,那段内容就移动到浮动盒子的下方。

    p { width: 10em; border: solid aqua; }span { float: left; width: 5em; height: 5em; border: solid blue; }...<p>  <span> </span>  Supercalifragilisticexpialidocious</p>

    这个文档片段可能是这样的:

    多个浮动的盒子可能彼此相邻,上述模型也同样适用于同一行中的多个相邻浮动盒子。
    下面这条规则将所有class="icon"的IMG都浮动到左边:

    img.icon {   float: left;  margin-left: 0;}

    看如下的html和样式文件:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HTML>  <HEAD>    <TITLE>Float example</TITLE>    <STYLE type="text/css">      IMG { float: left }      BODY, P, IMG { margin: 2em }    </STYLE>  </HEAD>  <BODY>    <P><IMG src=img.png alt="This image will illustrate floats">       Some sample text that has no other...  </BODY></HTML>

    IMG盒子浮动到左边,剩余的文档内容被格式化在同一行的浮动元素的右边。浮动盒子右边的行盒子因为浮动盒子的存在而缩短了,但是在浮动盒子的下方又重新恢复了正常的宽度。上面的文档,可能被格式化成下面的样子:

    如果文档被修改成下面这样,最终格式化后的效果依然是相同的:

    <BODY>  <P>Some sample text   <IMG src=img.png alt="This image will illustrate floats">           that has no other...</BODY>

    因为左边的文本内容被浮动盒子替换并重新流动到了浮动盒子的右边。
    因为浮动盒子的margin不与相邻盒子的margin重叠,所以上面例子中P盒子和IMG盒子的竖直margin不重叠。
    浮动盒子可以与正常文档流中的其他的盒子发生重叠(例如浮动盒子旁边的盒子有一个负的margin),此时,浮动盒子在未定位的流内块盒子之前,但在流内行内盒子之后。
    下面例子说明当浮动盒子与其他元素的边框重叠时发生了什么。

    浮动的图片遮盖了与他重叠的盒子的边框。

    如下示例说明如何通过clear属性禁止内容流向浮动盒子的一边。
    假设如下规则:

    p { clear: left }

    最终文档可能如下:

    5.1 float属性

    float属性的取值范围是: left | right | none | inherit,初始值为none。
    该属性值决定元素向左移动还是向右移,或者根本不动。float属性可以被应用于任何元素上,除了绝对定位的元素。float属性的取值有如下含义:

  • left 元素产生一个向左浮动的块盒子。其他内容流向盒子的右边。
  • right 与left相似,盒子浮动到右边,其他内容流向盒子的左边。
  • none 不浮动
  • 如下9条规定了浮动元素的确切行为:

    1. 向左浮动的盒子的外左边界不能超过包含块的左边界。同理应用于向右浮动的盒子。
    2. 对于一个向左浮动的盒子,如果在这个盒子之前还有其他向左浮动的盒子,那么,这个盒子的左外边界不能超过其他任何向左浮动的盒子的右外边界,或者这个盒子的上边界必须比其他盒子的下边界低。同理应用于向右浮动的盒子。
    3. 任何向左浮动的盒子的右外边界不能超过任何与之相邻的向右浮动的盒子的左外边界。同理应用于向右浮动的盒子。
    4. 浮动盒子的上外边界不能比包含块的上边界高。当浮动发生在两个合并的margin中时,浮动的盒子根据一个假设的父的空匿名块盒子定位。
    5. 浮动盒子的上外边界不能比任何其他之前的块盒子或浮动盒子的上外边界高。
    6. 浮动盒子的上外边界不能比任何之前的行盒子的上边界高。
    7. 一个向左浮动的盒子,如果在他之前还有向左浮动的盒子,那么这个盒子的右外边界不能超过包含块的有边界,除非这个盒子已经尽可能的向左了。同理应用于向右浮动的盒子。
    8. 浮动元素要尽可能的往高放置。
    9. 向左浮动的盒子要尽可能向左,向右浮动的盒子要尽可能向右。但是相对于尽可能向左或向右,更高的位置有更高的优先级。

    下面的html片段,b浮动到右边:

    <P>a<SPAN style="float: right">b</SPAN></P>

    如果P元素的宽度足够,那么a和b将各占一边,如下:

    5.2 clear属性

    clear属性的取值范围是: none | left | right | both | inherit, 初始值为none。只应用于块级元素。

    该属性决定元素盒子的哪一边不与浮动盒子相邻。clear属性不考虑被应用元素内部的浮动以及其他块格式化上下文中的浮动。

    属性取值含义如下:

  • left 应用该属性值的元素盒子的上边界要低于该元素之前的左浮动元素盒子的底外边界。
  • right 应用该属性值的元素盒子的上边界要低于该元素之前的右浮动元素盒子的底外边界。
  • both 应用该属性值的元素盒子的上边界要低于该元素之前的左浮动或右浮动元素盒子的底外边界。
  • none 不浮动。
  • 所有不是none的值都将引入空隙(clearance)。clearance禁止margin合并,表现得就像元素的上外边距外还有一段空间。
    要计算应用了clear属性的元素的clearance,首先需要找到元素上边界的假定位置。这个假定位置就是当clear属性值为none时元素实际上的上边界。
    如果假定的元素的上边界不能越过相关的浮动元素(past the relevant floats),那么就需要引入clearance。

    空隙的大小为如下两个值中的较大值:

    1. 将元素的上边界与最低的浮动元素的底外边界对齐需要的空间大小。
    2. 将元素的上边界放置到它假定的位置需要的空间大小。
      注意,空隙的大小可能为负也可能为0.

    举个例子1,假设有三个盒子,块B1的bottom margin为M1(B1没有后代,没有padding也没有border),浮动块F的高度为H,块B2的top margin为M2(没有padding,没有border,也没有后代)。B2设置了clear:both。不考虑B2的clear属性,这三个盒子的如下图。B1和B2的margin重叠了。假设B1的底边界为y坐标原点(y=0),F的顶部在y=M1处,B2的上边界在y=max(M1,M2),F的底部在y=M1+H。

    我们还假设B2不在F的下面,也就是说,我们需要引入clearance。因此:
    max(M1,M2) a546273fea031630e404606754990a72
    M1 + H = M1 + C1 + M2 96b4fef55684b9312718d5de63fb7121
    C1 = M1 + H -M1 - M2
    = H - M2
    第二步计算,就是保持B2在原来的位置,y=max(M1,M2),也就是说:
    max(M1,M2) = M1 + C2 + M2 96b4fef55684b9312718d5de63fb7121
    C2 = max(M1, M2) - M1 - M2
    按照我们之前的假设max(M1,M2) < M1 + H,所以:
    C2 = max(M1,M2) - M1 - M2 < M1 + H - M1 - M2 96b4fef55684b9312718d5de63fb7121
    C2 < H - M2
    因为C1= H - M2,所以
    C2 < C1
    因此,C= max(C1,C2) = C1。

    例2,假设所有元素都没有border和padding,在下面的代码中,clearance是-1em。

    <p style="margin-bottom: 4em">  First paragraph.<p style="float: left; height: 2em; margin: 0">  Floating paragraph.<p style="clear: left; margin-top: 3em">  Last paragraph.

    解释: 如果没有clear,第一段和最后一段的margin将会合并,并且最后一段的上边界将会与浮动段的顶部对齐。但是clear需要上边界低于浮动元素,也就是说要再低2em。这就意味着必须要引入clearance。因此,margin不再合并,并且 clearance + margin-top = 2em, 也就是说clearance = 2em - margin-top= -1em。

    当该属性被应用于浮动元素时,浮动元素的上外边界必须要低于之前的左浮动元素(clear:left)、右浮动元素(clear:right)或者左右浮动元素(clear:both)的底外边界。

    6. 绝对定位(Absolute positioning)

    在绝对定位模型中,盒子被从正常文档流中完全移除,并只相对于它的包含块进行偏移定位。绝对定位的盒子会为它的正常文档流后代盒子以及非fixed的绝对定位后代盒子建立一个包含块。绝对定位的盒子可能会遮盖其他元素,具体取决于堆叠层次。

    6.1 固定布局(Fixed positioning)

    固定布局是绝对布局的一个子类,唯一的不同在于固定布局的盒子的包含块由视口(viewport)产生。
    我们通常通过fixed布局来创建页面的框架,比如:

    上图的效果可以通过如下代码采用fixed布局实现:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HTML>  <HEAD>    <TITLE>A frame document with CSS 2.1</TITLE>    <STYLE type="text/css" media="screen">      BODY { height: 8.5in } /* Required for percentage heights below */      #header {        position: fixed;        width: 100%;        height: 15%;        top: 0;        right: 0;        bottom: auto;        left: 0;      }      #sidebar {        position: fixed;        width: 10em;        height: auto;        top: 15%;        right: auto;        bottom: 100px;        left: 0;      }      #main {        position: fixed;        width: auto;        height: auto;        top: 15%;        right: 0;        bottom: 100px;        left: 10em;      }      #footer {        position: fixed;        width: 100%;        height: 100px;        top: auto;        right: 0;        bottom: 0;        left: 0;      }    </STYLE>  </HEAD>  <BODY>    <DIV id="header"> ...  </DIV>    <DIV id="sidebar"> ...  </DIV>    <DIV id="main"> ...  </DIV>    <DIV id="footer"> ...  </DIV>  </BODY></HTML>

    7. display、position和float的关系

    这三个属性都影响盒子的产生以及定位,他们关系如下:

    1. 如果display的值为none,那么position和float不起作用。在这种情况下,元素不产生盒子。
    2. 否则,如果position的值为absolute或者fixed,那么盒子就使用绝对定位,float的最终使用的值为none,display的取值依据如下表格来定。盒子的显示位置根据top、right、bottom和left属性决定。
    3. 否则,如果float的取值不会none,那么盒子将会浮动,display的取值参照下表。
    4. 否则,如果元素是根元素,那么display的取值参照下表。
    5. 否则,display的取值就是指定的值。





      指定的值 最终使用的值
      inline-table table
      inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block
      其他 与指定的值相同

    8. 正常文档流、浮动和绝对定位的比较

    为了说明正常文档流、相对定位、浮动和绝对定位的不同,我们通过几个例子来说明,这些例子都是基于下面这段代码:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HTML>  <HEAD>    <TITLE>Comparison of positioning schemes</TITLE>  </HEAD>  <BODY>    <P>Beginning of body contents.      <SPAN id="outer"> Start of outer contents.      <SPAN id="inner"> Inner contents.</SPAN>      End of outer contents.</SPAN>      End of body contents.    </P>  </BODY></HTML>

    我们给上面的文档应用如下样式:

    body { display: block; font-size:12px; line-height: 200%;        width: 400px; height: 400px }p    { display: block }span { display: inline }

    在每个例子的说明中,左侧的数字表示正常文档流的位置。

    8.1 正常文档流

    我们增加如下样式:

    #outer { color: red }#inner { color: blue }

    P元素包含所有的行内容:匿名行内文本与两个SPAN元素。因此,所有的内容都在一个行格式化上下文中布局,他们都在P元素建立的包含块之中,效果如下:

    8.2 相对定位

    我们添加如下样式:

    #outer { position: relative; top: -12px; color: red }#inner { position: relative; top: 12px; color: blue }

    outer元素之前的文本正常流动,然后包含outer文本的行内盒子整体上移了12px。作为outer的子元素,inner也要上移12px,但是包含inner元素内容的盒子还需要根据自己的位置再下移12px,回到他们原来的位置。效果如下:

    注意,outer元素后面的文本并没有受影响。

    8.3 浮动

    我们给inner元素添加如下样式,使之向右浮动:

    #outer { color: red }#inner { float: right; width: 130px; color: blue }

    inner盒子之前的文本正常流动,inner盒子被从正常文档流中拿出并浮动到右边(已经为inner指定的宽度)。浮动盒子左边的行盒子宽度减少。

    再看clear属性的作用,我们给文档添加一个sibling元素:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><HTML>  <HEAD>    <TITLE>Comparison of positioning schemes II</TITLE>  </HEAD>  <BODY>    <P>Beginning of body contents.      <SPAN id=outer> Start of outer contents.      <SPAN id=inner> Inner contents.</SPAN>      <SPAN id=sibling> Sibling contents.</SPAN>      End of outer contents.</SPAN>      End of body contents.    </P>  </BODY></HTML>

    添加如下样式:

    #inner { float: right; width: 130px; color: blue }#sibling { color: red }

    让inner盒子浮动到右边,同时文档中剩余的文本流入空出来的区域。 效果如下:

    但是,如果给silibling元素应用clear:right,那么sibling元素内容将会流动到float元素的下面。

    #inner { float: right; width: 130px; color: blue }#sibling { clear: right; color: red }

    8.4 绝对定位

    最后,我们再看绝对定位:

    #outer {     position: absolute;     top: 200px; left: 200px;     width: 200px;     color: red;}#inner { color: blue }

    上面的样式将会使得outer盒子根据他的包含块来定位。一个已经定位的盒子的包含块由离它最近的已经定位的祖先盒子建立,如果这样的祖先盒子不存在的话,那么就是用初始包含块(initial containing block)。所以,outer盒子的上边距离包含块的顶部200px,左边距离包含块左边200px。outer的子元素在outer内部正常流动。效果如下:

    下面的这个例子展示的父元素采用相对定位的绝对定位的盒子。尽管作为父元素outer盒子实际上并没有偏移,但是,设置了position:relative就意味着这个盒子可以作为它的已定位的后代盒子的包含块。因为outer盒子是一个行内盒子并且分散在多行内,所以第一个行内盒子的上边缘和左边缘(图中粗虚线标出)作为top和left的参考。

    #outer {   position: relative;   color: red }#inner {   position: absolute;   top: 200px; left: -100px;   height: 130px; width: 130px;   color: blue;}

    效果如下:

    如果不给outer盒子设置position属性:

    #outer { color: red }#inner {  position: absolute;   top: 200px; left: -100px;   height: 130px; width: 130px;   color: blue;}

    那么,inner盒子的包含块就变成了初始包含块。效果如下:

    其他具体内容请参考http://www.w3.org/TR/CSS2/visuren.html

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。