伪类与伪元素的区别

1,576 阅读9分钟

    我预见了所有悲伤,但我依然愿意前往
                
                    --电影《降临》

定义:

伪类

  • 伪类用于向某些选择器添加特殊的效果。

    伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,而不是元素的id,class、属性等静态的标志。由于状态是动态变化的,所以一个元素达到一个特定状态时,它可能得到一个伪类的样式;当状态改变时它又会失去这个样式。

由此可以看出,它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类。其实是弥补了CSS选择器的不足,用来更方便地获取元素。

伪元素

  • 伪元素用于将特殊的效果添加到某些选择器。

    伪元素,是对元素中的特定内容进行操作,它所操作的层次比伪类更深了一层,也因此他的动态性比伪类要低的多。实际上,设计伪元素的目的就是去选取诸如元素内容的第一个字母、第一行,选取某些内容前面或后面这种普通的选择器无法完成的工作。

它控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素。本质上是创建了一个虚拟容器(元素),我们可以在其中添加内容或样式。

伪类分类

伪类包含两种:状态伪类和结构性伪类。

  • 状态伪类是基于元素当前状态进行选择的。在与用户的交互过程中元素的状态是动态变化的,因此该元素会根据其状态呈现不同的样式。当元素处于某状态时会呈现该样式,而进入另一状态后,该样式也会失去。 常见的状态伪类主要包括:
状态伪类 作用
:link 应用于未被访问过的链接
:hover 应用于鼠标悬停到的元素
:active 应用于被激活的元素
:visited 应用于被访问过的链接,与:link互斥
:focus 应用于拥有键盘输入焦点的元素
  • 结构性伪类是css3新增选择器,利用dom树进行元素过滤,通过文档结构的互相关系来匹配元素,能够减少class和id属性的定义,使文档结构更简洁。常见的包括:
结构化伪类 作用
:first-child 选择某个元素的第一个子元素
:last-child 选择某个元素的最后一个子元素
:nth-child() 选择某个元素的一个或多个特定的子元素
:nth-last-child() 选择某个元素的一个或多个特定的子元素,从这个元素的最后一个子元素开始算
:nth-of-type() 选择指定的元素
:nth-last-of-type() 选择指定的元素,从元素的最后一个开始计算
:first-of-type 选择一个上级元素下的第一个同类子元素
:last-of-type 选择一个上级元素的最后一个同类子元素
:only-child 选择的元素是它的父元素的唯一一个子元素
:only-of-type 选择一个元素是它的上级元素的唯一一个相同类型的子元素
:empty 选择的元素里面没有任何内容
:target 选择当前活动的目标元素

示例如下:

a:link {color: #FF0000}		/* 未访问的链接 */
a:visited {color: #00FF00}	/* 已访问的链接 */
a:hover {color: #FF00FF}	/* 鼠标移动到链接上 */
a:active {color: #0000FF}	/* 选定的链接 */

伪元素

伪元素种类

伪元素 作用
::first-letter 向文本的第一个字母添加特殊样式
::first-line 向文本的首行添加特殊样式
::before 在元素之前添加内容
::after 在元素之后添加内容
::selection 匹配突出显示的文本(用鼠标选择文本时的文本)

示例如下:

<html>  
    <head>  
        <title>CSS学习之路</title>  
        <meta http-equiv="Content-Type" content="text/html;" />
        <meta charset="UTF-8">
        <meta name="keywords" content="css 笔记" />  
        <meta name="description" content="shaoyuli的CSS3积累笔记" /> 
        <style type="text/css">
            .demo {
                border: 1px solid #ccc;
                width: 300px;
                margin: 50px auto;
                padding: 10px;
            }
            /* css3之前写一个冒号即可生效,但css3时需要与伪类进行区别所以一般写两个冒号
            因此写一个冒号和两个冒号都可以生效。工作中推荐写两个冒号 */
            .demo::first-letter {
                font-size: 40px;
                font-weight: bold;
                /* 首字下沉 */
                float: left
            }
            .demo::first-line {
                color: #f00;
            }
            .demo1 {
                width: 300px;
                border: 1px solid #ccc;
                margin: 10px auto;
                padding: 10px;
                text-align: center;
            }
            .demo1::before {
                content: url(./download.jpeg);
                display: block;
            }
            .demo1::after {
                content: url(./download.jpeg);
                display: block;
            }
        </style>
    </head> 
    <body> 
        <div class="demo">
            最近,在我遇到这样一个人后,我的想法改变了。我和两个已成年的女儿一起去了一家咖啡厅。但这家咖啡厅挤满了吵闹的人群,所以我们不得不爬上陡峭的楼梯才找到了空桌。在享用过咖啡和点心之后,我们走在陡峭的楼梯上准备下楼,在那样狭窄的空间里只能供一个人上下楼,几乎没有任何空间可以让另一个人爬上去或下来。
        </div>
        <div class="demo1">
            学习CSS3
        </div>
    </body> 
</html> 

效果展示:

伪元素的优缺点

  • 优点

    1. 不占用 DOM 节点,减少 DOM 节点数。

    2. 让 CSS 帮助解决了一部分 JavaScript 问题,简化了开发。

    3. 不仅块级元素可以设置伪元素,大部分行级元素也可以避免增加毫无意义的页面元素。

  • 缺点

    1. 不利于调试

    2. 伪元素不真正在文档内容中体现,只在视觉效果上体现,所以不能给伪元素添加具有实际意义的内容,这部分内容不会搜索引擎抓取。

伪元素使用时的注意事项

  • 1、伪元素如果没有设置content属性(可为空值),那么伪元素是无用的(可以将伪元素的内容设置为空),content插入的内容默认是 inline 元素,可以通过display:block改变

  • 2、插入的内容在页面的源码里是不可见的,只能在css里面可见

  • 3、插入的伪元素默认情况是内联元素,因此,为了给插入元素赋予高度,外边距、填充等等,必须显式定义它是一个块级元素。

  • 4、典型的css继承规则适用于插入的伪元素,比如,插入的字体系列,然后伪元素会像其他元素一样继承这些字体系列,同样的,伪元素不会继承没有自然继承自父元素(如padding和margin)的样式。

伪元素中属性content说明

content 的值可以是空值、字符串、attr()、url()、uri()、counter()等,下面分别演示一下。

空值

可以用来清除浮动。代码如下:

.clearFix::after{
  clear: both;
  content: "";
  display: block;
  height: 0;
  overflow: hidden;
 }

包含 cleafFix 这个类的元素,其内部的浮动可以被清除。

string(字符串)

在电话号码前面添加一个电话的icon图标。代码如下:

HTML部分

<p class="phoneNumber">13900001390</p>

CSS部分

.phoneNumber::before{
   content:'\260E';
   font-size: 16px;        
}

效果展示:

小电话的图标是一个特殊字符,每个特殊字符都有特定代码,特定代码用在HTML中以& 开头,用在 CSS 中以 \ 开头,用在 JS 中以 \u 开头。 比如这个电话图标,在 HTML 中用 &#9742 表示,在 css 中以 \260E 表示,在 JavaScript 中,以 \u260E 表示。

attr() 以及 url()

attr():可以调用当前元素的某个属性。

url():可以引用媒体文件(比如图片)。

演示代码:

HTML部分:

<a href="https://www.google.com">GOOGLE!</a>

CSS 部分:

a::before{
  content: url("https://www.google.com/logos/doodles/2018/world-cup-2018-day-19-6211393811382272.3-law.gif");
  }
a::after{
  content: "("attr(href)")";
 } 
a{
  text-decoration: none;
 }

效果预览:

例子中,content 中的 url 是引用媒体文件,所以不用加引号。 attr 是调用元素 href 属性当做字符串显示出来,所以要加引号。至于括号里面,如果加引号,就会显示出来 href 的值,如果不加引号就打印字符串 (attr(href))。

counter 计数器

counter: 调用计数器,可以不使用列表元素实现序号功能。

counter要配合 counter-increment 和 counter-reset属性使用。counter-reset 给同级元素增加计数器,比如一个页面有多个H1元素,那就给body加计数器。一个H1元素里面有多个H2元素,那就给H1元素加计数器。 counter-increment 增加计数器数值。

代码演示:

HTML部分:

<body>
<h1>哺乳动物</h1>
<h2></h2>
<h2>猴子</h2>
<h2>猩猩</h2>

<h1>冷血动物</h1>
<h2></h2>
<h2></h2>
</body>

CSS部分:

body{
 counter-reset: section;        
 }
/* 带有:的字段 */
.field_colon:after {
  content: ":";
}
h1{
  counter-reset:subsection;
}
h1::before{
  counter-increment: section;
  content:counter(section)'、';
}
h2:before{
  counter-increment: subsection;
  content: counter(section)'.'counter(subsection)'、';
}

效果演示:

总结:content的值什么时候加引号,什么时候不加通过以上实例可以看出: 动态的(会变的值)不加引号,媒体不加引号; 固定的值、字符串需要加引号

伪类与伪元素的区别与联系

  • 伪类与伪元素都是用于向选择器加特殊效果
  • 伪类与伪元素的本质区别就是否抽象创造了新元素,有没有创建一个文档树之外的元素
  • 伪类只要不是互斥可以叠加使用
  • 伪元素在一个选择器中只能出现一次,并且只能出现在末尾
  • 伪类与伪元素优先级分别与类、标签优先级相同
  • 伪类选择符必须是一个冒号才行,伪元素选择器前面有两个冒号,当前用一个冒号也可以