伪元素~伪类~傻傻分不清

背景

一直以来对伪元素和伪类概念很模糊,貌似就知道a标签常用的那4个状态,但是也不知道是叫伪元素还是叫伪类,项目中有个需求关系到了相关知识,学习整理

其实会越来越觉得像是CSS很多属性,光看文档的方式学很容易光知晓这个东西有某种作用,但是很难能想到通过组合或者在什么场景下用会做出很牛B的样式效果,通常都是设计出了某种没做过的效果,然后一头雾水的情况下去思考要怎么实现,接连搜索一些没有用过但是看过的属性,通过一定的思路组合组装最终实现,就会暗自觉得,哇,这些属性真牛B

需求是酱紫:

开发前的小思考

内容通过长得像进度条一样的点线联起来,每个点做为一段内容的标志,点之间连线,当存在一个点的时候不存在连线,最重要的是这个线的长度是随着内容的多少自适应的,所以不能做成固定长度的一条线

对于我来说棘手的地方有几点,一是线的高度,二是点线与内容一致,即一条内容一个点,多点才连线,先蹦出来疑点是点线和内容是分开写还是属于一个父元素下,分开确实能拿到点的数量,但是线的高度怎么弄,用js获取是恶心的事情,再加上点线的定位等等,认为不可行,这是个不能开心敲代码的死路

另种思路是每个点和每条内容是一个整体,点可以做同样的定位在左上,线的高度是跟着内容的多少占高来定的,上面有说分开的话不方便取高度,能用CSS设置的就不要用JS取,我的想法是让其能够在整体内以整体高度为基点设置百分比做为线的高度,很直观的分裂成点线内容一个区块,最后一个点是属于特殊判断,如果是最后一个点(涵盖了只存在一条内容的情况)就没有线

整体思路定了,实际操作

点和内容没问题,基于点线这种设计样式自然会想起伪元素,但是迟疑靠伪元素来做这条线能不能成功以整体高度为基点设置百分比,测试如下

测试开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<template>
<ul>
<li v-for="(item,index) in list">
<div :class="['circle',index==list.length-1?'':'circle-line']"></div>
<div class="content">{{item}}</div>
</li>
</ul>
</template>

<script>
export default{
data(){
return{
list: ['喂?是小仙女吗','我是小公举我是小公举我是小公举我是小公举我是小公举我是小公举','测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试']
}
}
}
</script>

<style scoped>
li{
/*从始至终只有区块最外层有定位,内部特别的点圆不能有定位,这样伪元素线就可以都是以li高度为基点设置百分比*/
position: relative;
width: 90%;
margin: 0 auto;
display: block;
/*设置两个区块的间距要通过padding,这样线的100%高度才是可视高度,点线能连上,不然用margin设置线就会短于两点距离*/
padding: 10px 0;

}
.content{
display: inline-block;
background-color: #f9f9f9;
padding: 10px;
word-wrap: break-word;
word-break: normal;
width: 88%;
/*这个蛮重要的,设置成顶部对齐,大大方便了点的定位*/
vertical-align: top;
}
.circle{
display: inline-block;
width: 5px;
height: 5px;
border-radius: 50%;
background-color: pink;
}
.circle-line:after{
content: '';
width: 1px;
height: 100%;
background-color: pink;
position: absolute;
/*这个定位依靠园的宽度,我设置的园正好是单数,直接定位2px就居中了,双数的话需要再设置transform:translate(-50%,0)*/
left: 2px;
top: 23px;
}
</style>

测试可行,效果图:

有几个点需要注意如代码注释,最最最重要之一是为了让伪元素设置的高百分比是以区块的高度为基点,一定不要设置点做定位,一旦点有定位,那么线设置百分比就会以点为基准,设置点的位置用vertical-align属性来定位,如果距离还和设计有出入,可以加一些margin的负值来细微的调,最最最重要之二是区块间距不能用margin,高度不包含margin值,所以基点高度会和两点的高度有误差,因此要用padding来做间距,这样的行为会影响到线的定位,注意线的定位调整

最终在项目中的效果:

最后附上伪元素伪类的链接

提炼

伪元素

:first-line —— 设置文本首行样式(只应用于块元素)
可设置的属性: font,color,background,word-spacing,letter-spacing,text-decoration,vertical-align,text-transform,line-height,clear

:first-letter —— 设置文本首字母样式(只应用于块元素)
可设置的属性: font,color,background,margin,padding,border,text-decoration,vertical-align(当float为none时),text-transform,line-height,float,clear

:before —— 元素内容之后插入新内容

:after —— 元素内容之前插入新内容

伪类

CSS1锚伪类

a:link —— 未访问
a:visited —— 已访问
a:hover —— 鼠标滑过(必须在link和visited之后才有效)
a:active —— 点击(必须在hover之后设置才生效)

CSS2

:focus —— 获取焦点的元素
:first-child —— 某元素的第一个子元素(p:first-child代表第一个p元素)
:lang —— 对指定lang属性的元素添加样式
例:

1
2
3
4
5
6
html
<q lang="no">A quote in a paragraph</q>
css
q:lang(no){
quotes: "~" "~"
}

so !!!! a标签那四个状态叫伪类不叫伪元素!!!!!!!