# CSS工作原理

关于CSS规则如何为HTML添加样式，并解释层叠的工作机制——当元素的同一个样式属性有多种样式值的时候，CSS就要靠层叠机制来决定最终应用哪种样式。

## 剖析CSS规则

### 添加CSS样式的方法

主要有三种：

* 行内样式：写在特定HTML标签的style属性里
* 嵌入样式：将CSS样式放在HTML文档的head元素中
* 链接样式：用link标签引入外部css文件

另，样式表中链接其他样式的方法：@import url(css/styles2.css)

### CSS规则命名惯例

1. 第一种方法：多个声明包含在一条规则里。

```css
p{color:red; font-size:12px; font-weight:bold;}
```

1. 第二种方法：多个选择符组合在一起。

```css
h1,h2,h3{color:red; font-size:12px; font-weight:bold;}
```

1. 第三种方法：多条规则应用给一个选择符。

```css
h1,h2,h3{color:red; font-size:12px;}
h3{font-weight: italic;}
```

所有用于选择特定元素的选择符又分三种：

* 上下文选择符：基于祖先或同胞元素选择一个元素
* ID和类选择符：基于id和class属性的值选择元素
* 属性选择符：基于属性的有无和特征选择元素

## 上下文选择符

格式：

```
标签1 标签2 {声明}
```

其中，标签2就是我们想要选择的目标，而且只有在标签1是其祖先元素（不一定是父元素）的情况下才会被选中。

## 特殊的上下文选择符

### 子选择符

格式：

```
标签1>标签2
```

注意：标签2必须是标签1的子元素。

### 紧邻同胞选择符

格式：

```
标签1+标签2
```

标签2必须紧跟在其同胞标签1的后面。

### 一般同胞选择符

格式：

```
标签1~标签2
```

标签2必须跟（不一定紧跟）在其同胞标签1后面。

### 通用选择符

通用选择符\*是一个通配符，它匹配任何元素。

例如：

```
p *{color:green;}
```

会把p包含的所有元素的文本变成绿色。 注：所有子元素文本变成绿色，但p标签的文本不变色。

如果通配符前面没有标签，则表示网页所有元素。

## ID和类选择符

### 类属性

body标签中包含的任何HTML元素都可以添加class属性。

#### 类选择符

格式：

```
.类名
```

#### 标签带类选择符

格式：

```
标签.类名
```

#### 多类选择符

可以给元素添加多个类：class="class1 class2"。

格式：

```
.类名1.类名2
```

> 不要乱用类 不要像使用ID一样，每个类都指定一个不同的类名，然后再为每个类编写规则。实际上，继承和上下文选择符能让不同的标签共享样式，从而降低你需要编写和维护的CSS量。

### ID属性

格式：

```
#ID名{声明}
```

**用于页内导航的ID：**（俗称锚点） 例如下面这个链接，其目标是同一页的另一个位置：

```html
<a href="#bio">Biography</a>
```

若只有“#”，那么点击链接会返回页面顶部。如果没有“#”，浏览器就会尝试加载bio目录下的默认页面了。 另外，如果你暂时不知道某个href应该放什么URL，也可以用#作为占位符，但不能把该属性留空。因为href属性值为空的链接的行为跟正常链接不一样。这样团队中其他人将来可以用中间层（比如PHP）变量替换#，以便动态接收来自数据库的URL。

## 属性选择符

### 属性名选择符

格式：

```
标签名[属性名]
```

例如：img\[title]{border:2px solid blue;}，带有title属性的img标签会被选择。

### 属性值选择符

格式：

```
标签名[属性名="属性值"]
```

选择任何带有值为属性值的属性名的标签名。

## 伪类

伪类分为两种：

* UI伪类，会在HTML元素处于某个状态时（比如鼠标指针位于链接上），为该元素应用CSS样式。
* 结构和伪类，会在标记中存在某种结构上的关系时（如某个元素是一组元素中的第一个或最后一个），为相应元素应用CSS样式。

使用方法：冒号“:”表示伪类，两个冒号“::”表示CSS3新增的伪元素。

### UI伪类

1. 链接伪类

* link：默认。
* visited：用户此前点击过这个链接
* hover：鼠标指针正悬停在链接上
* active：链接正在被点击（鼠标在元素上按下，还没有释放） 注意：由于这4个伪类的特指度相同，所以必须按照顺序使用。

1. :focus伪类 表单中的文本字段在用户单击它时会获得焦点，然后用户才能在其中输入字符。
2. :target伪类 例如下面例子，CSS规则：#more\_info:target{background:#eee;}，会在用户单击链接转向ID为more\_info的元素时，为该元素添加浅灰色背景。

```html
<a href="#more_info">More Information</a>
<h2 id="more_info">This is the information you are looking for.<h2>
```

### 结构化伪类

常见的结构化伪类：

1. :first-child和:last-child
2. :nth-child 例如：li:nth-child(3)会选择一组列表项中的每个第三项。 注意：是li！！！不是ul！！！

## 伪元素

常见的伪元素：

1. ::first-letter伪元素 例如：p::first-letter{font-size: 300%;}，可以得到段落首字符放大的效果。
2. ::first-line伪元素 可以选中文本段落的第一行。
3. ::before和::after伪元素 用于在特定定元素前面或后面添加特殊内容。 例如给`<p class="age">25</p>`添加一下标签会得到：Age：25 years.

```css
p.age::before{content:"Age：";}
p.age::after{content:" years.";}
```

## 继承

CSS中的祖先元素会向后代传递一样东西：CSS属性的值。 例如：

```css
body{font-family: helvetica,arial,sans-serif;}
``
文档中的所有元素都会继承这个样式。

CSS中有很多属性可以继承，比如颜色、字体、字号等。也有很多CSS属性不能继承，因为继承这些属性没有意义，比如边框、外边距等。

# 层叠
层叠，就是层叠样式表中的层叠，是一种样式在文档层次中逐层叠加的过程，目的是让浏览器面对某个标签特定属性值的多个来源，确定最终使用哪个值。
## 样式来源
浏览器层叠各个来源样式的顺序：
- 浏览器默认样式表
- 用户样式表（比如某些视障用户，他们可以通过用户样式表，强制浏览器加载的所有网站都以更大的字号等显示内容）
- 作者链接样式表（按照它们链接到页面的先后顺序）
- 作者嵌入样式
- 作者行内样式

**浏览器会按照上述顺序依次检查每个来源的样式，并在有定义的情况下，更新对每个标签属性值的设定。整个更新过程结束后，再将每个标签以最终设定的样式显示出来。**
## 层叠规则
1. 层叠规则一：找到应用给每个元素和属性的所有声明。
浏览器在加载每个页面时，都会据此查到每一条CSS规则，标识出所有收到影响的HTML元素。
2. 层叠规则二：按照顺序和权重排序。
浏览器依次检查5个来源，并设定匹配的属性。如果匹配的属性在下一来源也有定义，则更新该属性的值。
3. 层叠规则三：按特指度排序。
4. 层叠规则四：顺序决定权重。
如果两条规则都影响某元素的同一个属性，而且它们的特指度也相同，则位置最靠下（或后声明）的规则胜出。

## 计算特指度
利用“I-C-E”公式计算：
1. 选择符中有一个ID，就在I的位置上加1；
2. 选择符中有一个类，就在C的位置上加1；
3. 选择符中有一个元素名，就在E的位置上加1；
4. 得到一个三位数。

例如：

选择符|特指度
------|------
p|1
p.largetext|11
p#largetext|101
body p#largetext|102
body p#largetext ul.mylist|113
body p#largetext ul.mylist li|114

注意：0-1-12的特指度仍然比0-2-0低。
# 规则声明
声明包括两部分：属性和值。

值包含三类：
- 文本值：例如bold、hidden等。
- 数字值：绝对值和相对值。
- 颜色值
  - 颜色名：red、blue等。
  - 十六进制颜色：#ff8800等。
  - RGB颜色值：rgb(0,255,0)表示纯绿色。
  - RGB百分比值：100%,0%,0%表示纯红色。
  - HSL（色度，饱和度%，亮度%）
```
