之前介绍了8种选择器,基本上可以应对大部分的开发需求,但是如果不会使用伪类和伪元素,就跟下面的图差不多,后面会摔的。伪元素和伪类虽然不是特别常用,但是,很好用,可以帮你省掉很多无用功,效果还好。下面直接进入正题,尽量用最小的篇幅让人明白如何使用它们。
1.伪元素和伪类的区别
- 伪元素和伪类都是为了给一些特殊需求加样式,定义上基本一致。
- 伪类像类选择器一样给已存在某个元素添加额外的样式;伪元素则是给自己虚拟的元素添加样式。
- 已存在元素是指DOM中存在的,伪元素则是虚拟的一种,样式也是给这个虚拟的元素使用的。比如虚拟一个div
- 声明不同,伪类和选择器之间用一个冒号隔开,伪元素则是两个冒号隔.
2.常用的伪类
常用的伪类有两类UI伪类和结构伪类。这里只介绍5个,应该足够用了。
2.1 hover和active
这两个属于UI伪类(link/visited/active/hover)四个中的其中两个。
- hover指当鼠标移动到元素上时触发某种样式;activate指鼠标按下时的某种样式。
- hover使用场景:一些可点击的列表,表格行,卡片等,鼠标放上去之后背景颜色会发生变化,就可以使用hover。
- active使用场景:按钮按下,图片按下以及一些可点击元素或者组件等的按下操作样式改变。
下面是一个非常简单的按钮案例(在线MP4转GIF不知道这个图能存在多久,看不见的底下评论提醒我):
第一个按钮当鼠标放上去是改变边框和字体颜色,第二则是在鼠标按下的时候改变背景和颜色。具体代码如下
.btn{
height: 34px;
padding: 6px 12px;
border-radius: 4px;
font-size: 15px;
color: rgba(0,0,0,.65);
font-weight: 400;
outline: none;
border: 1px solid #cbcbcb;
}
.btn:hover{
border-color: #3385ff;
color: #3385ff;
}
.btn2{
height: 34px;
padding: 6px 12px;
border-radius: 4px;
font-size: 15px;
color: #fff;
background: #3385ff;
border-width: 0;
font-weight: 400;
outline: none;
}
.btn2:active{
border: 1px solid #3385ff;
color: #3385ff;
background: #fff;
}
HTML:
<div>
<button class="btn">按钮</button>
<button class="btn2">按钮</button>
</div>
使用非常简单,就是在类选择器后面使用一个冒号后面根据需求是鼠标放上去时触发还是按下时触发决定使用哪一个伪类。如上面第一个btn是( .btn:hover ) 第二个则是( .btn2:active )。
2.2 first-child last-child nth-child(n/odd/even)
这三个属于结构伪类,常用来给表格或者列表添加样式。
- 假设父元素是一个div,使用样式class=‘box’;
- 那么当定义.box:first-child或者.box:last-child时分别是指给div的第一个或者最后一个子元素添加样式。
- nth-child这个就比较牛掰了,参数是一个数值代表给第几个元素添加样式,如果是odd标示给元素为奇数的添加样式,even则是给是偶数的元素添加样式。
看个例子,首行添加灰色背景,其他奇数行橙色背景的一个表格
css(简单不):
td,th {
padding: 12px;
}
table tr:nth-child(odd){
background: #ffab00;
}
table tr:first-child{
background: #ccc;
}
html(也很简单都是重复的):
<table border="1" frame="box" rules="all" width="50%">
<tr>
<th>标题1</th>
<th>标题2</th>
<th>标题3</th>
<th>标题4</th>
</tr>
<tr>
<td>content-1</td>
<td>content-1</td>
<td>content-1</td>
<td>content-1</td>
</tr>
<tr>
<td>content-2</td>
<td>content-2</td>
<td>content-2</td>
<td>content-2</td>
</tr>
<tr>
<td>content-3</td>
<td>content-3</td>
<td>content-3</td>
<td>content-3</td>
</tr>
<tr>
<td>content-4</td>
<td>content-4</td>
<td>content-4</td>
<td>content-4</td>
</tr>
<tr>
<td>content-5</td>
<td>content-5</td>
<td>content-5</td>
<td>content-5</td>
</tr>
</table>
3.常用伪元素
before 和 after是经常经常重用的伪元素。我们直接看两个最简单的例子。再一句话的前面(before)和后面(after)分别添加一个圆形和一个矩形。
<p class="eazy">我就是那句话!</p>
css:
.eazy{
font-size: 18px;
}
.eazy::before{
content:'';
display: inline-block;
width: 10px;
height:10px;
background: #ffab00;
border-radius:50%;
}
.eazy::after{
content:'';
display: inline-block;
width: 10px;
height:10px;
background: #3385ff;
}
- 双冒号后面跟跟关键字before或者after,在后面的内容即是要给这个伪元素添加的样式。
- 其中content属性一定要设置,可以设置为空,否则不会显示;
- 其次,设置了依然没有显示就要设置表明这个伪元素块级元素。
3.1 在来看两个例子,项目开发中经常要画一些气泡,比如
这是两种气泡,带有背景色的和带有边框的,实现上稍微有些区别,但是他们的小突起就是用伪元素画的。
HTML:
<div class="bubble-box">
<div class="bubble-left">
Hello, can I have a star?
</div>
<div class="bubble-top">
Hello, can I have a star?
</div>
<div class="bubble-bottom">
Hello, can I have a star?
</div>
<div class="bubble-right">
Hello, can I have a star?
</div>
<div class="bubble-noColor">
Hello, can I have a star?
</div>
</div>
css有点长,但是仔细观察90%的代码都是重复的并不难。主要变动是使用定位position属性控制小突起的位置,以及border-color来控制凸起箭头的朝向。三角形的画法原理可以看这里!
.bubble-box{
display: flex;
padding: 10px;
}
.bubble-top{
width: 120px;
padding: 10px;
background: #3385ff;
border-radius: 6px;
position: relative;
color:#fff;
}
.bubble-top::before{
content: '';
width: 0;
height: 0;
position: absolute;
border:6px solid #3385ff;
border-color: transparent transparent #3385ff transparent;
left: 46%;
top: -12px;
}
.bubble-left{
width: 120px;
padding: 10px;
background: #3385ff;
border-radius: 6px;
position: relative;
color:#fff;
}
.bubble-left::before{
content: '';
width: 0;
height: 0;
position: absolute;
border:6px solid #3385ff;
border-color: transparent #3385ff transparent transparent;
left: -12px;
top: 24px;
}
.bubble-bottom{
width: 120px;
padding: 10px;
background: #3385ff;
border-radius: 6px;
position: relative;
color:#fff;
}
.bubble-bottom::before{
content: '';
width: 0;
height: 0;
position: absolute;
border:6px solid #3385ff;
border-color: #3385ff transparent transparent transparent;
left: 46%;
bottom: -12px;
}
.bubble-right{
width: 120px;
padding: 10px;
background: #3385ff;
border-radius: 6px;
position: relative;
color:#fff;
}
.bubble-right::before{
content: '';
width: 0;
height: 0;
position: absolute;
border:6px solid #3385ff;
border-color: transparent transparent transparent #3385ff;
right: -12px;
top: 24px;
}
.bubble-noColor{
width: 120px;
padding: 10px;
border:1px solid #ccc;
border-radius: 6px;
position: relative;
color:#0f0f0f;
}
.bubble-noColor::before{
content: '';
width: 9px;
height: 9px;
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
background: white;
transform: rotate(45deg);
position: absolute;
left: 46%;
top: -6px;
}
3.2 利用伪元素画一个时间轴
如图
解析
- 每一行都只设置左边框,这样就这回出现一条竖线。
- 然后每一行前面加一个圆点,就会呈现时间轴的样式,加圆点当然是用伪元素了。
先看HTML,很简单:
<div>
<ul class="list">
<li>2018-11-15 吃了好吃的</li>
<li>2018-11-16 不开心</li>
<li>2018-11-18 蓝瘦香菇</li>
<li>2018-11-23 滚蛋</li>
<li>2018-12-10 嗯哼随心随遇把</li>
</ul>
</div>
css 先给li标签设置左边框border-left,
.list{
padding: 10px;
border: 1px solid #fff;
}
.list li{
list-style: none;
padding: 10px;
border-left: 1px solid #ccc;
}
第二步,添加伪元素
.list li::before{
content: '';
display: inline-block;
width: 6px;
position: absolute;
height: 6px;
left: 16px;
margin-top: 7px;
border: 1px solid #ffab00;
border-radius: 50%;
background: #3385ff;
}
3.3 伪元素怎么添加内容的
伪元素虽然是不存在于DOM树种的元素,但是也是可以添加内容的,就是上面提到的content属性。content属性可以是URL、字符串甚至是图片,视频等。
我们把第三节刚开始的那个前后圆形和矩形的content设置为’1’和’2’.就变成这样了。
所以content就是这只伪元素中内容的入口,这也解释了为什么不设置这个属性就不显示的原因,哪怕设置为空,也相当于我定义了这个伪元素。
最后再看一个例子:
如果人工去标示会非常的消耗成本,实际上伪元素就可以轻松解决这个问题。content + counters实现目录结构。
HTML:
<div class="list2">
<ul>
<li>吃了好吃的
<ul>
<li>content</li>
<li>content</li>
<li>content</li>
</ul>
</li>
<li>不开心</li>
<li>蓝瘦香菇
<ul>
<li>content</li>
<li>content</li>
<li>content</li>
</ul>
</li>
<li>滚蛋</li>
<li>嗯哼随心随遇把</li>
</ul>
</div>
css counter-reset定义一个计数器后面跟一个名字,这个属性在哪个元素上设置则标示遇到这个元素我就重新开始计数,如上面的HTML,我们把这个属性设置到ul上,则遇到ul就重新计数(添加一个新的计数器,原计数器不受影响)。
.list2{
padding: 10px;
border: 1px solid #ccc;
}
.list2 li{
list-style: none;
}
.list2 ul{
counter-reset: xuhao;
}
.list2 li::before{
counter-increment: xuhao;
content: counters(xuhao, ".") " ";
}
在li元素的伪元素上接受这个计数值通过counters,第一参数接收计数器,第二参数指明新的计数值以什么字符链接在上一级计数值得后面