CSS-选择器详解

210 阅读6分钟

什么是CSS选择器? 按照一定的规则选出符合条件的元素,为之添加CSS样式

选择器的种类繁多,大概可以这么归类:

  1. 通用选择器(universal selector)
  2. 元素选择器(type selectors)
  3. 类选择器(class selectors)
  4. id选择器(id selectors)
  5. 属性选择器(attribute selectors)
  6. 组合(combinators)
  7. 伪类(pseudo-classes)
  8. 伪元素(pseudo-elements)

1. 统用选择器

  • 通用选择器(universal selector)

    • 所有的元素都会被选中
  • 一般用来给所有元素作一些通用性的设置

    • 比如内边距、外边距
    • 比如重置一些内容
    <!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>
        /* * {
          font-size: 30px;
          background-color: #f00;
        } */
    
        /* div {
          background-color: #f00;
        } */
    
        /* 更推荐的做法 */
        body, p, div, h2, span {
          margin: 0;
          padding: 0;
        }
      </style>
    </head>
    <body>
    
      <div>我是div元素</div>
      <p>我是p元素</p>
    
      <div>
        <h2>我是h2元素</h2>
        <p>我也是p元素  <span>呵呵呵呵</span> </p>
      </div>
    
    </body>
    </html>
    

PS效率比较低,尽量不要使用

2. 简单选择器(重要)

  • 简单选择器是开发中用的最多的选择器:

    • 元素选择器(type selectors), 使用元素的名称
    • 类选择器(class selectors), 使用 .类名
    • id选择器(id selectors), 使用 #id

image.png

  • id选择器注意事项

    • 一个HTML文档里面的id值是唯一的,不能重复
    • id值如果由多个单词组成,单词之间可以用中划线[连字符(hyphen)]、下划线_连接,也可以使用驼峰标识
    • 最好不要用标签名作为id值
    <!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 {
          color: red;
        }
    
        .box {
          color: blue;
        }
    
        #home {
          color: green;
        }
      </style>
    </head>
    <body>
      <!-- 强调: 在同一个HTML文档中, id不要重复, 应该是唯一 -->
    
      <div>我是div1</div>
      <div class="box">我是div2</div>
      <div id="home">我是div3</div>
    
      <p class="box">我是p元素</p>
    
      <h2 id="div">我是h2标题</h2>
    
      <!-- class/id的名称比较复杂 -->
      <div class="box one"></div>
      <div class="box-one box-first"></div>
      <div class="box_one box_first"></div>
      <!-- 大驼峰/小驼峰 -->
      <!-- <div class="boxOne BoxFirst"></div> -->
    
    </body>
    </html>
    
    • 效果 image.png

3. 属性选择器

  • 拥有某一个属性 [att]

  • 属性等于某个值 [att=val]

  • 了解

    • [attr*=val]: 属性值包含某一个值val

    • [attr^=val]: 属性值以val开头

    • [attr$=val]: 属性值以val结尾

    • [attr|=val]: 属性值等于val或者以val开头后面紧跟连接符-

    • [attr~=val]: 属性值包含val, 如果有其他值必须以空格和val分割

    <!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>
        [title] {
          color: red;
        }
    
        [title=div] {
          background-color: blue;
        }
      </style>
    </head>
    <body>
    
      <div>我是div元素</div>
      <div title="div">我也是div元素</div>
      <p>我是p元素</p>
      <h2 title="h2">我是h2元素</h2>
    
    </body>
    </html>
    
    • 效果

image.png

4. 后代选择器(重要)

  • 后代选择器一: 所有的后代(直接/间接的后代)

    • 选择器之间以空格分割
  • 后代选择器二: 直接子代选择器(必须是直接子代)

    • 选择器之间以 > 分割
<!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>
    /* 后代选择器 */
    .home span {
      color: red;
      font-size: 30px;
    }

    /* .home的子代的span元素设置一个背景 */
    .home > span {
      background-color: green;
    }
  </style>
</head>
<body>
  
  <div class="home">
    <span>啦啦啦啦</span>  
    <div class="box">
      <p>我是p元素</p>
      <span class="home-item">呵呵呵呵</span>
    </div>

    <div class="content">
      <div class="desc">
        <p>
          <span class="home-item">哈哈哈哈</span>
        </p>
      </div>
    </div>
  </div>

  <!-- 不希望被选中 -->
  <span>嘻嘻嘻</span>
  <div>
    <span>嘿嘿嘿</span>
  </div>

</body>
</html>
  • 效果

image.png

5. 兄弟选择器

  • 相邻兄弟选择器

    • 使用符号 + 连接
  • 普遍兄弟选择器

    • 使用符号 ~ 连接
<!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 + .content {
      color: red;
    }

    .box ~ div {
      font-size: 30px;
    }
  </style>
</head>
<body>
  
  <div class="home">
    <div>叽叽叽叽</div>
    <div class="box">呵呵呵呵</div>
    <div class="content">哈哈哈哈</div>
    <div>嘻嘻嘻嘻</div>
    <div>嘿嘿嘿嘿</div>
    <p>我是p元素</p>
  </div>

</body>
</html>
  • 效果

image.png

6. 选择器组(重要)

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

    • 在开发中通常为了精准的选择某一个元素

      • div.box
      • 既是一个div, 也必须有一个class为box
  • 并集选择器: 符合一个选择器条件即可(两个选择器以,号分割)

    • 在开发中通常为了给多个元素设置相同的样式;

      • div, p, h1 {}
    <!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;
        }
    
        body, p, h1, h2 {
          color: blue;
          font-size: 40px;
        }
      </style>
    </head>
    <body>
    
      <div class="box">我是div元素</div>
      <p>我是p元素</p>
      <h1>我是h1元素</h1>
    
    </body>
    </html>
    
    • 效果 image.png

7. 伪类

什么是伪类呢?

  • Pseudo-classes: 翻译过来是伪类
  • 伪类是选择器的一种,它用于选择处于特定状态的元素

常见的伪类:

  • 动态伪类(dynamic pseudo-classes)

    • :link、:visited、:hover、:active、:focus

    • 使用举例

      • a:link 未访问的链接
      • a:visited 已访问的链接
      • a:hover 鼠标挪动到链接上(重要)
      • a:active 激活的链接(鼠标在链接上长按住未松开)
    • 使用注意

      • :hover必须放在:link:visited后面才能完全生效
      • :active必须放在:hover后面才能完全生效
    • 建议的编写顺序是 :link、:visited、:hover、:active

    • 除了a元素,:hover、:active也能用在其他元素上

    <!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>
        /* a元素的链接从来没有被访问过 */
        a:link {
          color: red;
        }
    
        /* a元素被访问过了颜色 */
        a:visited {
          color: green;
        }
    
        /* a/input元素聚焦(获取焦点) */
        a:focus {
          color: yellow;
        }
    
        /* a元素鼠标放到上面 */
        a:hover {
          color: blue;
        }
    
        /* 点下去了, 但是还没有松手 */
        a:active {
          color: purple;
        }
    
        /* 所有的状态下同样的样式 */
        a {
          color: orange;
        }
      </style>
    </head>
    <body>
    
      <a href="http://www.mi.com">小米</a>
      <a href="http://www.baidu.com">百度一下</a>
    
      <input type="text">
    
      <div>我是div元素</div>
    
    </body>
    </html>
    
    • 效果

    image.png

    • :focus指当前拥有输入焦点的元素(能接收键盘输入)

      • 文本输入框一聚焦后,背景就会变红色

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

      • 动态伪类编写顺序建议为 :link:visited:focus:hover:active

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

        • 相当于a:link、a:visited、a:hover、a:active、a:focus的color都是red

  • 目标伪类(target pseudo-classes)

    • :target
  • 语言伪类(language pseudo-classes)

    • :lang( )
  • 元素状态伪类(UI element states pseudo-classes)

    • :enabled、:disabled、:checked
  • 结构伪类(structural pseudo-classes)(后续补充)

    • :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
  • 否定伪类(negation pseudo-classes)(后续补充)

    • :not()

8. 伪元素

  • 常用的伪元素有

    • :first-line、::first-line
    • :first-letter、::first-letter
    • :before、::before
    • :after、::after

为了区分伪元素和伪类,建议伪元素使用2个冒号,比如::first-line

  • 伪元素 ::first-line、::first-letter

    • ::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;
        }
    
        .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>
    
    • 效果(第一个字符和第一行的样式)

first-letter.png

  • ::before::after用来在一个元素的内容之前或之后插入其他内容(可以是文字、图片)

    • 通常会配合content属性来为该元素添加装饰内容。这个虚拟元素默认是行内元素
  • 注意!!!

    :before:after伪元素用来指定生成内容的样式和位置。如其名所示,:before和:after伪元素指定了一个元素文档树内容之前和之后的内容(就是指这个元素是要可以插入内容的,也就是说这个元素要是一个容器)。而inputimgiframe等元素都不能包含其他元素,所以不能通过伪元素插入内容。至于Chrome 中checkbox和radio可以插入,那应该是Bug了,要么就是姿势不对了。

    <!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::before {
          content: "321";
          color: orange;
          font-size: 20px;
        }
    
        .item::after {
          /* content: "cba"; */
          content: url("../images/hot_icon.svg");
          color: green;
          font-size: 20px;
    
          position: relative; /* 相对定位 */
          left: 5px;
          top: 2px;
        }
    
        /* 额外的补充 */
        /* ::after是一个行内级元素 */
        .box5::after {
          /* 使用伪元素的过程中, 不要将content省略 */
          content: "";
    
          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>
    
    • 效果:

image.png