CSS选择器:伪元素是怎么回事儿?

532 阅读3分钟

本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力

定义

伪元素,英文原名是pseudo-elements。其本质用一句话概括就是“可以向页面内插入内容,而无需在HTML中增加真实的DOM元素”。重点是一个”伪“字,我们常见用到这个字眼的有”伪代码“、”伪君子“等,其含义都是指”只是像,但不是真的“。

关于单冒号和双冒号

单冒号支持所有浏览器,双冒号是CSS3中新产生的,用于区分”伪元素“和”伪类“,建议使用双冒号表示”伪元素“,单冒号表示”伪类“。双冒号语法在IE8中不支持,所以如果不用考虑兼容IE8,最好使用双冒号表示”伪元素“。

伪元素内容

伪元素伪类的重要区别在于,”伪元素“有内容,因为毕竟是要”伪造“一个元素出来。而伪类则单纯地是给已有元素施加不真实存在的样式类(在某种条件下触发)。

伪元素的内容通过content属性声明,可以有以下几种选择:

  • 空字符串
  • 常用字符串或unicode
  • 图片资源
  • 计数器

常见用法

内容置空是最常见的用法,这样我们声明的伪元素没有任何实体内容,但可以通过样式声明,使得页面上出现我们期望的一些小效果。

比如按钮中的箭头

image.png

<div class="my-btn-wrap">
  <div class="my-btn">确定</div>
</div>
.my-btn-wrap {
  padding: 20px;
  background: aliceblue;
}
.my-btn {
  position: relative;
  margin: auto;
  width: 80px;
  height: 40px;
  border: 1px solid #000
  border-radius: 20px;
  line-height: 40px;
  text-align: center;
  background: #fff;
}
.my-btn::after {
  content: '';
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  right: 4px;
  width: 0;
  height: 0;
  border: 6px solid transparent;
  border-left: 6px solid #000;
}

比如聊天软件中的对话气泡

image.png

<div class="msg-wrap-self">
  <span>开始做拍一拍</span>
  <img src="https://user-images.githubusercontent.com/23159565/127432445-57fa5223-9002-4dc1-b557-1ec2710f65ee.jpeg" data-username="wilson" data-tapmsg="" class="avatar-common">
</div>
.msg-wrap-self {
  display: flex;
  padding-top: 10px;
  padding-right: 20px;
  align-self: flex-end;
}
.msg-wrap-self>span {
  position: relative;
  background-color: #aae87a;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 12px;
  margin-right: 12px;
}
.msg-wrap-self>span:after {
  position: absolute;
  top: 48%;
  transform: translateY(-50%);
  right: -10px;
  content: '';
  border-color: transparent;
  border-style: solid;
  border-width: 5px;
  border-left-color: #aae87a;
  border-left-width: 5px;
}
.msg-wrap-self>img {
  width: 25px;
  height: 25px;
  border-radius: 2px;
}

比如提示气泡

image.png

<div class="my-wrap">
  <div class="pop-tip">点击下方按钮下载</div>
  <div class="my-download">下载</div>
</div>
.my-wrap {
  padding: 20px;
  background: aliceblue;
}
.pop-tip {
  position: relative;
  background: pink;
  border-radius: 6px;
  line-height: 40px;
  padding: 0 10px;
  text-align: center;
  margin: 0 80px;
}
.pop-tip::after {
  content: '';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: -20px;
  width: 0;
  height: 0;
  border: 8px solid transparent;
  border-top: 16px solid #ffc0cb;
}
.my-download {
  position: relative;
  margin: auto;
  margin-top: 20px;
  width: 100px;
  height: 40px;
  border: 1px solid #000
  border-radius: 20px;
  line-height: 40px;
  text-align: center;
  background: #fff;
}

content值为普通字符串、unicode或图片资源地址的使用相对不太灵活,一般会通过给content赋值空串,并使用背景图的方式来展示相应内容具有更强样式灵活性。

关于计数器这种用法,可用来替代HTML中创建的li元素,我们以一个例子来展示它的用法。

image.png

<div class="items">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
    <div>item4</div>
</div>
body {
  counter-reset: id;
}
.items {
  margin: 60px 0;
}
.items > div {
  margin: 10px;
  padding: 5px 10px;
  background-color: yellowgreen;
}
.items > div::before {
  counter-increment: id;
  content: '第' counter(id) '条:';
}

总结

总的来说,伪元素主要用于使用CSS来“补充”HTML元素,这样可以将某些小样式内容转移至CSS进行实现,而无需在HTML结构中体现。

这种能力在HTML结构复杂的页面对于减轻页面结构非常有帮助,想象一下,你的页面结构本来就充满的各种层级、布局、容器,当某些元素周边还需要添加一下小的装饰。如果要在原有DOM结构上进行实现,可能需要重新调整部分HTML结构,这时候或许你就可以考虑使用伪元素来进行填充,以此“缓解”HTML结构的复杂度。