深入挖掘CSS让前端飞程序员

伪类&伪元素 - CSS精通之路

2018-01-12  本文已影响89人  果汁凉茶丶

2018/03/30更新】我居然不知道CSS的这两个用法,今天看到,惭愧至极

  1. div > p
      选择div下一级的所有p元素。他与 div p的区别是,前者只选择下一级元素,后者则选择div下所有子元素中为p元素的标签。
  2. p + span
      选择紧随p元素的span元素,pspan是同级关系。

# 前言:

  你的代码中是否每个标签都定义了一个类?完成一个页面后是否觉得代码很乱很拥挤?看见github优秀代码清爽简洁,想过你真的精通 ‘CSS’ 吗?想要进阶?不妨捡起CSS最容易被新手忽视与遗漏的模块:伪类 & 伪元素

CSS伪类[Pseudo-classes],用于向某些选择器提供特殊效果。

# 语法

伪类的语法:selector:pseudo-class {property:value;}
配合css类使用: selector.class:pseudo-class {property:value;}

# 锚[anchor]伪类 - 链接

  链接有不同的状态,为了区分和提高用户体验,可以利用css伪类对链接不同状态显示不同的样式

a:link { color: #ff0000; }   /* 未访问的链接 */
a:focus { color: #00ff00; }   /* 获得焦点的链接 */
a:visited { color:  #0000ff; }   /* 已访问的链接 */
a:hover { color: #ff00ff; }   /* 鼠标划过链接 */
a:active { color: #ffcc00; }   /* 点击时的链接 */

需要特别注意的是:

  1. 在css定义中,a:hover是必须定义在a:linka:visited之后才能生效【如果有】;
  2. a:active必须定义在a:hover之后才能生效【如果有】;
  3. 伪类名称对大小写不敏感,大小写均生效。

# 伪类配合css类使用

  伪类不仅能跟在一个标签名后面,也能跟在样式类的后面。

<style type="text/css">
    a.linkme:visited { color: #ff0000; }
</style>
<a class="linkme" href="css-syntax.html">css 语法</a>

# [CSS2] :first-child伪类

  在理解这个伪类的时候,走了不少误区,为了方便大家理解和自己回顾时更迅速捡起来,如下举例说明
假设有如下html:

1. <div>
2.    <p>I am the first element</p>
3.     <ul>
4.         <li>I am the first li emelent</li>
5.         <li>some text <strong>here</strong> </li>
6.         <li>go on</li>
7.     </ul>
8.     <p><em>who</em> know what I am</p>
9. </div>

分析】上面的例子中,能够作为 first-child 的元素有 行2 的p元素,行4 的li元素, 行5 的 strong元素, 行8 的em元素;
如果给定以下规则:

p:first-child {
    color: red;
}
li:first-child {
    font-weight: bold;
}

则,行2 的p元素的文案颜色将改成红色,行4 的li元素文案将被加粗。
误区】认为p:first-child{ color:red; } 会将p元素的第一个子元素文案置红,其实不然。要明白,伪类都是对选择器自身进行加工。
要点】必须声明 <!DOCTYPE>, 才能使 :first-child 在 IE 中生效。
联想】学 :first-child 必定要想到 :nth-child(an+b) ;注意区分,:nth-child(1) 是用于对父元素的子元素索引进行查找,具体见后面 :nth-child(an+b) 模块
经典案例

1. 匹配 第一个 <p> 元素

该用例中,选择器匹配作为任何元素的第一个子元素的<p>元素

p:first-child {
    color: red;
}
2. 匹配所有 <p> 元素中的第一个 <i> 元素
p > i:first-child {
    color: blue;
}
3. 匹配所有作为第一个子元素的 <p> 元素中的所有 <i> 元素
p:first-child i {
    color: lightgreen;
}

注意第二个例子的特殊用法。

# [CSS2] :last-child伪类

1. 匹配父元素中最后一个子元素<p>
p:last-child {
    color: aqua;
}

提示p:last-child 等同于 p:nth-last-child(1)

# [CSS3] :nth-child(an+b) 伪类 - 难点

功能】选择每个指定元素匹配父元素中的第an+b个子元素,根据子元素索引选择,具有bool结果性质,如果匹配不上则样式表就不执行

p:nth-child(2) {
    color: azure;
}

分析】对于该点「菜鸟教程」的部分解读有误,正确意思是:<p>元素所在的父元素的第二个子元素,如果是<p>元素,则加上样式内容,如果不是<p>元素,则跳过。
经典案例

1. 匹配下标是奇数或偶数的子元素的关键词(第一个子元素的下标是 1)
p:nth-child(odd){
    background: aliceblue;
}
p:nth-child(even){
    background: antiquewhite;
}
2. 匹配下标是 3 的倍数的所有 p 元素
p:nth-child(3){
    background: aquamarine;
}

# [CSS3] :nth-of-type(an+b) 伪类 - 难点

功能】匹配指定元素所在父元素中相同类型的第n个同级兄弟元素,根据类型选择,同样具有bool结果性质

p:nth-of-type(2) {
    background: beige;
}

分析】W3C的解释还是很费解,"属于其父元素的第二个 p 元素的每个 p ";我理解是:在<p>元素所在的不为<p>的父元素中,查找第二个<p>元素并为它加上样式表,且只作用于p内的行内元素中
特殊案例】为什么我觉得W3C的解释不太合理,注意如下这种情况:

<div>
    <p>line-1</p>
    <p>line-2<span>line-2-1</span>
          <P>line-2-2</P>
          <P>line-2-3</P>
          <div>line-2-4</div>
    </p>
    <div>line-3
        <p>line-3-1</p>
        <p>line-3-2</p>
        <p>line-3-3</p>
    </div>
    <p>line-4</p>
</div>

// css code
p:nth-of-type(2) {
    color:blueviolet;
}

来看看效果;


p:nth-of-type(2)的执行结果

关于该例,仁者见仁,智者见智,只要能正确理解并应用,一切你开心就好。

# [CSS3] :nth-last-child(an+b) 伪类

功能】匹配指定元素的倒数第an+b个子元素
案例】设置倒数第一个子元素的样式,比如去除底部边框

p:nth-last-child(1) {
    border-bottom: none;
}

# [CSS3] :nth-last-of-type() 伪类

案例】指定每个p元素匹配同类型中的倒数第2个同级兄弟元素背景色:

p:nth-last-of-type(2) {
    background:#ff0000;
}

# [CSS3] :not(seletor) 伪类

功能】匹配所有不是指定标签的元素
案例】设置不是p标签的元素的背景颜色

:not(p) {
    background-color: cadetblue;
}

# [CSS3] :empty 伪类

功能】匹配所有没有子元素的指定元素
案例】设置所有没有子元素的<p>元素的背景颜色为bisque

p:empty {
    background-color: bisque;
}

# [CSS2] :lang 伪类

功能】匹配带有指定 lang 属性开始的元素
以下案例会给声明了 lang 属性且值为 no 的<q>元素内容前后增加~符号。

q:lang(no) {
    quotes: "~" "~";
}

// html
<p>前面的文字 <q lang="no"> 段落中引用的文字</q></p>

CSS伪元素[Pseudo-elements],用于向某些选择器提供特殊效果

# 语法

伪元素的语法:seletor:pseudo-element { property: value; }
配合CSS类使用: selector.class:pseudo-element { property:value; }

# [CSS1] :first-line 伪元素

功能】用于向文本的首行设置特殊样式
经典案例

p:first-line {
    color: #ff0000;
    font-variant: small-caps;  // 把文本设置成小型(文字比普通字体小)的大写字体,可选值:normal/small-caps/inherit
}

要点】:first-line只能用于块级元素如<p>,<span>和<font>就不能用
注释】以下属性能应用于 :first-linefont/ color/ background/ word-space/ letter-spacing/ text-decoration/ vertical-align/ text-transform/ line-height/ clear(用于清除浮动)

# [CSS1] :first-letter 伪元素

功能】用于向文本的首个字母添加特殊样式

p:first-letter {
    color: #00ff00;
    font-size: xx-large;   // 还有这个值?见下方【拓展】
}

要点】:first-letter也只能用于块级元素如<p>,<span>和<font>就不能用
注释】还有以下属性能应用与:first-letter: font/ color/ background/ margin/ padding/ border/ text-decoration/ vertical-align(仅float为none时)/ text-transform/ line-height/ float/ clear(用于清除浮动)
拓展font-size 的多种可能值

# [CSS2] :before 伪元素

功能:before 伪元素可以在元素的内容前面插入新内容
案例】在<p>标签前面插入文字。默认地,这个伪元素是行内元素,不过可以使用属性 display 改变这一点。

p:before {
    content: '今日新闻:'
    background-color: chocolate;
}

如果想在元素上增加块,设置content为空,并增加样式即可,例如制作loading效果时即可使用该方法。

# [CSS2] :after 伪元素

功能:after 伪元素可以在元素的内容之后插入新内容
案例】下面的例子在每个 <h1> 元素后面插入一幅图片,与:before 一致,这个伪元素也是行内元素

h1:after {
    content:url(logo.gif);
}

# 后语

  本文尽可能列出了平时用到的所有伪类和伪元素,当然还有一些小众伪类并未给予说明,遇不到,还难记,不如写个简单的类实现。另外,如果本文有写的不对的地方,欢迎大家指正交流。

上一篇下一篇

猜你喜欢

热点阅读