ホームページ  >  記事  >  ウェブフロントエンド  >  CSS2.1SPEC:ビジュアルフォーマットモデルのwidth属性の詳細説明(その2)_html/css_WEB-ITnose

CSS2.1SPEC:ビジュアルフォーマットモデルのwidth属性の詳細説明(その2)_html/css_WEB-ITnose

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

この記事は、CSS2.1SPEC: ビジュアル フォーマット モデルの幅属性の詳細な説明 (パート 1) に続き、CSS ビジュアル フォーマット モデルの幅と関連する値の計算問題の分析を続けます。 :


注: 前のセクションとは異なり、このセクションのデモでは、float、absolute、その他の位置決め方法の出現により、効果の表示を容易にするために、すべてのデモでマージン属性を設定します。 bodyを10pxに変更し、10pxのパディング、3pxのボーダー、500pxの幅を持つクラスコンテナにdiv要素を追加し、float:left、_zoom:1を設定してBFCを形成し、floatをクリアします。 2.2.5 非置換浮動要素

この時点で、float 属性が設定された後、要素は「縮小」することがわかっています。計算する幅の値には特別なアルゴリズムもあります。まず、CSS 標準の計算ルールを確認してください。
まず、margin-left と margin-right の auto 値が 0 に設定されます。

次に、「shrink-to-fit」メソッドに従って要素の幅が計算されます。「shrink-to-fit」アルゴリズムの計算プロセスを見てみましょう。

[1] 優先的に計算します。 width: 含まれていない場合 明確な改行がある場合 (076402276aae5dbec7f672f8f4e5cc81 タグがある場合など)、そうでない場合は、改行なしで含まれるコンテンツを収容するために必要な幅。 [2] Preferred-min-width の計算: 改行が可能な場合 (英語ではスペースまたは句読点が出現し、ブロックレベルの要素が表示されます。そしてもちろん 076402276aae5dbec7f672f8f4e5cc81 タグが表示される場合)、改行 、含まれるコンテンツを収容するために必要な幅。 [3] available-width の計算: セクション 2.2.3 の式を使用します:
available-width = 含まれるブロックの幅 - 'margin-left' - 'border-left-width' - 'padding-left' - 'padding-right' - 'border-right-width' - 'margin-right、これにはすべてのスクロールアウトの幅も含まれます。

最終的な幅は、min(preferred-width, max(preferred-min-width, available-width)) です。最終的な式は次のように要約できます: 最終的な幅は available-width に基づきますが、preferred-width よりも大きくなることはなく、preferred-min-width よりも小さくなることはできないことが保証されます。比較的理解しやすいですが、preferred-width とpreferred-min-width を理解するのは比較的困難です。 デモを通して分析してみましょう:

##DEMO 1 シュリンクトゥフィットアルゴリズムの例 1

次のコードがあります:

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>"</strong><strong>float</strong>: <strong>left</strong>;<strong>border</strong>: 1<strong>px solid </strong><strong>#f00</strong>;<strong>"</strong>><br />        dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd<br /></<strong>div</strong>><br /></<strong>div</strong>>
us ご存知のように、英語ではスペースや句読点のない改行は許可されていません。ここでの「単語」の長さは 500 ピクセルの長さを超える必要があります:

効果を見てみましょう。

各幅を個別にマークします:


注: IE6 ではボックスの幅属性が時間内に定義されているため、IE6 でのこのデモの表示効果は多少異なりますが、それでもコンテンツによって引き伸ばされる可能性があります。この問題については、この記事の後半で紹介します

英語の単語は折り返すことができないので、ここでは、preferred-min-widthとpreferred-widthが同じ、つまり、「単語」の長さは同じであるため、この2つはwidth の値も、ここでは 756px (左右に 1px の境界線もあります) で、ここでは、shrink-to に計算されると、 available-width は含まれるブロックの幅になります。 -fit 式、最終的な幅の値は 756px です。

##DEMO 2 縮小してフィットさせるアルゴリズムの例 2

DEMO1 のコードに次の変更を加えます。つまり、DEMO1 の「単語」にいくつかのスペースを追加します。

このようにして、

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>"</strong><strong>float</strong>: <strong>left</strong>;<strong>border</strong>: 1<strong>px solid </strong><strong>#f00</strong>;<strong>"</strong>><br />        ddddddddddddddddddd dddddddddddd ddddddddddd dddddddddddddddddddddddddddddddddddddddddddddd<br /></<strong>div</strong>><br /></<strong>div</strong>>
は英語の文になり、空白スペースでの改行が許可されます。最終的な表示効果を見てみましょう:


各幅をマークします:


把这个几个值带入公式计算,也不难得出最终的宽度值就是available-width,即500px

 


2.2.6 浮动置换元素

首先, margin-left、margin-right的auto值将被设为0。

而width属性的计算则与行内置换元素的计算方法相同,可参照2.2.2节中的介绍。


2.2.7 绝对定位的非置换元素

为了方便显示,我们为container设置了100px的height值,另外需要明确的是,对于绝对定位的元素来说,如果它的包含块是一个块容器框产生,那么包含块的宽度是这个框的padding edge所形成;如果是一个行内元素,那么由包围其行框的区域形成;另外还有可能是初始包含块,具体可参照《CSS2.1SPEC:视觉格式化模型之包含块》的3.3节。

在本节和下一节中,需要首先明确一个概念"static position":

the term "static position" (of an   element) refers, roughly, to the position an element would have had in the normal 

flow. 

也就是,"static position"是指正常流中的第一个元素应该所处的位置(该元素的position属性为"static",并且没有float),这个元素其实是一个假想的元素。

此外,"left"值指的是包含块的左边缘到绝对定位元素所产生的框的左外边距边缘(left margin edge)的距离。"right"指的是包含块的右边缘到绝对定位元素所产生的框的右外边距的边缘(right margin edge)的距离。

我们用下面的demo演示一下包含块的direction为默认的ltr情况下的"static position":

##DEMO 3 "static position"说明

代码如下:

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>"</strong><strong>width</strong>: 100<strong>px</strong>;<strong>height</strong>: 100<strong>px</strong>;<strong>background</strong>: <strong>#34538b</strong>;<strong>"</strong>><br />        static posotion演示<br /></<strong>div</strong>><br /></<strong>div</strong>>

我们的container有10px的padding,对于正常流中的块级元素来说,在水平方向上,默认就是紧贴包含块的content area左侧的,而这个位置和content area的padding edge的距离就是padding-left。

标准中还指出,用户代理不一定必须去计算这个假想的box的尺寸。


另外, 这一节的内容都必须基于以下等式:

'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block


=》 IF :       left,right和width的值 都是auto,那么首先将margin-left、margin-right的auto设为0,如果包含块的direction属性为ltr,则把left值设为"static position"的位置,并按照下面的 规则3计算width和right的值;如果包含块的direction属性为rtl,则把right值设为"static position"的位置,并按照下面的

规则1

计算left和width的值。 [1]

=》ELSE IF:left,right和width的值都不是auto,如果margin-left和margin-right都是auto,则它们将会拥有相同的值并且必须使得等式成立,从而实现居中效果。但如果这样得出的margin值为负值,那么在包含块的direction属性为ltr的情况下需要将margin-left置为0,并且按照等式计算margin-right的值;反之则将margin-right的值置为0,然后按照等式计算margin-left的值。 [2]

=》ELSE IF:margin-left或者margin-right只有一个为auto,那么就按照等式计算auto值。[3]

=》ELSE IF:所有的值都不为auto(过约束),那么在包含块的direction属性为ltr的情况下,忽略right值,并按照等式重新计算right;反之则忽略left的值,并按照等式重新计算。[4]

=》ELSE IF:上面的几种情况如果都不符合,那么就先把margin的所有auto值置为0,然后按照下面的规则进行计算。[5]

规则:

 

[1]:如果left和width是auto,那么先按照"shrink-to-fit"算法计算width值,然后再根据等式计算left值。

 

[2]: 如果left和right都是auto,但是width不是auto,那么如果包含块的direction属性为ltr,则把left置为"static position"的位置,然后再根据等式求right值;反之,则把right置为"static position"的位置,然后再根据等式求left值。

 

[3]: 如果width和right是auto,那么首先根据"shrink-to-fit"算法计算width值,然后再根据等式计算right值

 

[4]: 标准原文中的4,5,6条规则其实可以归结为一条,即如果left,right和width只有一个auto值,那么直接根据等式计算auto值。


绝对定位元素的width计算相对复杂一些,我们通过几个demo来看一下:

##DEMO 4 width,left和right都为auto的情况

代码如下:

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>height</strong>: 100<strong>px</strong>;<strong>background</strong>: <strong>#34538b</strong>;<strong>position</strong>: <strong>absolute</strong><strong>"</strong>><br />        绝对定位演示<br /></<strong>div</strong>><br /></<strong>div</strong>>

      

在demo4中,我们定义了一个绝对定位的元素,并且width,left和margin都是默认的auto值,可以看到元素的width是按照"shrink-to-fit"得出的,而left值被设置为了static position的位置,这里其实就是包含块的padding-left:10px。置于right值,虽然浏览器的调试工具并没有给出具体right值的used value,但还是有理由相信浏览器会根据标准中的规则计算相应的值。


##DEMO 5 width,left和right都不为auto的情况

我们把demo4中的代码修改一下,为绝对定位元素设置显式的width,left和right值,并且为margin-left和margin-right设置auo值:

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>"</strong><strong>width</strong>:100<strong>px</strong>;<strong>height</strong>: 100<strong>px</strong>;<strong>background</strong>: <strong>#34538b</strong>;<strong>position</strong>: <strong>absolute</strong>;<strong>left</strong>: 0<strong>px</strong>;<strong>right</strong>: 0<strong>px</strong>;<strong>margin-left</strong>: <strong>auto</strong>;<strong>margin-right</strong>: <strong>auto</strong>;<strong>"</strong>><br />        绝对定位演示<br /></<strong>div</strong>><br /></<strong>div</strong>>

可以明显看到,在width,left和right都不为auto,并且水平margin为auto时,会按照平分margin-left和margin-right的方式布局,从而也可以达到元素居中的效果。

注:IE6/7并不会按照这个规则计算margin值,而是直接将margin的auto置为0然后再进行计算。


我们再修改一下代码,看一下只有一个margin值为auto时的情况:

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>"</strong><strong>width</strong>:100<strong>px</strong>;<strong>height</strong>: 100<strong>px</strong>;<strong>background</strong>: <strong>#34538b</strong>;<strong>position</strong>: <strong>absolute</strong>;<strong>left</strong>: 0<strong>px</strong>;<strong>right</strong>: 0<strong>px</strong>;<strong>margin-left</strong>: <strong>auto</strong>;<strong>margin-right</strong>: 0<strong>px</strong>;<strong>"</strong>><br />        绝对定位演示<br /></<strong>div</strong>><br /></<strong>div</strong>>
我们把margin-right置为0px,而把margin-left置为auto,显示效果如下:


可以看到,margin-left值是根据公式计算得出的值。

注: IE6/7 ではマージンの自動値が 0 に設定されており、過剰な制約条件下で計算されます。表示効果は次のようになります。


同時に。 time 過制約条件下での左右の値を再計算するルールを検証する。


絶対配置要素の幅と left、margin-left、margin-right、right の値の計算は少し複雑ですが、明確に理解すると理解しやすくなります。誰もが実験を通じてそれを検証することをお勧めします。さらに、IE6/7 では、状況に関係なくマージン値が 0 に設定されることに注意する必要があります。


2.2.8 絶対的に配置された変位要素

絶対的に配置された変位要素を計算する場合、前のセクションの「静的位置」と方程式はすべて該当しますが、計算ロジックは次のように同じではありません:

= "IF: 幅は「幅値幅値の計算ルール」に基づいて計算されます。また、margin-left と margin-right の計算値が両方とも auto の場合、その使用値は次のルールに従って計算されます。 [1]

=》ELSE IF: left と right の計算値がすべて auto である場合、包含ブロックの方向属性が ltr の場合、left は「」の左の位置に設定する必要があります。静的位置」; その逆 次に、「静的位置」の右側の位置に右側の値を設定します。 [2]


=》ELSE IF: left または right が auto の場合、margin-right と margin-left の auto 値を 0 に設定します。 [3]


=》ELSE IF: この時点で margin-right と margin-left が両方とも auto の場合、それらは同じ値になり、センタリング効果を達成するには方程式を確立する必要があります。ただし、この方法で取得したマージン値が負の値である場合、包含ブロックの方向属性が ltr の場合、margin-left を 0 に設定する必要があり、margin-right の値は次の式に従って計算されます。 ; それ以外の場合は、margin-right 値を 0 に設定し、式に従って margin-left の値を計算します。 [4]

=》ELSE IF: 現時点で 1 つの値のみが auto である場合、auto 値は式に従って計算されます。 [5]


=》ELSE IF: この時点で過制約が形成されている場合方向属性が ltr の場合、右の値は無視され、式に従って右が再計算されます。それ以外の場合、左の値は無視され、右の値が式に従って再計算されます。 [6]

これらの例はデモでは説明しませんが、IE6/7 ではまだ margin-left と margin-right の auto を 0 に設定します。


2.2.9 非置換インライン ブロック

表示属性「inline-block」を持つ要素は、既に学習したルールに基づいて、インライン ブロックに対して margin-left が計算されます。 margin-right と width は比較的簡単です。実際、その計算規則は基本的に浮動要素の規則と同じです。


まず、margin-left と margin-right の auto 値が 0 に設定されます。

次に、幅の値が「shrink-to-fit」アルゴリズムに従って計算されます。


2.2.10 インラインブロック置換要素

インラインブロック置換要素の計算方法は、2.2.2 項のインライン置換要素の計算方法と全く同じです


3 分幅と最大幅


🎜

在文章的开头部分曾提到,我们通过上述规则计算得出的width值只是一个tentative value,即暂定的一个值,原因就在于最终width的使用值可能还会受到min-width,和max-width值的影响,下面我们来介绍一下min-width和max-width。


3.1 min-width和max-width属性剖析

CSS标准中对min-width和max-width的定义如下:


These two properties allow authors to constrain content widths to a certain range.

这两个属性的作用就是可以让开发者将一个框的width限定在一个范围中,即[min-width:max-width]范围内。与width属性相同,这两个属性也不适用于行内非置换元素,表格行和表格行组,并且都不具有继承性,可以取绝对的长度值,也可以使用百分比,这些与width属性都是相似的,同时两个属性都不允许负值。


另外,min-width的默认值为0,即所有元素的width都不能小于0;max-width的默认值为none,即不限定元素width的最大值。


3.2 min-width,max-width的使用

min-width和max-width对于width使用值的具体影响如下:

[1]:首先根据第二节中介绍的规则计算得出width值以及相关的margin,left和right值。

[2]:如果计算得出的width值大于max-width,那么就把max-width作为width的使用值,再带入计算规则中计算一遍。

[3]:如果计算得出的width值小于了min-width,那么就把min-width作为width的使用值,再带入计算规则中计算一遍。

下面通过一个实例来实证一下,这里以max-width为例:

##DEMO 6  

max-width的使用

 

代码如下:

<<strong>div </strong><strong>class=</strong><strong>"container"</strong>><br /><<strong>div </strong><strong>style=</strong><strong>"</strong><strong>height</strong>: 100<strong>px</strong>;<strong>background</strong>: <strong>#34538b</strong>;<strong>max-width</strong>: 400<strong>px</strong>;<strong>"</strong>><br />        max-width演示<br /></<strong>div</strong>><br /></<strong>div</strong>>

我们为div定义max-width为400px,如果我们没有定义这个属性的话,由于width值在这里是auto,因此width值应该和包含块的content edge宽度相同,即为500px,但由于我们限定了max-width,并且500px>400px,所以最终width值的使用值就为400px,再把这个值带入到2.2.3节的规则中,就形成了一个过约束的条件,因此忽略margin-right值根等式重新计算,最终得到margin-right:100px。


 


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