css'content操作一波

/

2019-8-27

content属性需要与before及after伪元素配合使用,作用是可以定义伪元素所显示的内容,本文主要列举content的可选值及实用的案例与技巧

基本用法

一个简单的例子:

  1. <p>「不会写前端」</p>
  1. p {
  2. &::before {
  3. content: "欢迎关注"
  4. }
  5. &::after {
  6. content: "微信公众号"
  7. }
  8. }

浏览器显示的是这个亚子:

我们看看实际上在浏览器渲染的结构:

没错,就是这么粗暴,就跟他们的名字一样,一前一后
值得注意的是,在新的规范中,单冒号指伪类、双冒号指伪元素,就算你写成:after,标准的浏览器还是会渲染成::after,目的是兼容旧写法

可取的值

  1. 普通字符
  2. unicode
  3. attr函数
  4. url函数
  5. counter函数
  6. css变量

    逐一使用

    为了使文章简洁,下面有部分content属性在外层省略父元素:
    `html
    // 原始
    p {
    &::after {
    content: “”;
    }
    }

// 省略后
content: “”;

  1. ## 1. 普通字符
  2. ```html
  3. content: "我是文字内容";

2. unicode

浏览器自带的特殊字符:

  1. p {
  2. &:after {
  3. content: "\02691";
  4. color: red;
  5. }
  6. }

显示如下:

html特殊对照表

iconfont自定义字体图标:

  1. <span class="icon icon-close"></span>
  1. @font-face {
  2. font-family: "iconfont";
  3. src: url('//at.alicdn.com/t/font_1209853_ok7e8ntkhr.ttf?t=1560857741304') format('truetype');
  4. }
  5. .icon {
  6. font-family: "iconfont";
  7. }
  8. .icon-close::before {
  9. content: "\e617";
  10. }


iconfont-阿里巴巴矢量图标库

3. attr函数

顾名思义,这个函数可以获取html元素中某一属性的值,如id、class、style等

  1. <p data-content="我是文字内容"></p>
  1. content: attr(data-content);

4. url函数

显示我的头像:

  1. content: url("https://user-gold-cdn.xitu.io/2019/8/7/16c681a0fb3e84c4?imageView2/1/w/180/h/180/q/85/format/webp/interlace/1");

显示如下:

5. counter函数

counter函数的作用是插入计数器的值,配合content属性可以把计数器里的值显示出来,介绍用法之前,得先熟悉两个属性counter-reset跟counter-increment
counter-reset的作用是定义一个计数器:

  1. counter-reset: count1 0; // 声明一个计数器count1,并从0开始计算
  2. counter-reset: count2 1; // 声明一个计数器count2,并从1开始计算
  3. counter-reset: count3 0 count4 0 count5 0; // 声明多个计数器

counter-increment使计数器的值递增,可以理解成javascript中的+=:

  1. counter-reset: count 0;
  2. counter-increment: count 2; // 使count自增2,当前count的值为2
  3. counter-increment: count -2; // 使count自增-2,当前count的值为-2

注意,这里的计数器count的值为什么不是变回了0,可以理解成样式覆盖,就如以下代码:

  1. div {
  2. width: 100px;
  3. width: 200px; // 实际渲染的宽度
  4. }

6. css变量

显示变量的时候,如果变量是string类型则可以直接显示,如果是int类型,则需要借用counter函数

  1. // string类型
  2. --name: "不会写前端";
  3. p {
  4. &::after {
  5. content: var(--name); // 显示为"不会写前端"
  6. }
  7. }
  8. ---------- 我是分割线 ----------
  9. // int类型
  10. --count: 60;
  11. p {
  12. &::after {
  13. counter-reset: color var(--count);
  14. content: counter(count); // 显示为"60"
  15. }
  16. }
  17. ---------- 我是分割线 ----------
  18. // 不支持的类型及情况
  19. --count: 60.5; // 显示为"0",不支持小数
  20. --count: 60px; // 显示为"",不支持css属性值

拼接

普通字符串拼接:

  1. content: "xxx" + "xxx";

字符串拼接函数:

  1. // 不能使用 + 连接符,也可以不需要空格,这里只是为了区分
  2. content: "我支持" attr(xx);
  3. count: "我的掘金头像:" url("xxxxx");
  4. content: "计数器的值为:" counter(xx);

隐性转换:

  1. content: 0; // 显示为""
  2. content: "" + 0; // 显示为"0"
  3. content: "" + attr(name); // 显示为"attr(name)"

实用案例

1. 当a标签内容为空时,显示其href属性里面的值:

  1. <a href="https://juejin.im/user/587e1822128fe1005706db1c"></a>
  1. a {
  2. &:empty {
  3. &::after {
  4. content: "链接内容为:" attr(href);
  5. }
  6. }
  7. }

2. 面包屑跟分隔符

  1. <ul>
  2. <li>首页</li>
  3. <li>商品</li>
  4. <li>详情</li>
  5. </ul>
  1. ul {
  2. display: flex;
  3. font-weight: bold;
  4. li {
  5. &:not(:last-child) {
  6. margin-right: 5px;
  7. &::after {
  8. content: "\276D";
  9. margin-left: 5px;
  10. }
  11. }
  12. }
  13. }

显示如下:

之前还这样写来着

  1. <li v-for="(item, index) in list">
  2. <span>{{item}}</span>
  3. <span v-show="index < list.length - 1">、</span>
  4. </li>

3.进度条

  1. <div class="progress" style="--percent: 14;"></div>
  2. <div class="progress" style="--percent: 41;"></div>
  3. <div class="progress" style="--percent: 94;"></div>
  1. .progress {
  2. width: 400px;
  3. height: 17px;
  4. margin: 5px;
  5. color: #fff;
  6. background-color: #f1f1f1;
  7. font-size: 12px;
  8. &::before {
  9. counter-reset: percent var(--percent);
  10. content: counter(percent) "%"; // 文字显示
  11. display: inline-block;
  12. width: calc(100% * var(--percent) / 100); // 宽度计算
  13. max-width: 100%; // 以防溢出
  14. height: inherit;
  15. text-align: right;
  16. background-color: #2486ff;
  17. }
  18. }

显示如下:

加个过渡效果:

  1. transition: width 1s ease; // 页面首次进入没有过渡效果,因为width必须要发生变化才行

鱼和熊掌不可兼得,如果只靠css,想在页面首次进入触发动画效果,那只有animation才能做到了

  1. .progress {
  2. &::before {
  3. // 移除width跟transition属性
  4. animation: progress 1s ease forwards;
  5. }
  6. @keyframes progress {
  7. from {
  8. width: 0;
  9. }
  10. to {
  11. width: calc(100% * var(--percent) / 100);
  12. }
  13. }
  14. }

页面刷新后效果如下:

参考文章:小tips: 如何借助content属性显示CSSvar变量值

4. tooltip提示

  1. <button data-tooltip="我是一段提示">按钮</button>
  1. [data-tooltip] {
  2. position: relative;
  3. &::after {
  4. content: attr(data-tooltip); // 文字内容
  5. display: none; // 默认隐藏
  6. position: absolute;
  7. // 漂浮在按钮上方并居中
  8. bottom: calc(100% + 10px);
  9. left: 50%;
  10. transform: translate(-50%, 0);
  11. padding: 5px;
  12. border-radius: 4px;
  13. color: #fff;
  14. background-color: #313131;
  15. white-space: nowrap;
  16. z-index: 1;
  17. }
  18. // 鼠标移入button的时候显示tooltip
  19. &:hover {
  20. &::after {
  21. display: block;
  22. }
  23. }
  24. }

效果如下:

多方向、主题、动画实现可以看这篇文章:利用css‘content实现指令式tooltip文字提示

5. 计算checkbox选中的个数

  1. <form>
  2. <input type="checkbox" id="one">
  3. <label for="one">波霸奶茶</label>
  4. <input type="checkbox" id="two">
  5. <label for="two">烤奶</label>
  6. <input type="checkbox" id="three">
  7. <label for="three">咖啡</label>
  8. <!-- 输入结果 -->
  9. <div class="result">已选中:</div>
  10. </form>
  1. form {
  2. counter-reset: count 0;
  3. // 当checkbox选中的时候,计数器自增1
  4. input[type="checkbox"] {
  5. &:checked {
  6. counter-increment: count 1;
  7. }
  8. }
  9. // 输出结果
  10. .result {
  11. &::after {
  12. content: counter(count);
  13. }
  14. }
  15. }

效果如下:

6. 给目录加章节计数

  1. <!-- 章节 -->
  2. <ul class="section">
  3. <li>
  4. <h1>自我介绍</h1>
  5. <!-- 子章节 -->
  6. <ul class="subsection">
  7. <li>
  8. <h2></h2>
  9. </li>
  10. <li>
  11. <h2></h2>![](/attached/image/20190901/20190901231001_941.png)
  12. </li>
  13. </ul>
  14. </li>
  15. <li>
  16. <h1>写一段css代码</h1>
  17. </li>
  18. </ul>
  1. // 章节
  2. .section {
  3. counter-reset: section 0; // 外层计数器
  4. h1 {
  5. &::before {
  6. counter-increment: section 1; // 自增1
  7. content: "Section"counter(section) ". ";
  8. }
  9. }
  10. // 子章节
  11. .subsection {
  12. counter-reset: subsection 0; // 内层计数器
  13. h2 {
  14. &::before {
  15. counter-increment: subsection 1; // 自增1
  16. content: counter(section) "."counter(subsection); // 计数器是有作用域的,这里可以访问外层计数器
  17. }
  18. }
  19. }
  20. }

显示如下:

7. 加载中…动画

  1. <p>加载中</p>
  1. p {
  2. &::after {
  3. content: ".";
  4. animation: loading 2s ease infinite;
  5. @keyframes loading {
  6. 33% {
  7. content: "..";
  8. }
  9. 66% {
  10. content: "...";
  11. }
  12. }
  13. }
  14. }

效果如下:

8. 无更多数据

  1. <div class="no-more">无更多数据</div>
  1. .no-more {
  2. &::before {
  3. content: "——";
  4. margin-right: 10px;
  5. }
  6. &::after {
  7. content: "——";
  8. margin-left: 10px;
  9. }
  10. }

效果如下:

总结

content始终都需要配合before跟after伪元素使用,主要是显示一些额外的信息,篇幅较长,如有内容或知识点出错,请纠正!

Reproduced please indicate the author and the source, and error a link to this page.
text link: /20.html

不要让懒惰占据你的大脑,不让要妥协拖跨你的人生。青春就是一张票,能不能赶上时代的快车,你的步伐掌握在你的脚下,good luck3

Say something...

Website
Username
Email
2019/7/29上线