两层盒子
每个元素都两个盒子, 外在盒子
和内在容器盒子
。外在盒子
负责元素是可以一行显示,还是只能换行显示;内在容器盒子
负责 宽高、内容呈现什么的。按照display
的属性值不同,值为 block
的元素的盒子实际由外在的“块级盒子” 和内在的“块级容器盒子”组成,值为inline-block
的元素则由外在的“内联盒子”和内在的“块级容器盒子”组成,值为 inline
的元素则内外均是“内联盒子”。
盒子分“内在盒子”和“外在盒子”,显示也分“内部 显示”和“外部显示”,同样地,尺寸也分“内部尺寸”和“外部尺寸”。其中“内部尺寸”英 文写作“Intrinsic Sizing”,表示尺寸由内部元素决定;还有一类叫作“外部尺寸”,英文写作“Extrinsic Sizing”,宽度由外部元素决定。
width:auto 中,就第一个,也就是<div>默认宽度 100%显示,是“外部尺寸”,其余 全部是“内部尺寸”。而这唯一的“外部尺寸”,是“流”的精髓所在。
1. 外部尺寸与流体特性
(1)正常流宽度。
当我们在一个容器里倒入足量的水时,水一定会均匀铺满整个容器。
水流自动铺满容器示意
- 在页面中随便扔一个<div>元素,其尺寸表现就会和这水流一样铺满容器。这就是 block 容器的流特性。这种特性,所有浏览器的表现都是一致的。
- 表现为“外部尺寸”的块级元素一旦设置了宽度,流动性就丢失了。
- 所谓流动性,并不是看上去的宽度 100%显示这么简单,而是一种 margin/border/padding 和 content 内容区域自动分配水平空间的机制。
HTML
<h4>无宽度,借助流动性无宽度,借助流动性 </h4>
<div class="nav">
<a href="" class="nav-a">导航1</a>
<a href="" class="nav-a">导航2</a>
<a href="" class="nav-a">导航3</a>
</div>
<h4>width:100%</h4>
<div class="nav">
<a href="" class="nav-a width">导航1</a>
<a href="" class="nav-a width">导航2</a>
<a href="" class="nav-a width">导航3</a>
</div>
css
.width {
width: 100%;
}
.nav {
background-color: #cd0000;
}
.nav-a {
display: block;
margin: 0 10px;
padding: 9px 10px;
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;}
屏幕快照 2018-07-05 下午4.43.11.png
上下两个导航均有 margin 和 padding,前者无 width 设置,完全借助流特性,后者宽度 width:100%。结果,后者的尺寸超出了外部的容器,完全就不像“水流” 那样完全利用容器空间,即所谓的“流动性丢失”。
(2)格式化宽度。
格式化宽度仅出现在“绝对定位模型”中,也就是出现在 position 属性值为 absolute 或 fixed 的元素中。在默认情况下,绝对定位元素的宽度表现是“包裹性”,宽度由内部尺寸决定,但是,有一种情况其宽度是由外部尺寸决定的,是什么情况呢?
对于非替换元素,当 left/top 或 top/bottom 对立方位的属性值同时存在的时候,元素的宽度表现为“格式化宽度”,其宽度大小相对于最近的具有定位特(position 属性值不是 static)的祖先元素计算。
例如,下面一段 CSS 代码:
div { position: absolute; left: 20px; right: 20px; }
假设该<div>元素最近的具有定位特性的祖先元素的宽度是 1000 像素,则这个<div>元素的宽 度是 960(即 1000−20−20)像素。
2. 内部尺寸与流体特性
所谓“内部尺寸”,简单来讲就是元素的尺寸由内部的元素决定,而非由外部的容器决定。如何快速判断一个元素使用的是否 为“内部尺寸”呢? 很简单,假如这个元素里面没有内容,宽度就是 0,那就是应用的“内部尺寸”。
内部尺寸的三种表现形式
(1)包裹性。
“包裹性”,除了“包裹”,还有“自适应性”。“自适应性”是区分后面两种尺寸表现很重要的一点。所谓“自适应性”,指的是元素尺寸由内部元素决定,但永远小于“包含块”容器的 尺寸(除非容器尺寸小于元素的“首选最小宽度”)。换句话说就是,“包裹性”元素冥冥中有个 max-width:100%罩着的感觉(注意,此说法只是便于大家理解,实际上是有明显区别的)。因此,对于一个元素,如果其 display 属性值是 inline-block,那么即使其里面内容再多,只要是正常文本,宽度也不会超过容器。
CSS 世界为何要设计“包裹性”呢?
按钮就是 CSS 世界中极具代表性的 inline-block 元素,可谓展示“包裹性”最好的例 子,具体表现为:按钮文字越多宽度越宽(内部尺寸特性),但如果文字足够多,则会在容器的 宽度处自动换行(自适应特性)。
“包裹性”对实际开发有什么作用呢?
请看这个需求:页面某个模块的文字内容是动态的,可能是几个字,也可能是一句话。然后,希望文字少的时候居中显示,文字超过一行的时候居左显示。该如何实现?
HTML:
<div class="box">
<div class="conent">
文字多文字多文字多文字多文字多文字多文字多
</div>
</div>
CSS:
.box{
text-align: center;
width: 200px;
background-color: red;
}
.conent{
display: inline-block;
text-align: left;
}
文字少的时候
文字为两行的时候
除了 inline-block 元素,浮动元素以及绝对定位元素都具有包裹性, 均有类似的智能宽度行为。
(2)首选最小宽度。
首选最小宽度,指的是元素适合的最小宽度,在上面的例子中,外部容器的宽度是200px,如果宽度是0,那么里面的inline-block的元素的宽度是什么?
是 0 吗?不是。在 CSS 世界中,图片和文字的权重要远大于布局,因此,CSS 的设计者显 然是不会让图文在 width:auto 时宽度变成 0 的,此时所表现的宽度就是“首选最小宽度”。
首选最小宽度,具体表现规则如下:
- 东亚文字(如中文)最小宽度为每个汉字的宽度。
- 西方文字最小宽度由特定的连续的英文字符单元决定。并不是所有的英文字符都会组成连续单元, 一般会终止于空格(普通空格)、短横线、问号以及其他非英文字符等。
如果想让英文字符和中文一样,每一个字符都用最小宽度 单元,可以试试使用 CSS 中的 word-break:break-all。
- 类似图片这样的替换元素的最小宽度就是该元素内容本身的宽度。
首选最小宽度”对我们实际开发有什么作用呢?
可以让我们遇到类似现象的时候知道原因是什么,方便迅速对症下药,其他就没什么用了。
有点失望? 那好,我就举个利用“首选最小宽度”构建图形的例子吧。请问,如何使用一 层 HTML 标签分别实现下图所示的“凹”和“凸”效果(注意要兼容 IE8)?
image.png由于要兼容 IE8,CSS 新世界中图形构建利器的盒阴影和背景渐变全都没有用武之地,怎么办呢?我们可以利用“首选最小宽度”的行为特点把需要的图形勾勒出来。
HTML:
<span class="ao"></span>
<span class="tu"></span>
CSS :
.ao,
.tu {
display: inline-block;
width: 0;
font-size: 14px;
line-height: 18px;
margin: 35px;
color: #fff;
}
.ao:before,
.tu:before {
outline: 2px solid #cd0000;
font-family: Consolas, Monaco, monospace;
}
.ao:before {
content: "love你love";
}
.tu {
direction: rtl;
}
.tu:before {
content: "我love你";
}
网友评论