本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力。
前言
本文将从使用 CSS 实现一个太极图,作为出发点,循序渐进,让大家了解到伪元素能解决什么问题?和为什么会有伪元素,那现在就可以动手,写代码,实现一个太极吧。
实现太极图
html 代码
<div class="yinyang">
<div class="one"></div>
<div class="two"></div>
</div>
css 代码
* {
padding: 0;
margin: 0;
}
body {
background: rgb(152, 152, 152);
}
.yinyang {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border-radius: 50%;
background: linear-gradient(to bottom, #fff 0%, #fff 50%, #000 50%, #000 100%);
}
.yinyang > .one {
box-sizing: border-box;
position: absolute;
left: 0;
top: 50px;
width: 100px;
height: 100px;
border: 40px solid #000;
border-radius: 50%;
background: #fff;
}
.yinyang > .two {
box-sizing: border-box;
position: absolute;
right: 0;
top: 50px;
width: 100px;
height: 100px;
border: 40px solid #fff;
border-radius: 50%;
background: #000;
}
上面的代码可以优化吗?可以优化的,我们看看上面的 CSS 代码,是不是重复相同的代码,这就可以优化。
可以改成这样。
* {
padding: 0;
margin: 0;
}
body {
background: rgb(152, 152, 152);
}
.yinyang {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border-radius: 50%;
background: linear-gradient(to bottom, #fff 0%, #fff 50%, #000 50%, #000 100%);
}
.yinyang > .one,
.yinyang > .two {
box-sizing: border-box;
position: absolute;
top: 50px;
width: 100px;
height: 100px;
border-radius: 50%;
}
.yinyang > .one {
left: 0;
border: 40px solid #000;
background: #fff;
}
.yinyang > .two {
right: 0;
border: 40px solid #fff;
background: #000;
}
可以让太极动起来吗?可以,需要使用到 CSS3 动画:animation。
完整的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手把手教你用 css 画太极</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
background: rgb(152, 152, 152);
}
.yinyang {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border-radius: 50%;
background: linear-gradient(to bottom, #fff 0%, #fff 50%, #000 50%, #000 100%);
animation: spin 3s linear infinite;
}
.yinyang > .one,
.yinyang > .two {
box-sizing: border-box;
position: absolute;
top: 50px;
width: 100px;
height: 100px;
border-radius: 50%;
}
.yinyang > .one {
left: 0;
border: 40px solid #000;
background: #fff;
}
.yinyang > .two {
right: 0;
border: 40px solid #fff;
background: #000;
}
/* css3 动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="yinyang">
<div class="one"></div>
<div class="two"></div>
</div>
</body>
</html>
上面的代码还可以继续优化吗?可以,不知道大家有没有留意到两个 div 的作用,仅仅是用来布局显示,没有其他作用,那我们可以不使用 div 吗?这就要使用到我们的伪元素啦。
优化
我们在上一版的代码,不使用那两个 div 元素,改用伪元素来实现。我们来看看,怎么改造吧。
其实就是删掉那两个 div,将 .yinyang > .one 改成 .yinyang::before,还有将 .yinyang > .two 改成 .yinyang::after。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手把手教你用 css 画太极</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
background: rgb(152, 152, 152);
}
.yinyang {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border-radius: 50%;
background: linear-gradient(to bottom, #fff 0%, #fff 50%, #000 50%, #000 100%);
animation: spin 3s linear infinite;
}
.yinyang::before,
.yinyang::after {
box-sizing: border-box;
position: absolute;
top: 50px;
width: 100px;
height: 100px;
border-radius: 50%;
content: '';
}
.yinyang::before {
left: 0;
border: 40px solid #000;
background: #fff;
}
.yinyang::after {
right: 0;
border: 40px solid #fff;
background: #000;
}
/* css3 动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="yinyang"></div>
</body>
</html>
效果图
我们来审查下元素,看下是否有什么不一样的地方。
你会发现了 div 元素里面多了::before 和 ::after,而且有对应的样式。
回到正题
什么是伪元素?
伪元素的语法跟伪类相似,不过表现得是像你往标记文本中加入全新的HTML元素一样,产生的效果是把不存在的元素硬选出来。
简单来说,伪元素,就不是真正的元素,真正的元素,就比如是上面例子用到的 div 元素。
伪元素有哪些?
::before:表示在元素内容之前插入一个虚拟的元素「常用」::after:表示在元素内容之后插入一个虚拟的元素「常用」::first-letter:选中某块级元素第一行的第一个字母,并且文字所处的行之前没有其他内容(如图片和内联的表格)::first-line:在某块级元素的第一行应用样式- ``::cue`:匹配所选元素中的WebVTT提示
::selection:应用于文档中被用户高亮的部分(比如使用鼠标或其他选择设备选中的部分)::slotted:用于选定那些被放在 HTML 模板中的元素
除了 ::after 和 ::before,其他的,我平时都用不到。对其他伪元素感兴趣的话,可以查下 mdn,实现 demo,看看。
一张图片,知道伪元素有那些。
::before 与 ::after
::before 和 ::after 伪元素是最常用、最经典的。 ::before 表示在元素内容之前插入一个虚拟的元素, ::after 则表示在元素内容之后插入,并且 ::before 和 ::after 中支持所有的 CSS 属性。
但需要注意的是这两个伪元素所在的 CSS 规则必须指定 content 属性才会生效,也就是你没有设置 content 的话,就没有效果。
content 属性取值
- string
- attr()
- url()/uri()
- 计数器
string
<p>追梦玩家</p>
<style>
p::before {
content: '「';
color: blueviolet;
}
p::after {
content: '」';
color: blueviolet;
}
</style>
效果图
attr()
<a href="https://juejin.cn/user/2911162520331037">「追梦玩家」</a>
<style>
a::after {
content: ' → ' attr(href); /* 在 href 前显示一个箭头 */
}
</style>
效果图
url()/uri()
<p>「追梦玩家」</p>
<style>
p::after {
content: url("https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/0f4dc5bd1dce1965c8c9cb947b4f5018~300x300.image");
}
</style>
效果图
计数器
<style>
body {
counter-reset: id;
}
.items {
width: 300px;
margin: 60px 0;
}
.items > li {
margin: 10px;
padding: 5px 10px;
background-color: yellowgreen;
}
.items > li::before {
counter-increment: id;
content: '第'counter(id) '条:';
}
</style>
<ul class="items">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
效果图
伪元素的常见使用场景有?
清除浮动
相信大家,都用过吧,看看这个代码,熟悉不,这里就不多说了。
.clearfix::after {
content: '';
display: block;
clear: both;
}
使用伪元素扩大点击区域/给你的点击区域加个触控热区
背景: 给图标(按钮、标签)做事件点击时,常常会因为元素面积太小导致用户很难点中,影响用户体验,产品大佬就会让我们做大点击区域,一般给元素加个 padding 就可以了,但这时 UI 就会偏差。
要实现产品大佬的想要的效果,我们可以怎么做呢?
给需要增加热区的元素加上add_touch类,即可在原来的基础上,增加1.5倍触控热区。就可以解决那个问题了。
.add_touch {
position: relative;
}
.add_touch::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
transform: scale(1.5);
}
做个气泡
<span class="welcome">Hello</span>
<style>
.welcome {
position: relative;
display: inline-block;
margin-bottom: 26px;
padding: 4px 16px;
color: #fff;
background-color: #E6686A;
line-height: 22px;
}
.welcome::after{
position: absolute;
top: 100%;
left: 4px;
width: 0;
height: 0;
border: 10px solid transparent;
border-top-width: 0;
border-left-color: #E6686A;
content: '';
}
</style>
效果图
参考
写到最后
伪元素的语法跟伪类相似,不过表现得是像你往标记文本中加入全新的HTML元素一样,产生的效果是把不存在的元素硬选出来。
文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你或者喜欢,欢迎点赞和关注。