所有的前端开发人员都知道,width的默认值是auto。auto因为是默认值,所以出镜率不高,但是,它却是个深藏不露的家伙,它至少包含了以下4种不同的宽度表现。
(1)充分利用可用空间。比方说,、
这些元素的宽度默认是100%于父级容器的。这种充分利用可用空间的行为还有个专有名字,叫做fill-available。
(2)收缩与包裹。典型代表就是浮动、绝对定位、inline-block元素或table元素,英文称为“shrink-to-fit”,直译为“收缩到合适”,有那么点儿意思,但是不够形象。可以理解为“包裹性”。这与CSS3中的fit-content宽度表现一致。
(3)收缩到最小。这个最容易出现在table-layout为auto的表格中,想必大家在开发过程中一定见过如下图所示的一柱擎天的情况。
当每一列空间都不够的时候,文字能断就断,中文是随便断的,但英文单词不能断。于是,每一列被无情地每个字都断掉,形成一柱擎天。这种行为在规范中被描述为“perferred minimum width”或者“minimum content width”。后来还有了一个更加好听的名字“min-content”。
(4)超出容器限制。除非有明确的width相关设置,否则上面3种情况尺寸都不会主动超过父级容器宽度的,但是存在一些特殊情况。例如,内容很长的连续的英文和数字,或者内联元素被设置了white-space:nowrap,则表现为‘恰似一江春水向东流,流到断崖也不回头’。
例如,看下下面的CSS代码:
/* CSS code */.father-box { padding: 6px 0; width: 150px; background-color: red; white-space: nowrap;}.child-box { display: inline-block; background-color: #f0f3f9;}/* HTML code */ 恰似一江春水向东流,流到断崖也不回头这段代码的结果如下图所示:
子元素既保持了inline-block元素的收缩特性,同时又让内容宽度最大,直接无视父级容器的宽度限制。这种现象后来有了专门的属性值描述,这个属性值叫作max-content。
外部尺寸与流体特性(1)正常流宽度。当我们在一个容器里倒入足量的水时,水一定会均匀铺满整个容器。在页面中随便扔一个元素,其尺寸表现就会和这水流一样铺满容器。这就是block容器的流特性。这种特性,所有浏览器的变现都是一致的。所以,当使一个内联元素变为一个块级元素时,就不用设置宽度100%了,除非有特殊要求,需要设置固定宽度。
a { display: block; width: 100%;}元素是内联元素,display默认是inline,所以,设置display: block使其块状化绝对没有问题,但是后面的width: 100%就没有任何出现的必要了。
块级元素的流动性,并不是看上去的宽度100%显示那么简单,而是一种margin/border/padding和content内容区域自动分配水平空间的机制。表现为“外部尺寸”的块级元素一旦设置了宽度,这种流动性就丢失了。
大家来看一个例子:
/* CSS code */.width { width: 100% !important;}.nav { width: 240px; background-color: #cd0000;}.nav-a { display: block; margin: 0 10px; padding: 6px 12px; width: 200px; border-bottom: 1px solid #b70000; border-top: 1px solid #de3636; color: #fff;}.nav-a:first-child { border-top: 0;}.nav-a + .nav-a + .nav-a { border-bottom: 0;}/* HTML code */无宽度,借助流动性 导航一 导航二 导航三width: 100%,丢失流动性 导航一 导航二 导航三这是一个对比演示,上下两个导航均有margin和padding,前者无width设置,完全借助流动性,后者宽度100%。结果,后者的尺寸超出了外部容器宽度,完全就不像“水流”那样完全利用容器空间,即所谓的“流动性丢失”。
(2)格式化宽度。格式化宽度仅出现在“绝对定位模型”中,也就是出现在position属性值为absolute或fixed的元素中。在默认情况下,绝对定位元素的宽度表现是“包裹性”,宽度由内部尺寸决定,但是,对于非替换元素,当left/top或top/bottom对立方位的属性值同时存在的时候,元素的宽度表现为“格式化宽度”,其宽度大小相对于最近的具有定位特性(position属性值不是static)的祖先元素计算。
例如,下面一段CSS代码:
div { position: absolute; left: 20px; right: 20px;}假设该元素最近的具有定位特性的祖先元素的宽度是1000px,则这个元素的宽度就是960px(即1000 - 20 - 20)px。
“格式化宽度”与普通流一样,具有完全的流体性,也就是margin、border、padding和content内容区域同样会自动分配水平(和垂直)空间。
内部尺寸与流体特性所谓“内部尺寸”,简单来讲就是元素的尺寸由内部的元素决定,而非由外部的容器决定。
(1)宽度自适应性。对于一个元素,如果其display属性值是inline-block,那么即使其里面内容再多,只要是正常文本,宽度也不会超过容器。最能说明这一特性的就是“按钮”元素。按钮文字越多宽度越宽(内部尺寸特性),但如果文字足够多,则会在容器的宽度处自动换行(自适应特性)。
按钮通常以两种形式出现在页面代码中:
按钮可能,很有开发者对此没印象。那是因为在实际项目中,按钮上的文字个数比较有限,没机会换行,还有就是标签按钮才会自动换行,标签按钮,默认white-space: pre,是不会换行的,需要将其属性值重置为normal。
那么,这种特性在实际开发有什么作用呢?
请看这个需求:页面某个模块的文字内容是动态的,可能是几个文字,也可能是一句话。然后,希望文字少的时候居中显示,文字超过一行的时候居右显示。该如何实现?
核心CSS代码如下:
.box { padding: 10px; text-align: center;}.content { display: inline-block; text-align: left;}/* HTML code */文字不足一行,居中
文字数量超过一行显示最大数量,居右显示
除了inline-block元素,浮动元素以及绝对定位元素都具有此特性。
(2)首选最小宽度。所谓“首选最小宽度”,指的事元素最适合的最小宽度。以上面的布局样式为例,将外部容器元素的宽度设置为0,里面
元素的宽度是多少?会是0吗?答案当然是否定的。在CSS中,图片和文字的权重要远大于布局,所以CSS的设计者显然不会让图文在width: auto时宽度变成0的,此时所表现的宽度就是“首选最小宽度”。
“首选最小宽度”具体表现规则如下:
东亚文字(如中文)最小宽度为每个汉子的宽度(或者说当前元素设置的字号)西方文字最小宽度由特定的连续的英文字符单元决定,并不是所有的英文字符都会组成连续单元,一般会终止于空格、短横线、问号以及其他非英文字符等。例如,“display:inline-block”这几个字符以连接符“-”作为分隔符,形成了“display:inline”和“block”两个连续单元,由于连接符“-”分隔位置在字符后面,因此,最后的宽度就是“display:inline-”的宽度。如果想让英文字符和中文一样,每一个字符都用最小宽度单元,可以使用CSS中的word-break:break-all。类似图片这样的替换元素的最小宽度就是该元素内容本身的宽度。“首选最小宽度”在实际开发中有什么作用?
可以让开发者遇到类似现象的时候知道原因是什么,方便迅速对症下药,其他就没什么用了。(3)最大宽度。最大宽度就是元素可以有的最大宽度,实际上等同于元素设置white-space:nowrap