WebKist Inside: CSS 样式表的组成

webkist,inside,css,样式表,组成 · 浏览次数 : 15

小编点评

**Composite Selectors** Composite selectors allow you to combine multiple selectors to target different elements on the page. There are three main types of composite selectors: - **Class selectors:** Selects elements that have a specific class name. - **ID selectors:** Selects elements that have an ID attribute. - **Attribute selectors:** Selects elements that have a specific attribute value. **Composite Selector Examples** **1. Descendant Combinator** ```css .foo::before:hover.foo::before::marker { background-color: red; } ``` This selector selects all elements that are descendants of an element with the class "foo" and that have the class "before" and the class "marker". **2. Child Combinator** ```css >p { background-color: green; } ``` This selector selects all elements that are descendants of an element with the tag name "p". **3. Next-Sibling Combinator** ```css +::after { content: "This element is the next sibling of the preceding element"; } ``` This selector selects all elements that are the next sibling of an element with the class "previous". **4. Subsequence-Sibling Combinator** ```css ~::before { content: "This element is preceded by the preceding element"; } ``` This selector selects all elements that are preceded by an element with the class "previous". **5. Other Composite Selectors** Composite selectors can be used to combine elements from different categories, such as: - Descendant and attribute selectors - Child and class selectors - Next-Sibling and preceding selectors **Note:** Composite selectors can be used to create complex and selective selectors that can target elements that would be difficult to select otherwise. However, it's important to note that composite selectors can also be more complex and difficult to maintain than other types of selectors.

正文

1 StyleSheet

一张 StyleSheet 由一系列 Rules 组成,这些 Rules 可以分成 2 大类:

1 Style Rule

2 At-Rule

下面的例子展示了 Style Rule 和 At-Rule:

// Style Rule
div {
    background-color: red;
    font-size: 12px;
}

// At-Rule
@media print {
    body {
        font-size: 10pt;
     }
}

上面代码的第 1 个 Rule 是 Style Rule,表示 <div> 标签的背景色是红色,字号是 12px。

代码的第 2 个 Rule 是 At-Rule,At-Rule 都以 '@' 字符开始。@media 表示如果打印 HTML,HTML 中的字号使用 10pt。

2 Style Rule

Style Rule 由 2 部分组成:

1 selector list

2 声明块

如下图所示:

 selector list 定义一系列 selector,表示声明块应该应用在哪些 HTML 标签上。比如上图中的 selector list 就表示,background-color 和 font-size 应用在 <div> 和 <p> 标签上。

有关 Style Rule 的 selector,后面会有更详细的介绍。

3 Qualified Rule

从定义上讲,Style Rule 只是 Qualified Rule 的一种特殊形式,Qualified Rule 的组成如下图所示:

 从图上可以看到,Qualifed Rule 由 prelude声明块两部分组成。如果 prelude 是 selector list,那么此时的 Qualified Rule 就是 Style Rule。

那么什么时候会使用非 Style Rule 的 Qualified Rule 呢?一个场景是 At-Rule @keyframe 定义的动画:

div {
  // 1. 使用 @keyframe 定义的 slide-right 动画
  animation-name: slide-right;
  animation-duration: 2s;
}

// 2. 使用 @keyframe 定义 slide-right 动画
@keyframes slide-right {

    // 3. from 50% to 就是一个 Qualified Rule,但是不是 Style Rule
    from {
    margin-left: 0px;
    }

    50% {
    margin-left: 110px;
    opacity: 1;
    }

    50% {
    opacity: 0.9;
    }

    to {
    margin-left: 200px;
    }
}

上面代码注释 1 处 div 标签使用了 @keyframe 定义的一个动画 slide-right。

代码注释 2 处就是动画的定义,在定义内部,from、50%、to 处的 Rule 就是一个 Qualified Rule,但是不是 Style Rule,如注释 3 所示。

非 Style Rule 的 Qualifed Rule 不能作为 CSS 样式表的顶层 Rule,CSS 样式表的顶层 Rule 只能是 Style Rule 或者 At-Rule

4 声明块

声明块中的声明(Declaration)分成 2 类:

1 属性声明(property declaration)

2 描述符声明(descriptor delcaration)

在 Qualifed Rule 中的声明称为属性声明,而在 At-Rule 中的声明称为描述符声明。属性声明比较常见,描述符声明的例子如下所示:

@font-face {
  // 描述符声明
  font-family: overridden-font;
}

本质上来看,属性声明和描述符声明没有什么区别,只是所在的位置不一样。

无论是属性声明,还是描述符声明,都由声明名和声明值组成

5 At-Rule

At-Rule 以 '@' 字符开头。

At-Rule 分成 2 大类:

1 声明式 At-Rule(statement At-Rule)

2 块式 At-Rule(Block At-Rule)。

声明式 At-Rule 就像一条语句一样,以分号结尾。@cahrset 就是一个声明式 At-Rule:

@charset "utf-8";

块式 At-Rule 由 {} 包围,上面的 @media 就是一个块式 At-Rule。

块式 At-Rule 里面可以包含描述符声明,比如:

@font-face {
  // 描述符声明
  font-family: overridden-font;
}

可以包含 Qualifed Rule,比如:

@media print {
    // Qualifed Rule,也是 Style Rule
    body {
        font-size: 10pt;
     }
}

可以包含其他 At-Rule,比如:

@supports (display: flex) {
  @media screen and (min-width: 900px) {
    article {
      display: flex;
    }
  }
}

6 Selector

Style Rule 中的 Selector 用来匹配 HTML 中的标签,以便决定声明块中的声明运用在哪些 HTML 标签上,比如:

div {
    background-color: red;
}

表示 HTML 中的所有 div 标签背景色都要是红色。

Selector 分为 5 类: 简单 Selector(Simple Selector)、复合 Selector(Compound Selector)、组合 Selector(Complex Selector)、Selector List。

6.1 Simple Selector

简单 Selector 分为 6 种情形:

1 类型 Selector (Type Selector)

2 通用 Selector (Universal Selector)

3 属性 Selector (Attribute Selector)

4 类 Selector (Class Selector)

5 ID Selector

6 伪类 Selector (Pseudo-Class Selector)

6.1.1 类型 Selector

类型 Selector 就是 HTML 中的标签名,比如:

div {
    background-color: red;
}

中的 div 就是类型 Selector,匹配 HTML 中的所有 <div> 标签。

6.1.2 通用 Selector

通用 Selector 是一种特殊的类型 Selector,它匹配任意一个 HTML 标签,使用字符 '*' 表示,比如:

* {
    font-size: 13px;
}

表示 HTML 中每一个标签的字号都是 13px。

如果通用 Selector 和其他简单 Selector 组成复合 Selector,那么通用 Selector 不起作用,也就是说:

*.news <===> 等价于 .news
*#item <===> 等价于 #item

6.1.3 命名空间

@namespace 定义一个命名空间,相关语法如下:

@namespace <namespace-prefix>? [<string>|<url>]

其中,namespace-prefix 可以省略,如果省略了 namespace-prefix,那么就是定义了一个默认命名空间。

定义命名空间的例子如下:

// 定义了默认命名空间
@namespace "http://www.w3.org/1999/xhtml";

// 定义了一个命名空间,namespace-prefix 是 svg
@namespace svg "http://www.w3.org/2000/svg";

// 以字符串定义命名空间
@namespace  xml "XML-namespace-URL";

对于定义在一张 CSS 样式表里面的 namespace-prefix,只在当前 CSS 样式表可见。

The namespace prefix is declared only within the style sheet in which its @namespace rule appears. It is not declared in any style sheets importing or imported by that style sheet, nor in any other style sheets applying to the document.

如果一张样式表里面声明了多个命名空间,只有最后一个命名空间有效。

If a namespace prefix or default namespace is declared more than once only the last declaration shall be used.

类型 Selector 和通用 Selector 可以结合命名空间使用,这样类型 Selector 和通用 Selector 只匹配位于指定命名空间的 HTML 标签。

相关语法如下:

// ns 表示命名空间
// E 表示类型 Selector 或者通用 Selector

// 匹配位于命名空间 ns 的 HTML 标签 E
ns|E

// 匹配位于任意命名空间的 HTML 标签 E,如果 E 不属于任何命名空间,也会匹配上
*|E

// 匹配不属于任何命名空间的 HTML 标签 E
|E

// 如果没有默认命名空间,这个语法等价于 *|E
// 如果有默认命名空间,这个语法等价于 ns|E
E

下面看一些例子:

@namespace foo url(http://www.example.com);
foo|h1 { color: blue }  /* first rule */
foo|* { color: yellow } /* second rule */
|h1 { color: red }      /* ...*/
*|h1 { color: green }
h1 { color: green }

上面代码定义了一个命名空间 foo。

第 1 条 Rule 匹配 HTML 中所有位于命名空间 foo 的 <h1> 标签。

第 2 条 Rule 匹配 HTML 中位于命名空间 foo 的所有标签。

第 3 条 Rule 匹配不属于任何命名空间的 <h1> 标签。

第 4 条 Rule 等价 HTML 中所有 <h1> 标签,这些 <h1> 标签可以位于任意命名空间,也可以不位于任何命名空间。

第 5 条 Rule 等价于第 4 条 Rule,因为没有定义默认命名空间。

6.1.4 属性 Selector

属性 Selector 匹配 HTML 标签中具有相应属性的标签,比如:

[class="example"]

匹配所有具有 class 属性的 HTML 标签,假设一个 <span> 标签具有 class 属性并且属性值是 “example",那么这个 <span> 标签就被匹配到:

<span class="example">Hello, World!</span>

属性 Selector 的语法如下:

// 匹配具有属性名为 attr 的 HTML 标签
[attr]

// 匹配具有属性名为 attr,属性值为 val 的 HTML 标签
[attr=val]

// 匹配具有属性名 attr 的 HTML 标签,并且该属性值是一个由空格分割的 list,
// 如果这个属性值 list 里面有一个值是 val,那么就匹配上。
// 如果 val 本身是一个空字符串或者包含空格的字符串,那么就匹配不上任何 HTML 标签
[attr~=val]

// 匹配具有属性名 attr 的 HTML 标签,并且该属性值为 val 或者以 val- 开头
[attr|=val]

// 匹配具有属性名 attr 的 HTML 标签,并且属性值以 val 开头。
// 如果 val 是空字符串,那么匹配不到任何 HTML 标签
[attr^=val]

// 匹配具有属性名 attr 的 HTML 标签,并且属性值以 val 结尾。
// 如果 val 是空字符串,那么匹配不到任何 HTML 标签
[attr$=val]

// 匹配具有属性名 attr 的 HTML 标签,并且属性值至少包含 val。
// 如果 val 是空字符串,那么匹配不到任何 HTML 标签
[attr*=val]

具体例子如下:

// 匹配具有 title 的 <h1> 标签
h1[title]

// 如果 <span> 标签有一个 class 属性,并且属性值为 example,则匹配
span[class="example"]

// 如果 <a> 标签的 rel 属性值是 "copyright copyleft copyeditor",则匹配
a[rel~="copyright"]

// 如果 <a> 标签的 hreflang 的属性值为 en 或者 en-US,则匹配
a[hreflang|="en"] 

// 如果 <object> 标签的 type 属性以 image/ 开头,则匹配
object[type^="image/"] 

// 如果 <a> 标签的 href 属性以 .html 结尾,则匹配
a[href$=".html"] 

// 如果 <p> 标签的 title 属性值为 "hello, world",则匹配
p[title*="hello"] 

和类型 Selector、通用 Selector 一样,属性 Selector 的属性名 attr 也可以结合命名空间。不同的是,类型 Selector、通用 Selector 可以结合默认命名空间,属性 Selector 不能结合默认命名空间。

相关语法如下:

@namespace foo "http://www.example.com";
[foo|attr=val] { color: blue }
[*|attr] { color: yellow }
[|attr] { color: green }
[attr] { color: green }

上面代码定义了一个命名空间 foo。

第 1 条 Rule 匹配属性名 attr 位于命名空间 foo 的 HTML 标签。

第 2 条 Rule 匹配属性名 attr 位于任意命名空间或者不位于任何命名空间的 HTML 标签。

第 3 条 Rule 和第 4 条 Rule 是等价的,只匹配 attr 不属于任何命名空间的 HTML 标签。

6.1.5 类 Selector

类 Selector 以 '.' 字符开始。

例子如下:

.test {
    font-size: 20px;
}

这个类 Selector 匹配第 1 个 和第 3 个 <h1> 标签,不匹配第 2 个 <h1> 标签,因为第 2 个 <h1> 标签没有对应的 class:

<h1 class="test">标题一</h1>
<h1>标题二</h1>
<h1 class="test">标题三</h1>

6.1.6 ID Selector

ID Selector 以 '#' 字符开始,ID Selector 必须是唯一的,因此只匹配唯一的 HTML 标签:

例子如下:

#test {
    font-size: 20px;
}

这个 ID Selector 匹配第 1个 <h1> 标签:

<h1 id="test">标题一</h1>
<h1>标题二</h1>
<h1>标题三</h1>

6.1.7 伪类 Selector

有一些匹配行为,上述的简单 Selector 无法表达,比如有一个场景是,当用户鼠标停留在 <h1> 标签上,<h1> 标签才变换背景色。为了表达"用户停留"这个行为,就需要使用伪类 :hover,例子如下:

h1:hover {
    background-color: red;
}

伪类 Selector 以 ':' 开头,可以分成普通伪类函数伪类

:hover 就是普通伪类,:lang() 就是一个函数伪类。

伪类必须结合类型 Selector 和通用 Selector 才能使用,必须跟在类型 Selector 和通用 Selector 后面

6.2 复合 Selector

复合 Selector 由一个或者多个简单 Selector 组成,如果有多个简单 Selector,简单 Selector 之间不能由 Combinator 连接。

一个复合 Selector 的所有简单 Selector 匹配完成,整个复合 Selector 才算匹配,比如:

div#test {
    background-color: red;
}

只匹配具有 id 属性并且 id 属性等于 test 的 <div> 标签:

<div>Test1</div>
<div id="test">Test2</div>

如果类型 Selector 或者通用 Selector 出现在复合 Selector 中,那么类型 Selector 和通用 Selector 必须是复合 Selector 中的第一个简单 Selector。

同时,如果复合 Selector 中已经有了一个类型 Selector 或者通用 Selector,就不可以有其他的类型 Selector 和通用 Selector。

在复合 Selector 中,类 Selector、ID Selector、属性 Selector、伪类 Selector 都称为 Subclass-Selector。

6.3 复合伪元素 Selector (Pseduo-Compound Selector)

和伪类(Pseduo-Class)一样,伪元素(Pseduo-Element)也是用来表达 HTML 标签无法表达的信息。

与伪类不同的是,伪类侧重表达某种状态或者行为,而伪元素侧重表达 HTML 文档的某部分内容,比如 HTML 文档某行的首字母,就可以使用伪元素 ::first-letter 来表示。

复合伪元素 Selector 的组成首先要有一个伪元素,这个伪元素的后面可以跟一个伪类,这个伪元素的前面可以有一个复合 Selector或者另外一个复合伪元素 Selector。因此下面两种复合伪元素 Selector 都是合法的:

.foo::before:hover
.foo::before::marker

复合伪元素 Selector 中不能出现 Combinator

复合微元素 Selector 是用来匹配伪元素的,要成功匹配伪元素需要满足:

1 被匹配的伪元素需要是复合伪元素 Selector 中的伪元素;

2 匹配复合伪元素 Selector 中的伪类;

3 匹配复合伪元素 Selector 中的复合 Selector,这个被匹配的 HTML 标签被称为 Originating Element。

如果复合伪元素 Selector 没有复合 Selector,那么默认使用通用 Selector,也就是说,下面两种复合伪元素 Selector 是等价的:

::before <====> 等价于 *::before

本质上讲,复合伪元素 Selector 跟复合 Selector 不一样,如果一个地方只能使用复合 Selector,那么就不能使用复合伪元素 Selector。

NOTE: A pseudo-compound selector is not a compound selector, and can’t be used in places that expect a compound selector only. Pseudo-compound selectors act as if they carry a combinator with themselves, expressing their relationship with their originating element, just as the > combinator expresses a relationship with a parent element.

6.4 组合 Selector

组合 Selector 是由 Combinator 连接的 2 个复合 Selector。

Combinator 总共有 4 种:

1 Descendant Combinator

2 Child Combinator

3 Next-Sibling Combinator

4 Subsequence-Sibling Combinator

6.4.1 Descendant Combinator

后代 Combinator,由空格表示,匹配一个 HTML 标签的所有后代标签,比如:

h1 em

会匹配 <h1> 标签的所有后代 <em> 标签:

<h1>This <span class="myclass">headline
is <em>very</em> important</span></h1>

6.4.2 Child Combinator

子 Combinator,由 '>' 表示,匹配一个 HTML 标签的所有子标签,比如:

body > p

会匹配 <body> 标签的所有子 <p> 标签:

<body>
    <p>段落1</p>
    <p>段落2</p>
    <p>段落3</p>
</body>

6.4.3 Next-Sibling Combinator

下一个相邻兄弟节点 Combinator,由 '+' 表示,直接看例子:

div + p

会匹配 <div> 标签后面第一个 <p> 标签,而不会匹配其他 <p> 标签:

<p>上一个兄弟节点</p>
<div>我要匹配</div>
<p>下一个兄弟节点</p>
<p>下下个兄弟节点</p>

6.4.4 Subsequence-Sibling Combinator

后续兄弟 Combinator,由 '~' 表示,直接看例子:

div ~ p

会匹配 <div> 标签后面所有的兄弟 <p> 标签,而不会匹配 <div> 标签上面的兄弟 <p> 标签:

<p>上一个</p>
<div>DIV1</div>
<div>DIV2</div>
<p>下一个</p>
<p>下下一个</p>

7 Selector List

由逗号 ',' 连接的简单 Selector、复合 Selector、组合 Selector 组成,比如:

div, h1#item, p + span {
    background-color: red;
}

h1, h2, h3 {
    background-color: green;
}

参考连接

Selector Level 4

CSS Syntax Model Level 3

 

与WebKist Inside: CSS 样式表的组成相似的内容:

WebKist Inside: CSS 样式表的组成

WebKist Inside: CSS 样式表的组成

WebKit Inside: CSS 样式表的解析

WebKit Inside: CSS 样式表的解析

WebKit Insie: Active 样式表

WebKit Inside: CSS 样式表的匹配时机介绍了当 HTML 页面有不同 CSS 样式表引入时,CSS 样式表开始匹配的时机。后续文章继续介绍 CSS 样式表的匹配过程,但是在匹配之前,首先需要收集页面里面的 Active 样式表。 1 Active 样式表 在一个 HTML 文件里面,

WebKit Inside: CSS 样式表的匹配时机

WebKit Inside: CSS 的解析 介绍了 CSS 样式表的解析过程,这篇文章继续介绍 CSS 的匹配时机。 无外部样式表 内部样式表和行内样式表本身就在 HTML 里面,解析 HTML 标签构建 DOM 树时内部样式表和行内样式就会被解析完毕。因此如果 HTML 里面只有内部样式表和行内

WebKit Inside: CSS 样式表解码字符集

CSS 样式表引入有3种方式: 外部样式表、内部样式表、行内样式,不同的引入方式,解码样式表的字符集原理不一样。 外部样式表 外部样式表由 link 标签引入,当 WebKit 解析到 link 标签时就会构造 CachedCSSStyleSheet 对象。这个对象持有 CachedResource

网页“悼念模式”全站变灰/黑白色CSS代码

【Playwright+Python】系列教程(四)Pytest 插件在Playwright中的使用

一、命令行使用详解 使用Pytest插件在Playwright 中来编写端到端的测试。 1、命令行执行测试 pytest --browser webkit --headed 2、使用 pytest.ini 文件配置 内容如下: [pytest] # Run firefox with UI addop

【现代 CSS】标准滚动条控制规范 scrollbar-color 和 scrollbar-width

Chrome 在 121 版本开始,原生支持了两个滚动条样式相关的样式 scrollbar-color 和 scrollbar-width。 要知道,在此前,虽然有 ::-webkit-scrollbar 规范可以控制滚动条,可是,::-webkit-scrollbar 是非标准特性,在 MDN 文