3.1 [一步步跑完前端学习路线] 前端内容系统化梳理-层叠样式表-CSS-样式的绑定和选择器

157 阅读6分钟

选择器

当你看过内部样式和外部样式的写法, 不可避免会牵扯到选择器这个概念.

考虑一个点, 为什么要把CSS和HTML分离, 而不是统一使用内联样式写在标签上? 为什么要这样做, 有哪些优点, 或者缺点?

接下来我们开始详细分析各种选择器. 看能不能从中找到答案?

  1. 元素选择器(集合): div跳过
  2. 类选择器(集合):.children 跳过
  3. ID选择器(单个元素):#xiaoming 跳过
  4. 通配符选择器(所有): *为通配符选择器, 选中所有元素, 即样式对所有元素生效

组合选择器(两个以上的选择器的组合)

逗号分隔: 表示全选, 比如这里color样式会应用于所有的h2p

h2,p {
  color: gray;
}

空格分隔: 表示进一步筛选, 这里选中的是在本篇HTML中所有的div内部的所有的p, 最终选中的是p标签, 但有一个前提条件: p标签外得有div标签

div p {
  color: gray;
}

注意父子包含关系: (无论多深都会选中)

<div>
    <p>选中</p>
</div> 
<div>
    <h1>
        <p>选中</p>
    </h1>
</div> 
<p>未选中</P>

无空格分隔: div p 如果去掉空格, 就变成了divp, 这样的会被识别为一个叫divp的标签, 这样的标签在HTML中明显是不存在的, 所以没有意义. 那什么时候才有有意义呢? 如下示例这样的选择器是有意义的. 这样的选择器能被CSS识别为两个类选择器.children,.girl, 但是中间没有空格: 这样会选中的是class同时包含.children,.girl的元素

.children.girl {
  color: green;
}
<div class="children girl" >选中</div> 
<div class="girl children" >选中</div> 
<div class="girl" >未选中</div> 
<div class="children" >未选中</div> 

以上距离都是两个选择器的组合, 但是三个四个N个都是同理.

属性选择器

简单属性选择器: [xxx]只要标签包含指定的这个属性就会被选中

// (1) 这里其实是一个组合选择器: h1 和 [class] 两个选择器的 无空格组合
h1[class] {
  color: silver;
}
// (2) 这里是 a[href][title] 三个选择器的 无空格组合
a[href][title] {
  font-weight: bold;
}
<h1>(1)未选中</h1>
<h1 class>(1)选中</h1>
<h1 class="name">(1)选中</h1>

<a>(2)未选中</a>
<a hlef>(2)未选中</a>
<a title>(2)未选中</a>
<a href title>(2)选中</a>
<a href title style>(2)选中</a>
<a href="/" title="小明">(2)选中</a>

基于属性的值进一步筛选的属性选择器

这里给了选中和未选中示例, 尽量模拟了一些边界情况, 可以对比看更容易理解.

类型描述选中属性未选中属性
[foo~="bar"]所有带有foo属性、且foo属性的值严格等于bar的元素foo="bar"foo="barr"
[foo~="bar"]选择所有带有foo属性、且foo属性被空白分隔的单词列表中含有单词bar的元素。foo="bar"foo="bar xxx"foo="barr"
[foo*="bar"]选择所有带有foo属性、且foo属性值中含有子串bar的元素。foo="bar"foo="barr"foo="abarr"foo="bxar"
[foo^="bar"]选择所有带有foo属性、且foo属性值以bar开头的元素(严格意义的开头)。foo="bar"foo="barr"foo="abar"foo="xxx bar"
[foo$="bar"]选择所有带有foo属性、且foo属性值以bar结束的元素(严格意义的结尾)。foo="bar"foo="abar"foo="barr"foo="bar xxx"
[foo|="bar"]选择所有带有foo属性、且foo属性等于bar或以bar-开头的元素(严格意义的开头)foo="bar"foo="bar-x"foo="bar-xx aa"foo="barr-xxx"foo="aa bar-xxx"

衍生一下: [class~="bar"].bar等同

注意一下,选择器不能以-开头或结束,-只能放在名称中间

忽略大小写标识符i

a[href$='.PDF' i]

选中所有href.PDF且不分大小写(.pdf.PDF.PdF.pDF等)结尾的a标签

选择子元素

只会选择下一级子节点, 再往下就不会选中了

h1 > strong {
  color: red;
}
<h1>This is <strong>选中</strong> important.</h1>
<h1>
  This is <em>really <strong>未选中</strong></em> important.
</h1>

选择相邻兄弟元素(弟弟节点) +

h1 + p {
  margin-top: 0;
}

选中的是拥有共同的父节点、且和h1相邻、且是跟在h1后面的节点(最多只有一个).

思考一下为什么不能选中h1之前的兄弟节点?

选择所有的弟弟节点~

h2 ~ ol {font-style: italic;}

选中拥有共同的父节点、且在h2之后的所有ol节点(可以有很多个)

伪类选择器:``::

为了文章的尽可能的简洁和全面, 对细分具体内采取引用现有成熟文章方式进行.

伪类基本概念和用法-MDN

各个伪类概念和释义(左侧有目录可以切换查看其他伪类)

总结一下伪类做了什么事情:

1. 用于指定所选元素的特殊状态

  • 比如涉及键盘/鼠标行为的:hover:active:focus(聚焦)、:focus-visible(通过键盘/tab等导航导致的聚焦的样式, 或通过编程聚焦的样式)、:hocus-within(当前元素或其子孙元素聚焦导致导致的样式,常用于输入框前的label)、:in-range: input输入框的数字在maxmin中间、:indeterminate: 比如checkbox中间态(半选状态)、:invalid(表单验证错误)、
  • 涉及A标签的:link:visited:any-link;
  • 涉及表单控件的:autofill:blank:checked:disabled:default(默认被选中节点)、:empty(空输入)、:enabled:focus(聚焦)、
  • 涉及到播放器audio/video缓冲状态的:buffering;
  • 涉及时间维度的(WebTT、视频实时字幕):future(将来的、前途)、:current(当前的、现在)、:past(过去的)
  • 涉及到自定义控件的:defined(用户自创建的控件、且已经定义好的)
  • 其他: 涉及语言排版方向的:dir, :fullscreen:当前处于全屏的元素(只能是根节点、且全屏),:host,

2. 关系查找选择器

通过<current-selector>:伪类-->选择其他节点元素

  • :last-child: current-selector是否为父元素最后一个子节点
  • :first-child: 同上, 第一个子节点
  • :nth-child(): (函数式的下面讲)
  • :last-of-type: 相对于last-child有两点区别, 可以指定元素的类型通过current-selector, 这样的话查找只能往上一级查找, 所有以parent-selector.
  • :firt-of-type:同上, 第一个节点
  • :nth-of-child():(函数式的下面讲)
  • :nth-last-of-type:(函数式的下面讲)

3. 函数式伪类

函数式伪类主要用于逻辑筛选. <current-selector>:函数名(<relative-selector-list>), 其中current-selector可为空(这时候相当于*,整篇文档), 作用是: 在parent-selector元素内, 找到符合函数名(<relative-selector-list>)的节点并应用样式.

  • :has(): 能否在current-selector找到至少一个符合relative-selector-list元素。当current-selector不存在则全局搜索,最后结果是选中的是current-selector或没选中。
  • :host(): 用于在自定义元素、Shadow DOM的根节点设置样式,:host可无条件选择根节点。
  • :host-context(): 用于定义自定义元素、Shadow DOM的内部元素(根节点的后代节点)的样式,传入根节点的后代节点选择器,选中的是后代节点。
  • :is(): 又称为:any()/:matches():传入一个,分隔的选择器列表,内部元素能在列表中找到既被选中。
  • :lang(): 语言选择器:传入语言如en-US,符合即选中current-selector
  • :not(): 用于选择不符合指定选择器的元素。传入一个选择器,选中所有不匹配该选择器的元素。
  • :nth-child(): 用于选择父元素下的特定子元素。接受一个参数,可以是数字、关键字(如oddeven)或公式(如2n+1)。
  • :nth-of-type(): 类似于:nth-child(),但只考虑同类型的元素。选择父元素下特定类型的子元素。
  • :nth-last-of-type(): 与:nth-of-type()相似,但从父元素的最后一个子元素开始计数,选择特定类型的子元素。
  • :state(): 用于表示元素的状态,通常用于用户交互的状态(如:hover:focus等)。注意,state并不是标准的CSS伪类。
  • where(): 类似于:is(),但具有更高的优先级。用于选择符合指定选择器列表的元素,但不会影响其他选择器的优先级。