内部尺寸与流体特性
包裹性。
“包裹性”是我自己对“shrink-to-fit”理解后的一种称谓,我个人觉得非常形象好记,一直 用了很多年。“包裹性”也是 CSS 世界中很重要的流布局表现形式。 中文就是博大精深,顾名思义,“包裹性”,除了“包裹”,还有“自适应性”。“自适应性” 是区分后面两种尺寸表现很重要的一点。那么这个“自适应性”指的是什么呢? 所谓“自适应性”,指的是元素尺寸由内部元素决定,但永远小于“包含块”容器的 尺寸(除非容器尺寸小于元素的“首选小宽度” )。换句话说就是,“包裹性”元素冥冥 中有个 max-width:100%罩着的感觉(注意,此说法只是便于大家理解,实际上是有明 显区别的) 。 因此,对于一个元素,如果其 display 属性值是 inline-block,那么即使其里面内容 再多,只要是正常文本,宽度也不会超过容器。于是,图文混排的时候,我们只要关心内容, 除非“首选小宽度”比容器宽度还要大,否则我们完全不需要担心某个元素内容太多而破坏 了布局。
“包裹性”对实际开发有什么作用呢?
请看这个需求:页面某个模块的文字内容是动态的,可能是几个字,也可能是一句话。然 后,希望文字少的时候居中显示,文字超过一行的时候居左显示。该如何实现? 核心 CSS 代码如下:
.box { text-align: center; }
.content { display: inline-block; text-align: left; }
HTML:
<div class="box">
<p id="conMore" class="content">文字内容</p>
</div>
<!-- 按钮 -->
<p><button id="btnMore">更多文字</button></p>


除了 inline-block 元素,浮动元素以及绝对定位元素都具有包裹性, 均有类似的智能宽度行为。
首选最小宽度。
所谓“首选小宽度”,指的是元素适合的小宽度。我们接着上面的例子,在上面例子 中,外部容器的宽度是 240 像素,假设宽度是 0,请问里面的 inline-block 元素的宽度是多少? 是 0 吗?不是。在 CSS 世界中,图片和文字的权重要远大于布局,因此,CSS 的设计者显 然是不会让图文在 width:auto 时宽度变成 0 的,此时所表现的宽度就是“首选小宽度”。 具体表现规则如下。
• 东亚文字(如中文)小宽度为每个汉字的宽度。
• 西方文字小宽度由特定的连续的英文字符单元 决定。并不是所有的英文字符都会组成连续单元, 一般会终止于空格(普通空格)、短横线、问号以 及其他非英文字符等。例如,“display:inline- block”这几个字符以连接符“-”作为分隔符,形 成了“display:inline”和“block”两个连续 单元,由于连接符“-”分隔位置在字符后面,因此, 后的宽度就是“display:inline-”的宽度, 如果想让英文字符和中文一样,每一个字符都用小宽度 单元,可以试试使用 CSS 中的 word-break:break-all。
• 类似图片这样的替换元素的小宽度就是该元素内容本身的宽度。
“首选最小宽度”对我们实际开发有什么作用呢?
可以让我们遇到类似现象的时候知道原因是什么,方便迅速对症下药,其他就没什么用了。
有点失望?那好,我就举个利用“首选小宽度”构建图形的例子吧。请问,如何使用一 层 HTML 标签分别实现图 3-13 所示

的“凹”和“凸”效果(注意要兼容 IE8)? 由于要兼容 IE8,CSS 新世界中图形构建利器的盒阴影和背景渐变全都没有用武之地,怎 么办呢?我们可以利用“首选小宽度”的行为特点把需要的图形勾勒出来。核心 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你";
}
HTML:
<span class="ao"></span>
<span class="tu"></span>
还没看明白?那我把文字颜色放出来(见图 3-14),大家应该就知道实现原理了。

利用连续英文单词不换行的特性,我们就可以控制什么地方“凹”,什么地方“凸”啦!
min-width/min-height 的初始值是 auto,max-width/max- height的初始值是none
超越!important
针对下面的 HTML 和CSS 设置,图片后呈现的宽度是多少呢?
<img src="1.jpg" style="width:480px!important;">
img { max-width: 256px; }
答案是 256px。style、!important 通通靠边站!因为 max-width 会覆盖 width。
超越最大
超越大指的是min-width覆盖max-width,此规则发生在min-width和max-width 冲突的时候。例如,下面这种设置:
.container {
min-width: 1400px;
max-width: 1200px;
}
小宽度居然比大宽度设置得还大,?遵循 “超越大”规则(注意不是“后来居上”规则),min-width 活下来,max-width 被忽略, 于是,.container 元素表现为至少 1400 像素宽。
基于伪元素的图片内容生成技术
虽然“基于伪元素的图片内容生成技术”并不属于实用技术,但是,实际网页开发的时候, 会有一些场景必须使用<img>标签,此时,这些隐蔽的技术往往就会有神迹表现。我这里举个 小例子抛砖引玉一下,上一小节提到使用缺省 src 的<img>元素实现滚屏加载效果,但是,就 有可能存在这样一个体验问题:如果我们的 JavaScript 加载比较慢,我们的页面就很有可能出 现一块一块白色的图片区域,纯白色的,没有任何信息,用户完全不知道这里的内容是什么。 虽然 alt 属性可以提供描述信息,但由于视觉效果不好,被隐藏掉了。此时,我们总不免畅想: 要是在图片还没加载时就把 alt 信息呈现出来该多好啊。 恭喜你可以美梦成真!办法就是使用这里的“基于伪元素的图片内容生成技术”。
HTML:
<img alt="美女沉思图" data-src="1.jpg">
<p><button>设置src属性显示图片</button></p>
CSS:
img {
display: inline-block;
width: 256px; height: 192px;
/* 隐藏Firefox alt文字 */
color: transparent;
position: relative;
overflow: hidden;
}
img:not([src]) {
/* 隐藏Chrome alt文字以及银色边框 */
visibility: hidden;
}
img::before {
/* 淡蓝色占位背景 */
content: "";
position: absolute; left: 0;
width: 100%; height: 100%;
background-color: #f0f3f9;
visibility: visible;
}
img::after {
/* 黑色alt信息条 */
content: attr(alt);
position: absolute;
left: 0; bottom: 0;
width: 100%;
line-height: 30px;
background-color: rgba(0,0,0,.5);
color: white;
font-size: 14px;
transform: translateY(100%);
/* 来点过渡动画效果 */
transition: transform .2s;
visibility: visible;
}
img:hover::after {
transform: translateY(0);
}
JS:
var eleButton = document.querySelector('button'),
eleImg = document.querySelector('img');
if (eleButton && eleImg) {
var initValueButton = eleButton.innerHTML;
// 图片地址
var srcImage = eleImg.getAttribute('data-src');
// 移除该属性
eleImg.removeAttribute('data-src');
// 按钮点击事件
eleButton.addEventListener('click', function() {
if (this.innerHTML == initValueButton) {
this.innerHTML = '移除src属性';
// 图片显示
eleImg.setAttribute('src', srcImage);
} else {
this.innerHTML = initValueButton;
// src属性移除
eleImg.removeAttribute('src');
}
});
}
我们鼠标经过中间的色块区域的时候 会发现,有一个带有文字信息的半透明黑色条目出现了,如图所示。

此时,图片 src 没有,因此,::before 和::after 可以 生效,我们就可以把 alt 属性值通过 content 属性呈现出来
下面是此技术有意思的部分。当我们点击按钮给图片添 加一个 src 地址时,图片从普通元素变成替换元素,原本都还 支持的::before 和::after 此时全部无效,此时再 hover 图 片,是不会有任何信息出现的(见下图 )。于是就非常巧妙地 增强了图片还没加载时的信息展示体验。 细细体味会发现,这一体验增强实现非常巧妙地利用了 替换元素的各种特性表现,并且在 HTML 层面并没有任何其他代码或内容的辅助,可谓是非常高性价比的技术实现,大家不妨在自己的项目中小试 一下.

*根据我的测试,目前 Chrome 和 Firefox 等浏览器支持,但 IE 浏览器不支持;其次,要想让 Chrome 或 Firefox 等浏览器生效,还有其他一些需要注意的 技术点。
(1)不能有 src 属性(证明观点的关键所在);
(2)不能使用 content 属性生成图片(针对 Chrome);
(3)需要有 alt 属性并有值(针对 Chrome);
(4)Firefox 下::before 伪元素的 content 值会被无视,::after 无此问题,应该与 Firefox 自己占用了::before 伪元素的 content 属性有关。 *
content 字符内容生成
content 字符内容生成就是直接写入字符内容,中英文都可以,比较常见的应用就是配合 @font-face 规则实现图标字体效果。例如,下面这个例子:
@font-face {
font-family: "myico"; src: url("/fonts/4/myico.eot");
src: url("/fonts/4/myico.eot#iefix") format("embedded-opentype"),
url("/fonts/4/myico.ttf") format("truetype"),
url("/fonts/4/myico.woff") format("woff"); }
.icon-home:before {
font-size: 64px;
font-family: myico;
content: "家";
}
<span class="icon-home"></span>
此时,页面显示的可能就不是一个“家”字,而是一个图标
另外一个值得介绍的点就是,除常规字符之外,我们还可以插入 Unicode 字符,比较经典 的就是插入换行符来实现某些布局或者效果。核心 CSS 代码如下:
:after {
content: '\A'; white-space: pre;
}
很多人可能会问:这个'\A'是什么?'\A'其实指的是换行符中的 LF 字符,其 Unicode 编码是 000A,在 CSS 的 content 属性中则直接写作'\A';换行符除了 LF 字符还有 CR 字符, 其 Unicode 编码是 000D,在 CSS 的 content 属性中则直接写作'\D'。CR 字符和 LF 字符分 别指回车(CR)和换行(LF),content 字符生成强大之处就在于不仅普通字符随便插,Unicode 字符也不在话下。 那它具体有什么作用呢?很显然,作用就是换行。那换行又有什么用呢?确实,很多时候, 换行效果看上去没什么特别之处,我在 HTML 中弄个
标签不是照样有一样的效果?但是 content 字符生成在某些场景下真的可以大放异彩,我们不妨看下面这个配合 CSS3 animation 用来实现字符动画效果的例子。
我们动态加载页面内容的时候,经常会使用“正在加载中...”这几个字,基本上,后面的 3 个点都是静态的。静态的问题在于,如果网络不流畅,加载时间比较长,就会给人有假死的 感觉,但是,如果是点点点这种横向的动画效果,用户就会耐心很多,体验也会好很多,用户 流失率就会有所下降。没错,我们可以利用这里的'\A'换行特性让“...”这几个字符动起来, HTML 和 CSS 代码如下:
HTML:
正在加载中<dot>...</dot>
CSS:
dot {
display: inline-block;
height: 1em;
line-height: 1;
text-align: left;
vertical-align: -.25em;
overflow: hidden;
}
dot::before {
display: block;
content: '...\A..\A.';
white-space: pre-wrap;
animation: dot 3s infinite step-start both;
}
@keyframes dot {
33% { transform: translateY(-2em); }
66% { transform: translateY(-1em); }
}
效果即达成,IE6 至 IE9 浏览器下是静态的点点点,支持 animation 动画的浏览器下全 部都是打点 loading 动画效果,颜色大小可控,使用非常方便

网友评论