什么是伪类什么又是伪元素
伪类选择器:和一般的DOM中的元素样式不一样,它并不改变任何DOM内容。只是插入了一些修饰类的元素,这些元素对于用户来说是可见的,但是对于DOM来说不可见。伪类的效果可以通过添加一个实际的类来达到。
伪元素选择器:伪元素的效果是需要通过添加一个实际的元素才能达到的。
简单的来说伪类只是添加了样式,而伪元素则是添加了实际的元素
伪类
伪类存在的意义是为了通过选择器找到那些不存在与DOM树中的信息以及不能被常规CSS选择器获取到的信息。
伪类由一个冒号:开头,冒号后面是伪类的名称和包含在圆括号中的可选参数。
任何常规选择器可以再任何位置使用伪类。伪类语法不区别大小写。一些伪类的作用会互斥,另外一些伪类可以同时被同一个元素使用。并且,为了满足用户在操作DOM时产生的DOM结构改变,伪类也可以是动态的。
我们可以用伪类实现这样的功能:
获取不存在与DOM树中的信息。比如a标签的:link、visited等,这些信息不存在与DOM树结构中,只能通过CSS选择器来获取;
获取不能被常规CSS选择器获取的信息。比如伪类:target,它的作用是匹配文档(页面)的URI中某个标志符的目标元素,再比如:hover,可以获取到鼠标悬浮之后的样式。
伪元素
伪元素在DOM树中创建了一些抽象元素,这些抽象元素是不存在于文档语言里的(可以理解为html源码)。比如:documen接口不提供访问元素内容的第一个字或者第一行的机制,而伪元素可以使开发者可以提取到这些信息。并且,一些伪元素可以使开发者获取到不存在于源文档中的内容(比如常见的::before,::after)。
伪元素的由两个冒号::开头,然后是伪元素的名称。
使用两个冒号::是为了区别伪类和伪元素(CSS2中并没有区别)。当然,考虑到兼容性CSS2中已存的伪元素仍然可以使用一个冒号:的语法,但是CSS3中新增的伪元素必须使用两个冒号::。
伪元素创建了一个虚拟容器,这个容器不包含任何DOM元素,但是可以包含内容。另外,开发者还可以为伪元素定制样式。已::first-line为例,它获取了指定元素的第一行内容并且将第一行的内容加入到虚拟容器中。如果通过JavaScript来实现这个逻辑,那么要考虑的因素就太多了,比如制定元素的宽度、字体大小,甚至浮动元素的图文混排等等。一个选择器只能使用一个伪元素,并且伪元素必须处于选择器语句的最后。
::before 和:before 有何不同
伪元素由双冒号和伪元素名称组成。双冒号是在当前规范中引入的,用于区分伪类和伪元素。不过浏览器需要同时支持旧的已经存在的伪元素写法,比如:first-line、:first-letter、:before、:after等,而新的在CSS3中引入的伪元素则不允许再支持旧的单冒号的写法。
对于CSS2之前已有的伪元素,比如:before,单冒号和双冒号的写法::before作用是一样的。所以,如果你的网站只需要兼容webkit、firefox、opera等浏览器,建议对于伪元素采用双冒号的写法,如果不得不兼容IE浏览器,还是用CSS2的单冒号写法比较安全。
使用伪元素来制作一个菜单按钮
先来看一下演示效果
上一下代码:
<!DOCTYPE html>
<html>
<head>
<title>伪元素绘制menu动画</title>
</head>
<style type="text/css">
.menu{
width: 48px;
height: 48px;
display: inline-block;
box-sizing: border-box;
position: relative;
background-color: #D9D7D6;
}
.center{
display: inline-block;
width: 18px;
height: 2px;
background-color: black;
line-height: 4px;
position:absolute;
top: 50%;
left: 50%;
margin-top: -1px;
margin-left: -9px;
transition: transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
-webkit-transition: transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
-moz-transition:transform transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
border-radius: 3px;
cursor: pointer;
}
.center::before{
content:"";
display: inline-block;
width: 18px;
height: 2px;
background-color: black;
line-height: 4px;
position: absolute;
left: 0;
top: -5px;
transition: transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
-webkit-transition: transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
-moz-transition:transform transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
border-radius: 3px;
box-sizing: border-box;
}
.center::after{
content:"";
display: inline-block;
width: 18px;
height: 2px;
background-color: black;
position: absolute;
left: 0;
bottom: -5px;
transition: transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
-webkit-transition: transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
-moz-transition:transform transform .3s ease, left .3s ease, top .3s ease,bottom .3s ease,width .3s ease;
border-radius: 3px;
box-sizing: border-box;
}
.back{
transform:rotate(180deg);
}
.back::after{
-webkit-transform: rotate(-45deg);
width: 13px;
left: 8px;
bottom: -4px;
}
.back::before{
-webkit-transform: rotate(45deg);
width: 13px;
left: 8px;
top: -4px;
}
</style>
<body>
<a href="javascript:void(0)"class="menu">
<span class="center"></span>
</a>
<script src="http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
'use strict'
let menu = $(".center");
$(".menu").on("click",(e)=>{
if(menu.hasClass("back")){
menu.removeClass("back");
}else{
menu.addClass("back");
}
e.stopPropagation();
e.preventDefault();
})
</script>
</body>
</html>
大概思路就是用一个span标签构成菜单按钮三个横杆的中间一个,然后通过伪元素来为这个span标签增加上下两个剩余的横杆,并且使用绝对定位来布局。
至于变成箭头就是在写一个箭头样式的类通过js动态加到原来的按钮上了,箭头样式同样使用了伪元素,只是在之前的基础上改了角度和位置以及长度就好了。