CSS中content属性的妙用

前言

本文讲解CSS中使用频率并不高的content属性,通过多个实用的案例,带你由浅入深的掌握content的用法,让代码变得更加简洁、高效。

封面图

定义

W3school中这样定义:

content 属性与 :before 及 :after 伪元素配合使用,来插入生成内容。

该属性用于定义元素之前或之后放置的生成内容。默认地,这往往是行内内容,不过该内容创建的框类型可以用属性 display 控制。

在前端日常开发中,content属性使用频率并不高,所以开发者一般对它的理解并不深入,通常会在清除浮动、字体图标时偶尔使用。下面通过各种案例,来一起看看content的妙用。

案例

1. 清除浮动

<!--css-->
.left {float: left}
.right {float: right}
.clear:after {
    content: '';
    clear: both;
    display: block;
}

<!--html-->
<div class="container clear">
    <div class="left">左</div>
    <div class="right">右</div>
</div>

父元素.container中两个子元素.left.right浮动后会脱离文档流,无法撑起容器,造成.container高度为0。使用伪元素:after清除浮动,三个属性缺一不可:

  • content: ''; 通过:after添加一个内容为空的伪元素。
  • clear: both; 伪元素:after两侧浮动清除。
  • dispaly: block; 设置块元素,因为clear只对块元素有效。

说到clear属性,使用最多的就是clear: bothleft/right用的却很少,因为both已经包含left/right特性,简单直接还有效。想更加深入了解clear属性,可以看看张鑫旭大神的准确理解CSS clear:left/right的含义及实际用途

2. 小三角的气泡窗口

<!--css-->
.box {
    width: 200px;
    height: 100px;
    border-radius: 5px;
    background: #fff;
    position: relative;
}
.box:after {
    content: '';
    position: absolute;
    bottom: -20px;
    right: 20px;
    width: 0;
    height: 0;
    border-top: 10px solid #fff;
    border-bottom: 10px solid transparent;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
}

<!--html-->
<div class="box"></div>

效果:

配合伪元素:after,实现了一个右下角带倒三角指向性的气泡窗口。通过调整border各边的颜色和绝对定位位置,可以绘制出指向不同的气泡窗口,只用一个div标签实现,是不是既简洁又美观。可能你会想到这是伪元素:after的效果,和content属性无关,实际上去掉content:after是不生效的。

3. 字体图标

第一种是浏览器自带的特殊字符:

<!--css-->
.music:before {
    content: '\266C';
    color: red;
}

<!--html-->
<span class="music">晴天-周杰伦</span>

效果:

浏览器支持很多字体图标,如:天气☀、雪花❄、三叶草☘、太极☯等等有趣的字符。参考网页HTML特殊字符编码对照表

第二种是外部引入字体图标,如Bootstrap中的Glyphicon字体图标:

<link rel="stylesheet" href="../static/css/bootstrap.min.css">

<!--html-->
<span class="glyphicon glyphicon-heart"></span>

效果:

这里为什么没有写CSS样式呢,因为bootstrap.min.css中已经定义好了glyphicon-heart的样式,直接在官网上查看:

需要说明的是,本地引入bootstrap.min.css后,还需要引入字体图标库glyphicons-halflings-regular.woff2,字体图标才能生效。

<!--bootstrap.min.css-->

<!--format 属性是帮助浏览器识别字体的-->
@font-face {
    font-family: 'Glyphicons Halflings';
    src: url(../fonts/glyphicons-halflings-regular.eot);
    src: url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),
    url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),
    url(../fonts/glyphicons-halflings-regular.woff) format('woff'),
    url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),
    url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')
}

按照上述url路径,将glyphicons-halflings-regular.woff2放到如下目录结构中即可。

4. 无内容提示

<!--css-->
<!--:empty为空时匹配-->
div:empty:after {
    content: '暂无数据';
    color: red;
}

<!--html-->
<div>有内容数据</div>
<div></div>

效果:

当元素内容为空时,通过content内容“暂无数据”进行展示。可使用场景:后台接口返回数据后,插入到页面DOM中,当后台返回数据为空时,通过CSS直接提示暂无数据,不需要使用JavaScript处理。

一个有趣的现象,content内容“暂无数据”无法被选中,这是因为伪元素用于创建一些不在文档树中的元素,虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。

5. 面包屑菜单

<!--css-->
ul li {
    display: inline-block;
    font-weight: bold;
}

ul li:not(:last-child):after {
    content: '\276D';
    margin: 5px;
}

<!--html-->
<ul>
    <li>首页</li>
    <li>商品</li>
    <li>详情</li>
</ul>

效果:

又是一个content值为特殊字符的例子,配合伪类和伪元素完成面包屑菜单。

6. 加载中...动画

<!--css-->
.loading:after {
    content: ".";
    animation: loading 2s ease infinite;
}

@keyframes loading {
    33% {
        content: "..";
    }
    66% {
        content: "...";
    }
}

<!--html-->
<p class="loading">加载中 </p>

效果:

animation动画值含义:

  • loading:animation-name,规定需要绑定到选择器的 keyframe 名称为loading。
  • 2s:animation-duration,规定完成动画所花费的时间2秒。
  • ease:animation-timing-function,规定动画的速度曲线,先慢中快后慢。
  • infinite:animation-iteration,规定动画应该播放的次数为无限次。

通过animation动画完成33%、66%时与content内容配合,实现动态“加载中...”的效果。

7. 插入图片

<!--css-->
.loading:before {
    content: url("../static/img/loading.gif");
    vertical-align: middle;
}

<!--html-->
<div class="loading"> 加载中... </div>

效果:

除了插入字体图标,content还可以使用url()方法插入图片,和background属性类似可以使用url指定一个图片路径,不同的是content属性无法控制图片大小,使用条件有限。

8. attr属性内容生成

<!--css-->
.web:after {
    content: "("attr(href)")"
}

<!--html-->
<a class="web" href="https://echeverra.cn">echevera</a>

效果:

content值也可以是attr()方法,用来获取指定属性的值,可插入到指定的位置。

9. 半边特效

<!--css-->
span{
    font-family: sans-serif;
    font-size: 30px;
    font-weight: bold;
    position: relative;
    color: green;
}
span:before{
    content: attr(text);
    color: orange;
    position: absolute;
    left: 0;
    top: 0;
    width: 50%;
    overflow: hidden;
}

<!--html-->
<span text="echeverra">echeverra</span>
<span text="博">博</span>
<span text="客">客</span>

效果:

半边特效是通过attr()方法获取text属性值,属性值与其内容相同,巧妙的设置绝对定位,只显示一半并覆盖了原文本内容,实现文字半边特效,是不是还挺炫酷的。需要注意的是有些font-family字体会有文字无法重合的问题。

10. 文字引号

<!--css-->
span {
    quotes: '“' '”';
}
span:before {
    content: open-quote;
}
span:after {
    content: close-quote;
}

<!--html-->
<p>鲁迅说过:<span>真正的勇士,敢于直面惨淡的人生,敢于正视淋漓的鲜血。</span></p>

效果:

利用元素的quotes属性指定双引号,使用contentopen-quote属性值设置开口引号,close-quote属性值设置闭合引号,当然quotes也可以指定其他符号。

11. 添加章节数

<!--css-->
ul{
    counter-reset: section;
}
li{
    list-style-type: none;
    counter-increment: section;
}
li:before{
    content: counters(section, '-') '.';
}

<!--html-->
<ul>
    <li>章节一</li>
    <li>章节二
        <ul>
            <li>章节二一</li>
            <li>章节二二</li>
            <li>章节二三</li>
        </ul>
    </li>
    <li>章节三</li>
    <li>章节四</li>
    <li>章节五
        <ul>
            <li>章节五一</li>
            <li>章节五二</li>
        </ul>
    </li>
    <li>章节六</li>
</ul>

效果:

这里用到了counter计数器方法,涉及到counter-resetcounter-incrementcounter()counters()几个属性。

  • counter-reset用来指定计数器名称,例子中命名为section,同时可以指定计数器开始计数的数值,如指定开始计数数值为1:counter-reset: section 1;,不指定默认为0

  • counter-increment用来指定计数器每次递增的值,如指定计数器递增值为2:counter-increment: section 2;,默认值为1,counter-increment只要指定了counter-reset,对应的计数器的值就会变化。

  • counter(name, style)用来输出计数器的值。其中name为计数器名称,style可选参数,默认为阿拉伯数字,也可指定list-style-type支持的值,如罗马数字lower-roman

  • counters(name, strings, style)用来处理嵌套计数器,同样是输出计数器的值,和counter()不同的是多了一个strings参数,表示子序号的连接字符串。例如1.1string就是'.'1-1就是'-'

关于计数器的详细的教程,同样可以参考CSS大神张鑫旭的CSS counter计数器(content目录序号自动递增)详解

12. 计算checkbox选中数

<!--css-->
form {
    counter-reset: count 0;
}

input[type="checkbox"]:checked {
    counter-increment: count 1;
}

.result:after {
    content: counter(count);
}

<!--html-->
<form>
    <input type="checkbox" id="javaScript">
    <label for="javaScript">javaScript</label>
    <input type="checkbox" id="PHP">
    <label for="PHP">PHP</label>
    <input type="checkbox" id="Python">
    <label for="Python">Python</label>

    <div class="result">已选:</div>
</form>

效果:

巧妙运用计数器配合:checked伪类,选中计数器增加1,取消选中减1,用CSS实现动态计数功能。

总结

总结content属性值可以为以下几种:

  • string字符串,最常见的,对应案例:清除浮动、小三角的气泡窗口、字体图标、无内容提示、面包屑菜单、加载中...动画。
  • url()方法,对应案例:插入图片。
  • attr()方法,对应案例:attr属性内容生成、半边特效。
  • quotes引号,对应案例:文字引号。
  • counter()方法,计数器功能,对应案例:添加章节数,计算checkbox选中数。

尽管使用javaScript同样可以实现上述的大部分功能,灵活性也更高,但使用CSS的好处就是可以极大地简化开发,不占用JS主线程,提升web的性能。

其实content的案例远不止于此,在查阅相关资料的同时,我还见识到了另外一些神奇的用法,当然原理大致相同,本文的案例只是尽可能的带你了解content不为人知的一面,打开一个全新的世界,让你举一反三。如果能在实际开发中运用上,那就更Nice了,希望能对大家有所帮助。

你学“废”了么?

参考文章:

(完)

文章首发于我的博客 https://echeverra.cn/css-content,原创文章,转载请注明出处。

欢迎关注我的微信公众号 echeverra,一起学习进步!不定时会有资源和福利相送哦!

评论

  1. 弋儿
    Windows Chrome
    3月前
    2021-9-03 10:08:44

    你的文章在电脑上看不全的说,滑到最后有一些文字是看不到的,会闪出一个空页。左侧的目录定位不大准。

    • echeverra 博主
      Windows Chrome
      3月前
      2021-9-03 10:12:58

      多谢提出宝贵意见,其他文章也有同样的现象么?用chrome浏览器或者清下浏览器缓存试试

  2. echeverra 博主
    Windows Chrome
    已编辑
    3月前
    2021-9-03 10:37:44

    谢谢大家来我的小博客,今早网站差点被点爆了,查看后台统计才知道这篇文章有幸被阮一峰老师收录到最新一期的博客周刊中https://www.ruanyifeng.com/blog/2021/09/weekly-issue-174.html,再次感谢阮一峰老师的引流。

  3. 电池社区
    Windows Chrome
    3月前
    2021-9-14 11:08:00

    从阮神的网站来的流量也没有特别海量,也就是一天内突然来了一千四百多个IP,根据wp统计,可能实际IP人数应该比这个数少,VP也就3276,平均下来,一个IP最多点击了你网站2个页面。1天24小时,24小时有1440分钟,就算去除晚上和其他闲余23个小时,就按照1个小时内,你的网站突然来了1468个IP访问量,再给你加上各种搜索引擎蜘蛛访问IP数,就按一小时来了1500个IP访问,产生4000VP,那么平均下来1分钟内,也就25个IP访问量,VP量也就66.67,这个访问量,你的站就挂了~。。。从截图看,明显是数据库跟主程序按照在同一个云主机中,即使wordpress程序对数据库访问次数再高,才这么一点流量就导致数据库挂了,我建议你核查一下你这个主题程序,有没有什么漏洞或者木马,另外查一查你的数据库在当时的访问日志,是不是当时存在被攻击的情况。
    一核CPU才21.4%负荷,1818MB的内存也才76.7%使用量,这个说明服务器并不处于高负荷状态,但是负载却100%,建议你另外查一下你的服务器配置情况,以及服务器有没有被挂东西~
    总之,按照你截图的访问量,对于1核1G的独立云服务器来说,并不算什么。。。。除非你用的是哪种最便宜共享型云,硬件配置本身属于不好的服务器。

    • echeverra 博主
      Windows Chrome
      3月前
      2021-9-14 17:30:55

      哈哈,有心了,之所以高负荷可能是因为服务器不只运行着博客,我还搭建了游戏服务

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇