CSS | 盒模型的宽度计算规则

2019-04-14 21:55发布

文章目录

前言

以下内容默认以标准盒模型即content-box为标准。

width 属性

width 属性:
在标准盒模型中,width指定了盒的内容宽度(content width) 属性 取值 可选值 指定长 / 百分比 / auto / inherit 默认值 auto 适用元素 除非替换的行内元素,表格行和行组(row group) 外的所有元素 可继承性 否 取值含义: 取值 含义 auto 宽度取决于其它属性的值 指定长度 用具体长度指定内容区宽度,负值非法。 百分比 参照包含块的宽度,以百分比形式指定当前盒宽度。注意:1.如果包含块的宽度取决于该元素宽度,使用百分比布局是未定义的。2.绝对定位元素的百分比参考的是其第一个非static祖先元素的padding box宽度

详细计算规则

盒模型的总宽度计算中,将涉及元素的属性left, margin, padding, border, width, right,以下将根据不同盒类型和场景进行分类解析:
其中相对定位元素的left与right值的计算规则请参考相对定位下,盒偏移量计算规则

计算值与应用值

下面的表述将涉及计算值与应用值两个概念。
计算值是经过层叠的指定值,直白地说,即初始值,继承值和用户指定值三者中最终参与计算的值。
应用值为实际用于布局时的值。大多数时候,应用值与计算值是相同的,都会根据规则将auto替换成相应合适的值。但下文将遵循文档原文,以“当计算值为XXX,其应用值为XXX”的语句来描述规则。

行内非替换元素

  • width属性不适用。行内非替换元素的宽度由实际内容宽度决定。
  • 当margin-left/margin-right的计算值为auto时,其应用值为0
span{ margin: auto } 根据规则根据规则根据规则

行内替换元素,常规流中的替换inline-block,浮动的替换元素

  • 当margin-left或margin-right的计算值为auto时,其应用值为0
  • 当height和width计算值都为auto,若该元素具有固有宽度,width的应用值为固有宽度值。
  • 当height和width的计算值都为auto,若该元素没有固有宽度,但具有固有高度或指定高度值,且拥有固有比例;则width的应用值 = (高度的应用值) * (固有比例)
  • 当height和width的计算值都为auto,若该元素没有固有宽高,则width的应用值是未定义的。

常规流中的块级非替换元素

常规流中的块级非替换元素的宽度计算规则满足以下恒等式:
margin-left + border-left + padding-left+ width + padding-right + border-right + margin-right = 包含块宽度 其中 margin,padding,border的默认值为0
在这里插入图片描述
此计算规则与BFC中块级元素“独占一行”的特性相吻合
  • 当width不为auto且 border + padding + width < 包含块宽度时,若margin-left/margin-right均有指定值,则margin被过度约束
    此时,若包含块的direction为ltr,则margin-left的指定值有效,margin-right指定值无效,根据恒等式重新计算该值。若包含块的direction为rtl,则margin-right的指定值有效。
    示例:
    下例中,包含块direction为ltr,margin-left指定值有效。
在这里插入图片描述 .container { direction: ltr; background: orangered; width: 200px; height: 200px; margin: 50px; } .son { margin-left: 10px; margin-right: 10px; background: royalblue; width: 100px; height: 100px; }
  • 若width为auto,则width = 内容块宽度 - 当前所有指定值的和,所有其它auto值设为0。
    在这里插入图片描述
.son{ border: solid; margin-left: 80px; margin-right: auto; padding-left: auto; padding-right: 20px; text-align: center }
  • 当width不为auto,且margin-left和margin-right都是auto时,它们的应用值相等。此时,该元素相对于包含块边界水平居中。
    这就是块级元素通过 margin:0 auto 水平居中的原理。注意:margin默认值为0,所以需要手动设置auto
.son{ width: 300px; border: solid; margin-left: auto; margin-right: auto; text-align: center } 在这里插入图片描述

常规流中的块级替换元素

width的应用值由行内替换元素决定。其它属性值由非替换块级元素的规则确定
在这里插入图片描述 img{ display: block; padding: 0 20px; margin: 0 auto; }

浮动的非替换元素,常规流中的非替换inline-block

若margin-left或margin-right的计算值为auto,则其应用值为0
若width的计算值为auto,应用值就是自适应(shrink-to-fit)宽度,CSS文档并未定义自适应宽度的具体算法,它大多数情况下表现为由子元素的最大指定宽度撑开,但忽略绝对定位子元素的宽度,考虑float元素的宽度。
示例:
在这里插入图片描述 .container{ float: left; height: 200px; background: salmon } .pre{ width: 200px; height: 100px; background: seagreen } .fl{ float: left; height: 100px; width: 400px; background: royalblue } .ab{ position: absolute; height: 50px; width: 500px; background: rgb(114, 216, 148) } <div class="container"> <div class="ab">div> <div class="pre">div> <div class="fl">div> div>

绝对定位的非替换元素*

绝对定位元素的包含块是第一个非static定位的祖先元素的padding box。

静态位置

CSS在处理绝对定位时,会首先假想position:static下的元素盒,称其为绝对定位元素的静态位置,假想盒的包含盒称为静态位置包含盒。
静态位置上的元素left值为 包含块的padding box 左边界 - 元素的margin box 左边界的距离,right值类似。
出于计算静态位置的目的,fixed定位元素的包含块为初始包含块,而不是视口,并且所有可滚动的盒应该假设滚动到其起点。

一般计算规则

绝对定位元素的总宽度计算满足,以下恒等式:
left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 包含块的宽度
其中,包含块,下文称实际包含块,指的是绝对定位元素的第一个非static父元素的padding box,不是假想盒的包含块。
  • 当left,width和right全不是auto时,
  1. 若margin-left,margin-right都是auto,设定margin-left = margin-right。
    示例:
    在这里插入图片描述
.container { position: relative; width: 250px; height: 250px; background: skyblue; } .ab { position: absolute; width: 125px; left: 10px; right: 10px; margin: 0 auto; height: 125px; background: tomato; } <div class="container"> <div class="ab">div> div>
  1. 若margin-left / margin-right其中之一为auto,则带入恒等式直接求值。
  2. 若margin-left/ margin-right 均不为auto,则根据实际包含块的direction忽略left或right,若direction为ltr,则left指定值生效,right忽略,反之,right指定值生效。
    示例:
    当实际包含块的direction为rlt时,right指定值生效。
    在这里插入图片描述
.container { position: relative; direction: rtl; width: 250px; height: 250px; background: skyblue; } .ab { position: absolute; width: 125px; left: 10px; right: 10px; margin: 0 10px; height: 125px; background: tomato; } <div class="container"> <div class="static"> <div class="ab">div> div> div>
  • 除上述情况,其它情况下,均把值为auto的margin-left和margin-right设置为0,再根据其它属性的取值情况,应用以下的某条规则。
  1. 当left,width和right全为auto时,根据direction,设定left或right为静态位置值,再套入下面对应的规则。
  2. 当left和width都是auto,right不是auto,则宽度自适应,再求出left。
  3. 当right和width都是auto,left不是auto,则宽度自适应,再求出right。
  4. 当left和right都是auto,width不是auto,若静态位置包含块的direction是ltr,就把left设置为静态位置,然后求出right。若direction是rtl,则反之。
  5. 当left,width和right中仅一个为auto时,则将其带入恒等方程,得到其应用值。

绝对定位的替换元素

width的应用值由行内替换元素规则决定。其它规则与非替换元素类似,相当于指定了width的非替换元素参与规则计算。