《CSS世界》

内部尺寸与流体特性

包裹性。

“包裹性”是我自己对“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 所示

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),大家应该就知道实现原理了。


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');
        }
    });
}

我们鼠标经过中间的色块区域的时候 会发现,有一个带有文字信息的半透明黑色条目出现了,如图所示。


alt 信息美美地显示

此时,图片 src 没有,因此,::before 和::after 可以 生效,我们就可以把 alt 属性值通过 content 属性呈现出来

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


src 属性存在时候 :before/:after 失效

*根据我的测试,目前 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 动画效果,颜色大小可控,使用非常方便


loading
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 《CSS 世界》 PDF版 链接 , 使用纸质书效果更好 第4章 深入理解 content 4.1 content...
    Xinxing_Li阅读 812评论 1 0
  • 1 流,元素与基本尺寸 1.1 块级元素 特性:一个水平流上只能单独显示一 个元素,多个块级元素则换行显示 常见的...
    JLUiceman阅读 577评论 0 0
  • 1. width: auto auto 是默认值,至少包含 4 种不同的宽度表现: 充分利用可用空间。比如 ...
    McDu阅读 226评论 0 0
  • 一、块级元素 块级元素是指一个水平留上只能单独显示一个元素,多个块级元素则换行显示。 1.1 块级元素和displ...
    Honwiy阅读 344评论 0 0
  • CSS世界 1. 概念 三种盒子display: block; 外在的“块级盒子”和内在的“块级容器盒子”dis...
    汨逸阅读 269评论 0 1