CSS

CSS基础-选择器

This entry is part 2 of the seriesenjoy-css

选择器可以选中页面上的特定元素并为其指定样式。 CSS提供了一组极其丰富的选择器,这些选择器可以以有趣的方式进行混合和匹配。

基础选择器

最基本的选择器

css
/* 通用选择器。 该选择器匹配所有元素 */
/* focus(1:1) */
* {
color: red
}
/* 类型选择器或则标签选择器 */
/* focus(1:1) */
p {
padding: 8px;
}
/*
类选择器。该选择器匹配class属性中有指定类名的元素
例如: <div class="my-class"> Hello World! </div>
*/
/* focus(1:1) */
.my-class {
color: red
}
/*
ID选择器。 该选择器匹配拥有指定ID属性的元素
例如: <div id="my-id"> Hello World! </div>
*/
/* focus(1:1) */
#my-id {
color: red
}

伪类选择器

伪类选择器用于选择处于某种特定状态的元素。这种状态可能是由于用户交互,也可能是由于元素相对于其父级或兄弟元素的位置。

伪类选择器始终以一个冒号:开始,其语法如下

css
selector:pseudo-class {
property: value;
}

例如,伪类 :hover 可以用于选择一个按钮,当用户的指针悬停在按钮上时,设置此按钮的样式

Code Playground
<style>
  button {
    padding: 20px;
    border: 1px dashed red;
    background: white;
  }

  /* 👇 */
  button:hover {
    /* 鼠标悬停时,改变按钮背景颜色 */
    background: #6383f0;
  }
</style>

<button>Hover over me!</button>

MDN上有超过50中不同类型的伪类, 建议您尽可能的查看一下。

下面我们会介绍一些常用的伪类

focus/focus-within

  • focus: 匹配通过鼠标点击、触摸屏幕或者按Tab键导航而获得焦点的元素
  • focus-within: 解决嵌套元素的焦点问题。 当父元素中的任意子元素成为焦点时, 规则生效。
Code Playground
<link rel="stylesheet" href="./form.css">
<style>

#email:focus {
  outline: 3px solid white;
  outline-offset: .25rem;
}

/* 👉 form 内的任意子元素focus时, 该规则生效*/
.form:focus-within {
  outline: 3px solid green;
  outline-offset: 0.25rem;
}

</style>
<form class="form" action="">
  <div class="form_group">
    <label class="form_label" for="email">Email</label>
    <input class="form_input" type="email" id="email" />
  </div>

  <div class="form_group">
    <label class="form_label" for="password">Password</label>
    <input class="form_input" type="password" id="password" />
  </div>
</form>

first-child/last-child/nth-child(an+b)、first-of-type/last-of-type

  • li:first-child: li如果是其兄弟元素中的第一个元素, 则匹配
  • li:last-child: li如果是其兄弟元素中的最后一个元素, 则匹配
  • li:nth-child(an+b): li如果是其兄弟元素中的指定位置, 则匹配
Code Playground
li:first-child {
  font-size: 2rem;
}
li:last-child {
  font-size: 2rem;
}

/* 👉 尝试下 n, 2n, 3n, 3n+2, n+4, -n+4 ... */
li:nth-child(3) {
  font-size: 3rem;
})
  • li:first-of-type: 一组兄弟元素中 指定类型 的第一个元素
  • li:last-of-type: 一组兄弟元素中 指定类型 的最后一个元素
Code Playground
/* ❌ li如果是一组兄弟元素中的第一个, 则匹配 */
li:first-child {
  font-size: 2rem;
}
/* ❌ li如果是一组兄弟元素中的最后一个, 则匹配 */
li:last-child {
  font-size: 2rem;
}

/* ✅  一组兄弟元素中, 第一个出现的li元素匹配 */
li:first-of-type {
  font-size: 3rem;
}
/* ✅  一组兄弟元素中, 最后一个出现的li元素匹配 */
li:last-of-type {
  font-size: 3rem;
}
li:nth-of-type(2) {
  font-size: 6rem;
}

has()、is()/where()、not()

has()

has()允许开发者基于元素的子元素来选择元素。这个伪类本质上是一个父元素选择器

尝试实现下面功能, 注意切换 Show caption时的差异

Show caption

<figure>内部包含有<figcaption>时,我希望<figure>有以下特性:

  • Padding
  • Background
  • Shadow

在没有has()之前,我们只能通过Javascript动态的给<figure>元素添加某个类来实现该功能, 比如:

css
figure.with-caption {
padding: 16px;
background-color: #fff;
box-shadow: 0 3px 10px 0 rgba(0, 0, 0, 0.1);
}

但是有了has()之后,仅通过CSS我们就能实现上面的要求

Show caption
css
/* 当figure内部包含有figcaption时 */
figure:has(figcaption) {
padding: 16px;
background-color: #fff;
box-shadow: 0 3px 10px 0 rgba(0, 0, 0, 0.1);
}

is()/where()

is()where() 都以选择器列表作为参数,并选择该列表中任意一个选择器可以选择的元素, 这对于以更紧凑的形式编写大型选择器非常有用。

例如你的同事编写了以下代码:

css
h1 > b, h2 > b, h3 > b, h4 > b, h5 > b, h6 > b {
color: hotpink;
}

那么你可以改用:is()where()达到相同的效果:

css
/* 提高易读性的同时避免了使用长选择器:*/
:is(h1,h2,h3,h4,h5,h6) > b {
color: hotpink;
}
无限直观了解使用 :is() 前后的效果

not()

用于选择不符合一组选择器的元素,因此也被称为反选伪类(negation pseudo-class)。它的作用是防止特定的元素被选中,通过将一个或多个以逗号分隔的选择器列表作为其参数,选择器中不得包含另一个否定选择器或伪元素

其语法如下:

css
:not(selector1, selector2, ...) {
/* ... */
}

下面用一个例子解释下该伪类是如何使用的, 需求如下:

  • 创建一个ul列表, 内部包含n个li
  • 除第一个li之外的其余li左边距设为40px

你第一时间可能想到用下面这种方法去实现:

css
li {
margin-left: 40px;
}
li:first-of-type {
margin-left: 0px
}

但其实使用not()可以更简单的实现

Code Playground
<style>
li {
  font-size: 2rem;
}
li:not(:first-of-type){
  margin-left: 40px
}
</style>
<ul>
  <li>🍔</li>
  <li>🍟</li>
  <li>🧀</li>
  <li>🍿</li>
  <li>🍖</li>
</ul>

link、hover、visited、active

Code Playground
<style>
  a:link {
    /* 未访问链接 */
    color: blue;
  }
  a:hover {
    /* 用户鼠标悬停 */
    background: yellow;
  }
  a:visited {
    /* 已访问链接 */
    color: purple;
  }
  a:active {
    /* 激活链接 */
    color: red;
  }

  p:active {
    /* 激活段落 */
    background: #eee;
  }
</style>

<p>
  本段包含一个链接:
  <a href="#">当您单击此链接时,它将变为红色。</a>
  当你点击该段落或链接时,它将变成灰色背景。
</p>

伪元素选择器

伪元素类似于伪类,但是它不匹配特定状态的元素,而是匹配在文档中没有直接对应HTML元素的特定部分。伪元素选择器可能只匹配元素的一部分,甚至向HTML标记中未定义的地方插入内容

例如, 我们可以为用::marker来为列表标记设置样式为📌.:

Code Playground
<style>
  li {
    font-size: 2rem;
  }
  li::marker {
    content: '📌.';
  }
</style>
<ul>
  <li>🍔</li>
  <li>🍟</li>
  <li>🧀</li>
  <li>🍿</li>
  <li>🍖</li>
</ul>

其语法如下, 注意是::这要与伪类区分开来:

css
selector::pseudo-element {
property: value;
}

细想一下,我们并没有显式的创建 列表标记, 但我们却可以通过::marker来给它设置样式.

这就是为什么它们被称为伪元素——这些选择器针对的是DOM中我们没有用HTML标记显式创建的元素。

伪元素类型

  • ::before:在选定元素的内容前插入内容。
  • ::after:在选定元素的内容后插入内容。
  • ::first-letter:选择元素的第一个字母。
  • ::first-line:选择元素的第一行。
  • ::marker:选择列表项的标记(例如列表项前的数字或符号)。
  • ::placeholder:选择表单元素的占位符文本。
  • ::selection:选择用户选中的文本。
  • ::backdrop:选择元素的背景层,通常用于全屏模式下的背景。
  • ::file-selector-button:选择文件输入元素的选择按钮。
  • ::cue:选择媒体元素的文本轨道(例如字幕或描述)。
  • ::part():选择使用::part()属性定义的部分。
  • ::slotted():选择使用插槽(slot)插入的元素。

组合器

CSS组合器(Combinators)用于描述两个选择器之间的关系,它们帮助我们更精确地选择和样式化文档中的元素。CSS组合器可以将两个或多个选择器组合起来,以便更准确地定位和选择元素

以下是CSS中的四种组合器:

  1. 后代选择器(Descendant Selector):使用空格( )来连接两个选择器,表示第二个选择器是第一个选择器的后代。例如,div p 选择所有在<div>元素内部的<p>元素。
  2. 子选择器(Child Selector):使用大于号>来连接两个选择器,表示第二个选择器是第一个选择器的直接子元素。例如,div > p 选择所有直接在<div>元素内部的<p>元素。
  3. 相邻兄弟选择器(Adjacent Sibling Selector):使用加号+来连接两个选择器,表示第二个选择器紧跟在第一个选择器后面,并且它们共享同一个父元素。例如,div + p 选择紧跟在<div>元素后面的第一个<p>元素。
  4. 一般兄弟选择器(General Sibling Selector):使用波浪线~来连接两个选择器,表示第二个选择器跟在第一个选择器后面,并且它们共享同一个父元素。例如,div ~ p 选择所有在<div>元素后面的<p>元素。
Code Playground
<link rel='stylesheet' href='./styles.css'>
<style>
  /* 后代选择器 */
  .main-list li {
    border: 2px dotted;
  }
  /* 子选择器 */
  .main-list > li {
    border: 2px solid;
  }

  /* 相邻兄弟选择器 */
  .apple + li::marker {
    content: '📌'
  }

  /* 一般兄弟选择器 */
  .apple ~ li::after {
    content: '👈'
  }
</style>

<ol class="main-list">
  <li>Salt</li>
  <li>Pepper</li>
  <li>
    Fruits & Veg:
    <ul>
      <li class="apple">Apple</li>
      <li>Banana</li>
      <li>Carrots</li>
    </ul>
  </li>
</ol>

属性选择器

CSS属性选择器是一种强大的工具,它允许开发者根据元素的属性和属性值来选择和样式化元素。以下是CSS属性选择器的详细解释和使用示例:

基本用法

属性选择器的基本语法是[attr],它选择所有具有指定属性的元素。例如,a[title]选择所有具有title属性的<a>元素。

具体属性选择器:

  • [attr="value"]:选择所有属性值完全匹配给定值的元素。
  • [attr~="value"]:选择所有属性值包含给定值的元素,且值之间用空格分隔。
  • [attr|="value"]:选择所有属性值以给定值开头的元素,且值之间用连字符分隔。
  • [attr^="value"]:选择所有属性值以给定值开头的元素。
  • [attr$="value"]:选择所有属性值以给定值结尾的元素。
  • [attr*="value"]:选择所有属性值包含给定值的元素。

Questions? Let's chat

discord logoOPEN DISCORD
6423
members online
previous article
CSS基础-基本概念
next article
CSS基础-层叠、优先级与继承

A TypeScript Full Stack Blog

Share articles about Typescript, React, Next.js, Node.js and Css from time to time.
No spam, unsubscribe at any time.