04_CSS - 常见选择器

130 阅读8分钟

CSS - 常见选择器

开发中经常需要找到特定的网页元素进行设置样式

所以我们需要按照一定的规则选出符合条件的元素,为之添加CSS样式

而这些规则就被称之为CSS选择器

通用选择器

通用选择器(universal selector) --- 所有的元素都会被选中

一般用来给所有元素作一些通用性的设置 --- 例如清除body默认的8px外边距 通用选择器(universal selector) --- 所有的元素都会被选中

一般用来给所有元素作一些通用性的设置 --- 例如清除body默认的8px外边距

元素选择器

Tips: 对于类选择器和id选择器

  1. 一个HTML文档里面的id值是唯一的,不能重复 --- 重复不报错 是因为浏览器做了容错处理,不推荐

  2. 不要用标签名作为id值或者类名 --- 不会报错,不推荐,可读性差

  3. id选择器名或class选择器类型如果由多个单词组成,单词之间可以用

     中划线-
    

     下划线_
    

    连接,也可以使用

     驼峰标识(包括大驼峰和小驼峰)
    
    • 中划线又叫连字符(hyphen)
    • 推荐使用中划线进行多个单词之间的连接符

属性选择器

后代选择器

后代元素 = 直接后代元素 + 间接后代元素

一般后代表示的就是直接后代元素 + 间接后代元素

而子代表示的就是直接子代元素

所有后代选择器

兄弟选择器

注意: 在默认情况下,兄弟选择器选中的都是后继兄弟元素

如果需要选中前置兄弟元素,可以结合:not伪元素来进行选择

选择器组

交集选择器:

交集选择器 --- 需要同时符合两个选择器条件 (两个选择器紧密连接)

Snipaste_2022-10-18_15-59-28.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    div.box {
      color: red;
      font-size: 30px;
    }
  </style>
</head>
<body>
  
  <div class="box">我是div元素</div>
  <p class="box">我是p元素</p>

</body>
</html>

并集选择器:

并集选择器 --- 符合一个选择器条件即可 (两个选择器以,号分割)

Snipaste_2022-10-18_16-02-21.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body, p, h1, h2 {
      color: red;
      font-size: 40px;
    }
  </style>
</head>
<body>

  <p>我是p元素</p>
  <h1>我是h1元素</h1>

</body>
</html>

伪类选择器

Pseudo-classes: 翻译过来是伪类

伪类是选择器的一种,它用于选择处于特定状态的元素 --- 如被点击,被悬浮等

常见伪类分类举例
动态伪类:link、:visited、:hover、:active、:focus
目标伪类:target
语言伪类:lang( )
元素状态伪类:enabled、:disabled、:checked
结构伪类:nth-child( )、:nth-last-child( )、:nth-of-type( )、:nth-last-of-type( ) :first-child、:last-child、:first-of-type、:last-of-type :root、:only-child、:only-of-type、:empty
否定伪类:not()
其它:placeholder

动态伪类

  • a:link 未访问的链接
  • a:visited 已访问的链接
  • a:hover 鼠标挪动到链接上
  • a:active 激活的链接(鼠标在链接上长按住未松开)
  • :focus当前拥有输入焦点的元素
  1. 除了a元素,:hover, :active也能用在其他元素上

  2. 直接给a元素设置样式,相当于给a元素的所有动态伪类都设置了

    --- 相当于a:link、a:visited、a:hover、a:active、a:focus 都设置了相同的样式

  3. 因为链接a元素可以被键盘的Tab键选中聚焦,所以:focus也适用于a元素

注意:

  1. :hover必须放在:link:visited后面才能完全生效
  2. :active必须放在:hover后面才能完全生效
  3. :focus必须放在:hover后, :active之前才能完全生效

所以动态伪类编写顺序推荐为: :link、:visited、:focus、:hover、:active

目标伪类 --- :target

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    /*
      1. 元素必须拥有id属性
      2. url必须存在fragment

      :target 用于匹配那个元素的id属性的值 和 url中的fragment字段的值一致

      例如: 当URL为http://www.example.com/index.html#bar时
       <div id="bar">bar</div> 的颜色会被设置为红色
    */
    :target {
      color: red;
    }
  </style>
</head>
<body>
  <div id="foo">foo</div>
  <div id="bar">bar</div>
  <div id="baz">baz</div>
</body>
</html>

语言伪类 --- :lang()

/*
	选中所有 有lang属性 且其值为zh的元素

	1. lang属性是一个全局属性 其一般是在html元素上进行设置 但是其本质上可以在任何元素上都进行设置	
		 如: `<div lang="zh-CN">foo</div>`
	2. :lang这个伪类的使用方式是通过函数的形式进行使用 --- css函数的参数不要使用引号进行包裹
*/
:lang(zh) {
  color: red;
}

结构伪类

选择器作用
:nth-child(n)css函数调用 n的其值从0开始依次递增 选取当前元素的父元素的第n个子元素
:nth-last-child(n)css函数调用 n的其值从0开始依次递增 从后往前选取当前元素的父元素的第n个子元素
:nth-of-type(n)css函数调用 n的其值从0开始依次递增 选取当前元素的父元素的第n个同类型子元素
:nth-last-of-type(n)css函数调用 n的其值从0开始依次递增 从后往前选取当前元素的父元素的第n个同类型子元素
:first-child等同于:nth-child(1)
:last-child等同于:nth-last-child(1)
:first-of-type等同于:nth-of-type(1)
:last-of-type等同于:nth-last-of-type(1)
:only-child该元素是父元素中唯一的子元素 即匹配没有任何兄弟元素的元素
:only-of-type该元素是父元素中唯一的同类型子元素 即该子元素在父元素中没有其它相同类型的兄弟元素
:root根元素,就是HTML元素
:empty完全空白的元素

:nth-child vs :nth-of-type

<!-- :nth-child(n) -->

<style>
  /* ul下的第三个子元素,且该子元素的类型是li的时候,设置其颜色为红色 */
  /* 
    注意:在JS中 索引是从0开始计算的,但是在css中,索引是从1开始计算的
    也就是说nth-child(3) 选择的是第三个对应的元素
  */
  ul li:nth-child(3) {
    color: red;
  }
</style>

<ul>
  <li>content1</li>
  <li>content2</li>
  <!-- content3的颜色被设置成了红色 -->
  <li>content3</li>
  <li>content4</li>
  <li>content5</li>
</ul>

<!-- :nth-last-child(n) -->
<style>
  /* ul下的倒数第二个子元素,且该子元素的类型是li的时候,设置其颜色为红色 */
  ul li:nth-last-child(2) {
    color: red;
  }
</style>

<ul>
  <li>content1</li>
  <li>content2</li>
  <li>content3</li>
  <!-- content4的颜色被设置成了红色 -->
  <li>content4</li>
  <li>content5</li>
</ul>

<!-- :nth-of-type(n) -->
<style>
  /* 
  	ul下的第三个子元素,且该子元素的类型是li的时候,设置其颜色为红色
  	在计算过程中,不计算其它类型元素
  */
  ul li:nth-of-type(3) {
    color: red;
  }
</style>

<ul>
  <li>content1</li>
  <li>content2</li>
  <span>span 1</span>
  <!-- content3的颜色被设置成了红色 -->
  <li>content3</li>
  <li>content4</li>
  <li>content5</li>
</ul>

<!-- :nth-last-of-type(n) -->
<style>
  /* 
  	ul下的倒数第三个子元素,且该子元素的类型是li的时候,设置其颜色为红色
  	在计算过程中,不计算其它类型元素
  */
  ul li:nth-last-of-type(3) {
    color: red;
  }
</style>

<ul>
  <li>content1</li>
  <li>content2</li>
  <!-- content3的颜色被设置成了红色 -->
  <li>content3</li>
  <span>span 1</span>
  <li>content4</li>
  <li>content5</li>
</ul>

:nth-child(n)的其它使用方式

:nth-child(n)的其它使用方式同样使用于:nth-last-child(n):nth-of-type(n):nth-last-of-type(n)

/*
	选中所有的偶数列
	:nth-child(2n) 等价于 :nth-child(even)
*/
ul li:nth-child(2n) {
  color: red;
}

/*
	选中所有的偶数列
	:nth-child(2n + 1) 等价于 :nth-child(odd) 等价于 :nth-child(2n - 1)
*/
ul li:nth-child(2n + 1) {
  color: red;
}

/*
	选中第一个子元素
	:nth-child(1) 等价于 :first-child
*/
ul li:nth-child(1) {
  color: red;
}

/*
	-n + X
	选中前X个子元素
*/
ul li:nth-child(-n + 3) {
  color: red;
}

/*
	设置第一个,第五个,第九个,第十三个 ... 子元素的字体颜色为红色
*/
ul li:nth-child(4n + 1) {
  color: red;
}

<style>
  /*
 	  ul :nth-child(2) 相当于  为ul下任意层级 任意类型的子元素都添加了:nth-child(2)这个结构伪类
  
  	ul > :nth-child(2) 相当于 为ul的第二个直接子元素设置对应的样式,在本例中 等价于 ul li:nth-child(2)
  */
  ul :nth-child(2) {
    color: red;
  }
</style>

<ul>
  <li>content1</li>
  <!-- content2的颜色被设置为了红色 -->
  <li>content2</li>
  <li>content3</li>
  <li>
    <span>span1</span>
    <!-- span2的颜色被设置为了红色 -->
    <span>span2</span>
  </li>
  <li>content5</li>
</ul>

否定伪类 --- :not()

:not(x) --- x是一个简单选择器, 可以是元素选择器、通用选择器、属性选择器、类选择器、id选择器、伪类(除否定伪类)等任何合法的选择器

在设置:not(x)的时候,一般会添加一个限制条件, 例如xxxx :not(x), 从而避免将样式添加到bodyhtml等元素上

/*
	.dv元素下 没有.lorem 这样一个类的元素
	tips:
		1. :not使用形式是以函数形式进行使用的
		2. 其中的值 不能使用引号进行包裹
*/
.dv :not(.lorem){
  color: red;
}

伪元素

常用的伪元素有

  • :first-line、::first-line
  • :first-letter、::first-letter
  • :before、::before
  • :after、::after
  1. 为了区分伪元素和伪类,建议伪元素使用2个冒号,比如::first-line

  2. 伪元素用于选择某一个具体的元素中某一个或某些具体的部分

  3. 行内替换元素一般不能设置伪元素,因为对其设置伪元素其实本质

    是给其占位元素进行设置,最终会被实际需要渲染的元素给替换掉

::first-line,::first-letter

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 800px;
      background-color: #f00;
      color: #fff;
    }

    /* .keyword {
      font-size: 30px;
      color: orange;
    } */

    .box::first-line {
      font-size: 30px;
      color: orange;
    }

    .box::first-letter {
      font-size: 50px;
      color: blue;
    }
  </style>
</head>
<body>
  
  <div class="box">
    <span class="keyword">雁门关,别名西陉关 ,坐落于我国山西省忻</span>州市代县以北约成员国20千米的雁门山。它是长城上的一个关键大关,与宁武关、偏关并称之为“外三关”。坐落于偏关县大河上,辖四侧墙,总长度数百公里。迄今仍有30千米储存完好无损,所有用砖遮盖,沿堤岸耸立,十分壮阔。“边关丁宁岩,山连紫塞,地控大河北,鑫城携手共进强。”这也是前人对偏关的赞扬。早在春秋战国时代,这儿便是赵武灵王攻克胡林的竞技场。唐朝名将在关东建有九龙庙,宋代建有魏镇、杨三关。现有的关城始建明洪武二十三年,是重点学科文物古迹。
  </div>

</body>
</html>

::before::after

::before::after常通过 content 属性来为一个元素添加修饰性的内容

往一段文本的前后加入对应的内容的时候,我们可以在元素的前后插入对应的内容

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .before {
      color: red;
    }

    .after {
      color: blue;
    }

    /* 伪元素 */
    /* 在.item后边添加上foo文本 */
    .item::before {
      /* 设置的内容 */
      content: "321";
       /* 对插入的内容设置对应的样式 */
      color: orange;
      font-size: 20px;
    }

    .item::after {
      /* content: "cba"; */
           /*
          1. 可以使用url函数来设置插入的图片的路径
          2. url函数的参数可以使用引号进行包裹
          3. 在css中的引号 推荐使用 双引号 而不是 单引号
        */
      content: url("../images/hot_icon.svg");
      color: green;
      font-size: 20px;

      /* 位置不是很好看(以后) */
      position: relative; /* 相对定位 */
      left: 5px;
      top: 2px;
    }

    /* .new::after {
      content: url("../images/new_icon.svg");
    } */

    /* 额外的补充 */
    /* ::after是一个行内级元素 */
    
    /* 在.lorem后边插入一个 8 * 8的红色矩形 */
    .box5::after {
      /* 使用伪元素的过程中, 不要将content省略 */
      /*
	 
  	即使不需要设置插入的内容 --- 此时可以使用空字符串进行代替
      */
      content: "";
      /*
        默认情况下,::before 和 ::after 插入的元素
        都是行内非替换元素 所以需要将他们转换为行内块元素
        因为 行内级元素 是无法设置对应的width和height的
      */
      display: inline-block;
      width: 8px;
      height: 8px;
      background-color: #f00;
    }
  </style>
</head>
<body>
  
  <div class="box">
    <span class="before">123</span>
    我是div元素
    <span class="after">abc</span>
  </div>

  <div class="box2">
    <span class="before">123</span>
    我是box2
    <span class="after">abc</span>
  </div>

  <!-- 伪元素方案 -->
  <div class="box3 item">我是box3</div>
  <div class="box4 item">我是box4</div>

  <!-- 伪元素的补充 -->
  <div class="box5">我是box5</div>

</body>
</html>

这样做存在如下问题:

  1. 如果多处文本前后需要添加相同的内容的时候,这么做必须需要重复编写大量相同的代码
  2. 因为文本内容和span元素之间有换行,所以在前后插入的元素和文本之间必然存在一个空格

此时,CSS就为我们提供了::before::after伪元素来实现在一个元素的前边和后边插入对应的图片或文本