包含ブロックの導入後、CSS2.1 標準で width 属性と height 属性が導入されました。これら 2 つの属性もページ レイアウトで重要な役割を果たします。ボックスモデルでは、ボックスのコンテンツ領域を囲む幅と高さ、明示的な定義の有無、ボックスの種類、ボックスのレイアウト、ボックスと他のボックスとの関係、その他の追加情報が含まれます。ボックスの最終的な幅と高さの値に影響を与えるため、この記事ではまず、幅属性と、ビジュアル フォーマット モデルで幅の値を決定する方法の関連アルゴリズムを紹介します。
この記事を読む前に、まずブロックを含む CSS の概念を理解する必要があります。以下を参照してください。 CSS2.1SPEC: ブロックを含むビジュアル フォーマット モデル
1 width 属性の分析
1.1 Value
width 属性には、以下を含むいくつかの異なる値のメソッドがあることがわかります。(1) 幅の値: つまり、CSS の長さの値は、ボックスの幅を明確に指定するために使用されます。値の単位は、px、em など、CSS でサポートされている長さの単位にすることができます。
(2) パーセンテージ: パーセンテージは、含まれるブロックの幅に基づいて計算されます。ただし、含まれるブロックの幅を、含まれるコンテンツに基づいて決定する必要がある場合、最終的なレイアウトは未定義になります。つまり、標準では幅の値の計算方法が明確に指定されていません。さらに、ボックスが絶対的に配置されている場合、その長さのパーセンテージは、含まれているブロックのパディング エッジの幅に基づいて計算されます。
注: 実験の結果、要素の幅がパーセンテージ値であり、その要素を含むブロックの幅をその含まれるブロックの内容に基づいて決定する必要がある場合、状況やブラウザによっては完全に異なることが判明しました。したがって、この場合、レイアウト時に幅の値を定義するためにパーセンテージを使用しないことをお勧めします。具体的なルールはまだまとめる必要があり、研究を行った友人がそれらを共有できます。
(3)auto: CSS 標準で規定されている幅の計算方法に従って計算されます。具体的なアルゴリズムは後で詳しく紹介します
(4)inherit: 実は、width 属性が継承できないのは不思議です。
1.2 適用可能な要素
width は、非置換のインライン要素に適用されます
デフォルトではspan、em)テーブル行(tr)、テーブル行グループ(tbody)要素を除く他のすべての要素。たとえば、span の幅を設定した場合、span の表示属性が inline-block または block に変更されない限り、この幅は効果がありません。また、1.1で述べた通り、width属性は継承できません。
でcss ボックス モデル、ページ上のボックスが占めるスペースに影響する属性には、幅、高さ、マージン、ボーダー、パディングが含まれます。さらに、左、右、上、下の値もサイズに影響します。特定の条件下でのページ上のボックスの位置 (位置は非静的)。これらの属性に明確な値(数値またはパーセンテージ)を定義すると、最終的に使用される値はこの明確な値になります(高さと幅については、最大値または最小値の影響を受ける場合もあります)。この記事では、要素ボックスの水平方向のサイズと位置に影響を与えるプロパティ (width、margin-left、margin-right、padding-left、padding-right、border-left-width、border-right-width) についてのみ説明します。 、左、右)
border-width と padding のデフォルト値は 0 で、auto 値はないため、デフォルトでは、これら 2 つの値の値は 0、margin- left、margin-right のデフォルト値も 0 ですが、auto 値があります。
ただし、デフォルトでは、width、left、right のデフォルト値は auto です。これらの属性では、auto 値の最終的な使用値を計算する必要があります。デフォルトの auto 値の計算方法は次のとおりです。強調表示されます。
2.2 いくつかのサイズと位置の属性値の計算方法
まず、標準の説明を見てみましょう:
要素の 'width'、'margin-left'、' の値レイアウトに使用される margin-right'、'left'、および 'right' プロパティは、生成されるボックスのタイプと相互に依存します (レイアウトに使用される値は、使用される値と呼ばれることもあります)。使用される値は、「auto」が適切な値に置き換えられ、パーセンテージが含まれるブロックに基づいて計算された値と同じですが、例外があります
つまり、width、margin-left、margin-。要素で使用される right、left、right 属性は、生成されるボックスのタイプと相互の関係によって決まります。一般に、最終的に使用される値は計算された値と同じになります。つまり、auto は適切な値に置き換えられます。値、パーセンテージは含まれるブロックに基づいて計算されます。しかし例外もあり、焦点は例外です。
さらに、この規格では次のことも具体的に指摘しています。
注: 以下で計算される「width」の使用値は暫定的な値であり、「min-width」と「min-width」に応じて複数回計算する必要がある場合があります。 「max-width」については、以下の「最小幅と最大幅」のセクションを参照してください。
つまり、幅は min-width または max-width の値にも影響される可能性があるため、不確実な値になります。この記事の終わり こちらも紹介します。
注: 効果を示すために、この記事のすべてのデモには本文に 10 ピクセルのマージン、10 ピクセルのパディング、および 3 ピクセルの境界線が与えられています
2.2.1 非置換インライン要素
非置換用-replacement インライン要素の場合、マージンの auto 値には 0 が割り当てられ、width 属性は適用されません。非置換インライン要素の場合、実際の幅はそれに含まれる実際のコンテンツ (通常はテキスト) によって決まり、また、単語区切り、単語折り返し、および空白属性の影響も受けます。以下に例を示します。
##DEMO 1 行内の非置換要素の幅
次のようなスパンがあります:
< >
<スパン > dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
スパン
>body
>
スパンの幅は 1736px であり、IE6 以降でも同じ効果があることがわかります。
width なので。インラインボックスの部分は包含ブロックによって与えられるので、本文のコンテンツ領域の境界に到達すると、
2.2.2
インライン置換要素 置換要素のコンテンツは CSS レンダリング モデルによって制御されず、多くの場合、固有のディメンションを持ちます。インラインのディスプレイスメント要素によって生成されるボックスの幅を計算するときは、ディスプレイスメント要素の固有のサイズを考慮する必要があります。
まず、マージンの自動値には 0 が割り当てられます
幅の値の計算ロジックは次のとおりです。
=》 IF : height和width都是auto,但是元素有着固有的宽度,那么固有宽度就是width使用值,比如 文本输入框(input[type=text]) ,如果它的width和height都为默认的auto值,那么最终的宽度就是其固有的width,但是在不同浏览器中这个宽度值可能存在差异。[1]
=》 ELSE IF:width为auto值,但元素有固有的宽高比ratio,并且height有确切的值(或者有固有的高度),则width的使用值为:
(used height) * (ratio) [2]
=》 ELSE IF: width和height都为auto,元素有固有的宽高比ratio,但是却没有固有的宽度或者高度,那么元素的宽度是未定义的。(在这种情况下,CSS2.1标准推荐在包含块的宽度不依赖于内容的情况下,按照计算正常流中的块级非置换元素的width值的方法来计算,见本章第3部分)[3]
=》 ELSE IF:元素的width属性为auto,但是有固有的宽度值,那么固有的宽度值就是元素width的使用值 [4]
=》 ELSE IF:元素的width属性为auto,但是上述的几种情况都不符合,那么宽度的使用值为 300px,如果300px超出了用户代理的宽度,那么用户代理应该用能够容纳的最大矩形框的宽度作为width的使用值,并且这个矩形的宽高比为2:1。典型的例子比如canvas和iframe。 [5]
##DEMO 2 iframe的width
有如下代码:
<body>
<iframe src="../fixed.html"></iframe>
</body>
显示的效果为:
可以看到,显示的宽度为300px,高度为150px。
2.2.3 正常流中的块级非置换元素
这种情况是我们在布局时经常会遇到的,我们在body中添加了一个div时,它的宽度是多少?为什么两个正常流的div不能在同一行中显示?学习了这一节的内容,就能解答这两个问题了。
首先,这一节的内容都必须基于以下等式:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
如果width不是auto,而且'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width'
(再加上所有非auto的margin)的值大于包含块的宽度,那么 margin-left和margin-right的所有的auto值在下面的计算中都将被视为0.
=》 IF : 如果上面的值都不是auto,那么这种情况被称为“过约束”,在这种情况下,有一个属性的值将会不同。如果包含块的direction属性为ltr,那么就忽略margin-right,并且利用其它值以及上面的等式计算margin-right的使用值。如果是rtl,那么就重新计算margin-left的值。 [1]
##DEMO 3 过约束条件下的margin值重新计算
我们有如下代码:
< body >
< div style= " width : 100 px ; height : 30 px ; border : 1 px solid #f00 ; " id= "div" > div >
body >
在这种情况下,元素的显示效果如下:
我们再修改一下代码,为元素显式加一个margin-right:
< body >
< div style= " width : 100 px ; height : 30 px ; border : 1 px solid #f00 ; margin-right : 200 px " id= "div" > div >
body >
事实上两种情况是一样的情况,因为margin-right本身的默认值就是0,从显式的效果中可以看出元素的margin-right是被重新计算了的,我们再修改一下代码,把body的direction属性修改为rtl:
< body style= " direction : rtl " >
< div style= " width : 100 px ; height : 30 px ; border : 1 px solid #f00 ; " id= "div" > div >
body >
显式效果也符合标准中所述,IE6+在这一点上都是符合标准的。
=》 ELSE IF:上面这些值中如果只有一个auto值,那么就按照公式计算得出这个auto值[2]
##DEMO 4 只有一个auto值的情况
我们有如下代码:
<body>
<div style="width: 100px;height: 30px;border: 1px solid #f00;margin-left: auto;" id="div"></div>
</body>
这种情况下,只有margin-left属性是auto值(默认为auto),我们看一下显示的效果:
元素的 margin-left 值就等于 包含块的宽度- border-left-width - border-right-width - width
=》 ELSE IF:width是auto,那么其他所有的auto值都设为0,width按照等式来计算。[3]
=》 ELSE IF:margin-left和margin-right都是auto,那么它们的使用值将会相同,并且最终的结果会使得该元素产生的block居中。实际上,这就是我们常用的margin auto居中的方案。[4]
我们用一个DEMO来展示这个效果:
##DEMO 5 width为auto以及margin-left,margin-right都为auto的情况
我们有如下代码:
<<strong>div </strong><strong>style=</strong><strong>"</strong><strong>width</strong>:<strong>auto</strong>;<strong>margin-left</strong>: <strong>auto</strong>;<strong>margin-right</strong>:<strong>auto</strong>;<strong>height</strong>: 30<strong>px</strong>;<strong>border</strong>: 1<strong>px solid </strong><strong>#f00</strong>;<strong>" </strong><strong>id=</strong><strong>"div"</strong>></<strong>div</strong>>
显示效果为:
验证了规则3,即如果width为auto,那么就把其他所有的auto设为0,并且用等式计算width值。
コードを再度変更して、幅の明示的な値を設定してみましょう:
div が中央に配置され、左側と右側のマージンの値が等しいことがわかり、ルール 4 を確認できます。このセンタリング ソリューションは IE6 でも機能します。
2.2.4 通常フローのブロックレベルの変位要素
通常のフローのブロックレベルの変位要素については、幅の値を計算するときにセクション 2.2.2 のルールが引き続き適用されます。 ;
置換された要素の幅の値を取得した後、2.2.3 の規則に従ってマージンの値を計算します。
例を使って検証してみましょう:
##DEMO 6 通常のフローにおけるブロックレベルの置換要素の幅とマージン
次のコードがあります:
< body >
< ;入力 type= "text" style= margin : auto " /> ボディ
>効果は:
input はデフォルトではブロック レベルの要素ではなく、インライン レベルの要素であるため、セクション 2.2.3 のルール 4 に準拠していません。コードを変更して、display:block スタイルを追加しましょう。
<
>
< input
"text" " 余裕 : auto ; display : block " /> body >
効果は次のとおりです:
input要素が表示されているのがわかります。中心。