《css 世界》content

1. content 与替换元素

替换元素(<img> <object> <video> <iframe> 或表单元素如 <textarea> <input> <select>),顾名思义,内容可替换,其他特性:

  1. 替换元素的外观不受 css 的影响。如何改变替换元素的外观,需要类似 appearence 属性,或浏览器自身暴露的一些样式接口,如 ::-ms-check{} 可更改高版本 IE 浏览器下单复选框的内间距、背景色等样式,但直接 input[type="checkbox"]{} 却无法更改。
  2. 有自己的尺寸。很多替换元素在没有明确尺寸设定的情况下,其默认的尺寸(不包括边框)是 300px * 150px,如 video、iframe、canvas 查看case,也有少部分替换元素为 0px,如 img。而表单元素的替换元素的尺寸与浏览器有关,没有明显的规律。
  3. 在很多 css 属性上有自己的一套表现规则。比如 vertical-align 属性,对于非替换元素,默认值是 baseline,即 x 字符的下边缘,替换元素的内容没有 x 字符,于是基线被定义成了元素的下边缘。

2. 替换元素尺寸计算

css > html > 固有尺寸

  1. 如果固有尺寸具有固有的宽高比例,同时仅设置了高度或宽度,则元素按固有的宽高比例显示。
  2. 内联替换元素和块级替换元素使用同一套计算规则。
    如:case
    img {display: block;}
    <img src="1.jpg"/>
    
    虽然图片变成了块级,但是尺寸规则还是和内联状态下一致。这也是为何图片及其他表单类替换元素设置 display:block 宽度却没有 100% 容器的原因。
  3. 图片的 content 替换内容默认的适配方式是 object-fit: fill,其他属性 object-fit:none object-fit:contain case

3. 替换元素与非替换元素之间的关系

  1. 相差一个 src 查看demo
  2. 相差一个 content
    demo1 使用 content 属性生成一张图片。 Chrome 下,所有的元素都支持 content 属性,而其他浏览器仅在 ::before/::after 伪元素下支持。
    demo2 使用 content 属性替换将图片为另一张图片。content 属性改变的仅是视觉呈现,当右键保存的时候,仍是保存的 src 对应的图片。
    demo3 让普通标签元素变成替换元素。视觉上文字被替换了,但屏幕阅读器阅读的还是文字内容,搜索引擎抓取的还是文本信息,对页面的可访问性没有任何影响。想在移动端使用该技术,建议使用 SVG 矢量图片。
  3. content 属性生成的内容被称为“匿名替换元素”。
    1. content 生成的文本无法选中、无法复制,好像设置了 user-select:none,同时,无法被屏幕阅读设备读取、无法被搜索引擎抓取。
    2. 不能左右 :empty 伪类。case
    3. content 动态生成值无法获取。

4. content 内容生成技术

在实际项目中,content 属性几乎都用在 ::before/::after 这俩个伪元素中,因此,“content 内容生成技术”有时候也称为“::before/::after伪元素技术”。

4.1 content 辅助元素生成

此应用的核心不在 content 生成的内容,而在于伪元素本身,通常,会把 content 设置为空字符串。

.element::before {
    content: '';
}

然后,利用其它 css 代码来生成辅助元素,或实现图形效果,或实现特定布局。
还有一个常见应用,清除浮动带来的影响:

.clear::after {
    content: '';
    display: table;  /* or block */
    clear: both;
}

demo 两端对齐
jsfiddle case

// div 与第一个 i 之间不能换行
    <div id="box" class="box"><i class="bar"></i>
        <i class="bar"></i>
        <i class="bar"></i>
        <i class="bar"></i>
    </div>
    .box {
          width: 256px;
          height: 256px;
          border-bottom: 1px dashed #ccc;
          text-align: justify;
          background-color: #f9f9f9;
    }

    .bar {
        display: inline-block;
        width: 20px; height: 0;
    }

    /* 底对齐 */
    .box:before {
        content: "";
        display: inline-block;
        height: 100%;
    }

    /* 两端对齐 */
    .box:after {
        content: "";
        display: inline-block;
        width: 100%;
    }

4.2 content 字符内容生成

比如配合 @font-face 规则实现图标字体效果 demo

除了 content 内容为常规字符,还可以插入 Unicode 字符,比较经典的是插入换行符来实现某些布局或效果。

::after {
    content: '\A';
    white-space: pre;
}

'\A':换行符中的 LF 字符,其 Unicode 编码是 000A,在 content 中直接写作 '\A'
'\D':换行符中的 CR 字符,其 Unicode 编码是 000D。

实例:实现动态 ... 加载效果 case

正在加载中<dot>...</dot>
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); }
}

实现原理:插入 3 行内容,分别是 3 个点、2 个点和 1 个点,然后通过 transfrom 控制垂直位置,依次展示每行内容。

伪元素使用 ::before 同时 display 设置为 block,是为了在高版本浏览器下原来的 3 个点推到最下面,不会影响 content 的 3 行内容显示,使用 ::after 恐怕就很难实现。

4.3 content 图片生成

content 图片生成指的是直接使用 URL 功能符显示图片,URL 中的地址可以是常见的 png、jpg 格式,也可以是 ico 图片、svg 文件和 base64URL 地址,但不支持 css3 渐变背景图。

div::before {
  content: url(1.jpg);
}

demo

4.4 content 开启闭合符合生成

css 中有个 quotes 属性,可以指定 open-quote close-quote 具体是什么。

case 针对不同语言指定不同的前后符号。

<p lang="ch"><q>中文</q></p>
<p lang="en"><q>This book is very good!</q></p>
<p lang="no"><q>denne bog er fantastisk!</q></p>
:lang(ch) > q {
  quotes: '“' '”';
}

:lang(en) > q {
  quotes: '"' '"';
}

:lang(no) > q {
  quotes: '<' '>';
}

case “提问、回答”

4.5 content attr 属性值内容生成

img::after {
  content: attr(alt);
}

.icon::before {
    content: attr(data-title);  /* 自定义属性 */
}

4.6 content 计数器

计数器两个属性:counter-reset counter-increment
一个方法:counter()/counters()

  1. counter-reset:计数器-重置,给计数器命名,顺便告诉从哪个数字开始计数,默认是 0. demo
.xxx {
  counter-reset: name 3; /* 从 3 开始计数*/
}
.xxx::before {
  content: counter(name);
}

多个计数器 demo

.xxx {
  counter-reset: name1 3 name2 4; /* name1 从 3 开始计数, name2 从 4 开始*/
}
.xxx::before {
  content: counter(name1);
}
.xxx::after {
  content: counter(name2);
}

counter-reset 还可以设置为 none 和 inherit,取消重置以及继承重置。

  1. counter-increment:计数器递增,值为 counter-reset 的 1 个或多个关键字,后面可以跟随数字,表示每次计数的变化值。缺省为 1。
    counter-increment 一旦出现,会在 counter-reset 初始值上增加。counter() 负责输出。
  2. counter() 显示计数。
counter(name)
counter(name, style)

style 即为 list-style-type 支持的值,作用是:我们递增递减的可以不一定是数字,还可以是英文字母或罗马文等。demo
counter() 支持级联。demo

  1. counters():嵌套计数
counters(name, style)

style 参数为字符串(需要引号包围,必需参数),表示子序号的连接字符串。例如,1.1 的 string 就是 .1-1 的 string 就是 -

要实现嵌套,必须让每个列表容器拥有一个 counter-reset ,通过子辈对父辈的 counter-reset 重置、配合 counters() 方法实现。
demo

<div class="reset">
    <div class="counter">我是王小二
        <div class="reset">
            <div class="counter">我是王小二的大儿子</div>
            <div class="counter">我是王小二的二儿子
                <div class="reset">
                    <div class="counter">我是王小二的二儿子的大孙子</div>
                    <div class="counter">我是王小二的二儿子的二孙子</div>
                    <div class="counter">我是王小二的二儿子的小孙子</div>
                </div>
            </div>
            <div class="counter">我是王小二的三儿子</div>
        </div>
    </div>
    <div class="counter">我是王小三</div>
    <div class="counter">我是王小四
        <div class="reset">
            <div class="counter">我是王小四的大儿子</div>
        </div>
    </div>
</div>
.reset { 
  padding-left: 20px; 
  counter-reset: wangxiaoer;
}
.counter::before { 
  content: counters(wangxiaoer, '-') '. '; 
  counter-increment: wangxiaoer;
}

demo2 reset 必须唯一

显示 content 计数值的那个 DOM 元素在文档流中的位置一定要在 counter-increment 元素后面,否则没有计数效果。

4.7 content 内容生成的混合特性

是指 content 内容生成语法可以混合在一起使用

a::after {
  content: "(" attr(href) ")";
}

q::before {
    content: open-quote url(1.jpg);
}

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