如何把css'content的操作跟价值发挥到最大

2019-09-03

JiangRen Mr

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

基本用法

一个简单的例子:

<p>「不会写前端」</p>
复制代码
p {
  &::before {
    content: "欢迎关注"
  }

  &::after {
    content: "微信公众号"
  }
}
复制代码

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

 

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

 

没错,就是这么粗暴,就跟他们的名字一样,一前一后😁

值得注意的是,在新的规范中,单冒号指伪类、双冒号指伪元素,就算你写成:after,标准的浏览器还是会渲染成::after,目的是兼容旧写法👍

可取的值

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

逐一使用

为了使文章简洁,下面有部分content属性在外层省略父元素:

// 原始
p {
  &::after {
    content: "";  
  }
}

// 省略后
content: "";
复制代码

1. 普通字符

content: "我是文字内容";
复制代码

2. unicode

浏览器自带的特殊字符:

p {
  &:after {
    content: "\02691";
    color: red;
  }
}
html特殊字符对照表

 


iconfont自定义字体图标:

<span class="icon icon-close"></span>
复制代码
@font-face {
  font-family: "iconfont";
  src: url('//at.alicdn.com/t/font_1209853_ok7e8ntkhr.ttf?t=1560857741304') format('truetype');
}

.icon {
  font-family: "iconfont";
}

.icon-close::before {
  content: "\e617";
}
复制代码

显示如下:

 

iconfont-阿里巴巴矢量图标库

 

3. attr函数

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

<p data-content="我是文字内容"></p>
复制代码
content: attr(data-content);
复制代码

4. url函数

显示我的掘金头像:

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-resetcounter-increment😎


counter-reset的作用是定义一个计数器:

counter-reset: count1 0; // 声明一个计数器count1,并从0开始计算
counter-reset: count2 1; // 声明一个计数器count2,并从1开始计算
counter-reset: count3 0 count4 0 count5 0; // 声明多个计数器
复制代码

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

counter-reset: count 0;
counter-increment: count 2; // 使count自增2,当前count的值为2
counter-increment: count -2; // 使count自增-2,当前count的值为-2
复制代码

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

div {
  width: 100px;
  width: 200px; // 实际渲染的宽度
}
复制代码

6. css变量

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

// string类型
--name: "不会写前端";

p {
  &::after {
    content: var(--name); // 显示为"不会写前端"
  }
}

---------- 我是分割线 ----------

// int类型
--count: 60;

p {
  &::after {
    counter-reset: color var(--count);
    content: counter(count); // 显示为"60"
  }
}

---------- 我是分割线 ----------

// 不支持的类型及情况
--count: 60.5; // 显示为"0",不支持小数
--count: 60px; // 显示为"",不支持css属性值
复制代码

拼接

普通字符串拼接:

content: "xxx" + "xxx";
复制代码

字符串拼接函数:

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

隐性转换:

content: 0; // 显示为""
content: "" + 0; // 显示为"0"
content: "" + attr(name); // 显示为"attr(name)"
复制代码

实用案例

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

<a href="https://juejin.im/user/587e1822128fe1005706db1c"></a>
复制代码
a {
  &:empty {
    &::after {
      content: "链接内容为:" attr(href);
    } 
  }
}
复制代码

显示如下:

 

2. 面包屑跟分隔符

<ul>
  <li>首页</li>
  <li>商品</li>
  <li>详情</li>
</ul>
复制代码
ul {
  display: flex;
  font-weight: bold;

  li {
    &:not(:last-child) {
      margin-right: 5px;
        
      &::after {
        content: "\276D";
        margin-left: 5px;
      }
    }
  }
} 

 

之前还这样写来着😂

<li v-for="(item, index) in list">
  <span>{{item}}</span>
  <span v-show="index < list.length - 1">、</span>
</li>
复制代码

3. 进度条

<div class="progress" style="--percent: 14;"></div>
<div class="progress" style="--percent: 41;"></div>
<div class="progress" style="--percent: 94;"></div>
复制代码
.progress {
  width: 400px;
  height: 17px;
  margin: 5px;
  color: #fff;
  background-color: #f1f1f1;
  font-size: 12px;

  &::before {
    counter-reset: percent var(--percent);
    content: counter(percent) "%"; // 文字显示
    
    display: inline-block;
    width: calc(100% * var(--percent) / 100); // 宽度计算
    max-width: 100%; // 以防溢出
    height: inherit;
    text-align: right;
    background-color: #2486ff;
  }
}

加个过渡效果:

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

 

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

.progress {
  &::before {
    // 移除width跟transition属性
    animation: progress 1s ease forwards;
  }
  
  @keyframes progress {
    from {
      width: 0;
    }

    to {
      width: calc(100% * var(--percent) / 100);
    }
  }
}

 

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

4. tooltip提示

<button data-tooltip="我是一段提示">按钮</button>
复制代码
[data-tooltip] {
  position: relative;
  
  &::after {
    content: attr(data-tooltip); // 文字内容
    display: none; // 默认隐藏
    position: absolute;
    
    // 漂浮在按钮上方并居中
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translate(-50%, 0);
    
    padding: 5px;
    border-radius: 4px;
    color: #fff;
    background-color: #313131;
    white-space: nowrap;
    z-index: 1;
  }
    
  // 鼠标移入button的时候显示tooltip
  &:hover {
    &::after {
      display: block;
    }
  }
}


多方向、主题、动画实现可以移步我之前写过的一篇文章:利用css‘content实现指令式tooltip文字提示🤡

5. 计算checkbox选中的个数

<form>
  <input type="checkbox" id="one">
  <label for="one">波霸奶茶</label>
  <input type="checkbox" id="two">
  <label for="two">烤奶</label>
  <input type="checkbox" id="three">
  <label for="three">咖啡</label>
  
  <!-- 输入结果 -->
  <div class="result">已选中:</div>
</form>
复制代码
form {
  counter-reset: count 0;
  
  // 当checkbox选中的时候,计数器自增1
  input[type="checkbox"] {
    &:checked {
      counter-increment: count 1;
    }
  }
  
  // 输出结果
  .result {
    &::after {
      content: counter(count);
    }
  }
}

 

6. 给目录加章节计数

<!-- 章节 -->
<ul class="section">
  <li>
    <h1>自我介绍</h1>

    <!-- 子章节 -->
    <ul class="subsection">
      <li>
        <h2></h2>
      </li>
      <li>
        <h2></h2>
      </li>
    </ul>
  </li>
  
  <li>
    <h1>写一段css代码</h1>
  </li>
</ul>
复制代码
// 章节
.section {
  counter-reset: section 0; // 外层计数器

  h1 {
    &::before {
      counter-increment: section 1; // 自增1
      content: "Section"counter(section) ". ";
    }
  }

  // 子章节
  .subsection {
    counter-reset: subsection 0; // 内层计数器

    h2 {
      &::before {
        counter-increment: subsection 1; // 自增1
        content: counter(section) "."counter(subsection); // 计数器是有作用域的,这里可以访问外层计数器
      }
    }
  }
}

7. 加载中...动画
<p>加载中</p>
复制代码
p {
  &::after {
    content: ".";
    animation: loading 2s ease infinite;

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

      66% {
        content: "...";
      }
    }
  }
}

 

8. 无更多数据

<div class="no-more">无更多数据</div>
复制代码
.no-more {
  &::before {
    content: "——";
    margin-right: 10px;
  }


  &::after {
    content: "——";
    margin-left: 10px;
  }
}
复制代码

效果如下:

 

总结

content始终都需要配合beforeafter伪元素使用,主要是显示一些额外的信息,更多案例需要大家去挖掘,只要脑洞大👍,篇幅较长,如有内容或知识点出错,请大家纠正!

 

本文章转载自掘金。

 

近期开课hot

Python零基础入门

start2025/02/12 03:14 (Sydney)

Web全栈班24期 NodeJS方向

start2024/12/08 11:30 (Sydney)

logo

Follow Us

linkedinfacebooktwitterinstagramweiboyoutubebilibilitiktokxigua

We Accept

/image/layout/pay-paypal.png/image/layout/pay-visa.png/image/layout/pay-master-card.png/image/layout/pay-stripe.png/image/layout/pay-alipay.png

地址

Level 10b, 144 Edward Street, Brisbane CBD(Headquarter)
Level 2, 171 La Trobe St, Melbourne VIC 3000
四川省成都市武侯区桂溪街道天府大道中段500号D5东方希望天祥广场B座45A13号
Business Hub, 155 Waymouth St, Adelaide SA 5000

Disclaimer

footer-disclaimerfooter-disclaimer

JR Academy acknowledges Traditional Owners of Country throughout Australia and recognises the continuing connection to lands, waters and communities. We pay our respect to Aboriginal and Torres Strait Islander cultures; and to Elders past and present. Aboriginal and Torres Strait Islander peoples should be aware that this website may contain images or names of people who have since passed away.

匠人学院网站上的所有内容,包括课程材料、徽标和匠人学院网站上提供的信息,均受澳大利亚政府知识产权法的保护。严禁未经授权使用、销售、分发、复制或修改。违规行为可能会导致法律诉讼。通过访问我们的网站,您同意尊重我们的知识产权。 JR Academy Pty Ltd 保留所有权利,包括专利、商标和版权。任何侵权行为都将受到法律追究。查看用户协议

© 2017-2024 JR Academy Pty Ltd. All rights reserved.

ABN 26621887572