# 4.1 语言基础

## \~\~\~\~\~\~\~ at-rules 相关 \~\~\~\~\~\~

<details>

<summary>link 和 @import 的区别</summary>

1. 类别不同
   * `link` 是 HTML 标签，属于元数据，用来加载外部资源，包括但不限于样式表
   * @import 是 CSS at-rules，用来导入样式表
2. 加载时机
   * 在加载页面的时候，link 就会被同时加载
   * @import 会等到引用它的 CSS 文件被加载完，才会被加载
3. 浏览器兼容性
   * `link` 无兼容性问题（老牌标签）
   * @import 需 IE5+
4. 优先级：`link` 高于 `@import`

</details>

<details>

<summary><code>calc</code>, <code>@support</code>, <code>@media</code> 的含义和用法</summary>

* `calc()` 用于动态计算长度，还支持 + - \* / 等运算
* `@support` 用于特性检测，即是否支持某个 CSS 属性
* `@media` 媒体查询，可以针对不同的媒体类型定义不同的样式

</details>

## \~\~\~\~\~\~\~\~\~ 选择器 \~\~\~\~\~\~\~\~\~

<details>

<summary>浏览器是如何解析 CSS 选择器的？</summary>

从右至左解析的。

之所以没选择从左向右的匹配，主要还是考虑到性能，因为如果发现了不符合规则，就需要回溯。

而从右至左的匹配，先找到所有的最右节点，然后向上寻找其父节点，直到找到根元素或成功匹配该规则，就结束这个分支的遍历。

在 CSS 解析完毕之后，会将解析的结果和 DOM Tree 的内容一起，最终建立一棵 Render Tree，然后用它来进行渲染。

</details>

<details>

<summary>选择器的优先级</summary>

1. 选择器优先级：#id > .class > tagName
   * 属性选择器、通配符
   * 伪选择器：伪类、伪元素
   * 优先级：属性选择器 = 伪类选择器
2. 带有 `!important` 标记的属性，优先级最高
3. 来源优先级：内联 > 内部 > 外部 > 浏览器用户自定义样式 > 浏览器默认样式

\======

style 权重若为 1000, 则 id 选择器权重是 100, class 是 10, div 是 1

TODO.实际的权重是多少？记得是 2 的多少次方

</details>

## \~\~\~\~\~\~\~\~ 布局和定位 \~\~\~\~\~\~\~

<details>

<summary>盒模型</summary>

盒模型，就是用来描述页面上元素的矩形区域。

![](https://2598460105-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGNkDWo1TzHEOBRUxCRfy%2Fuploads%2FsCU5Srvmm5qvNenUdm9A%2Fimage.png?alt=media\&token=8204ec82-35db-4d28-aaeb-025fdbc1f24c)

CSS 中的盒模型有两种：

* 标准的 W3C 盒模型
* IE 盒模型

它们的区别在于 width 和 height 属性的包含范围不同。

* 标签盒模型：content
* IE 盒模型：content+padding+border

CSS3 引入了 `box-sizing` 属性，它有三个值：

* `content-box` 即标准盒模型
* `padding-box`
* `border-box` IE盒模型

</details>

<details>

<summary>BFC</summary>

BFC，Block Formatting Context，块级格式化上下文。

BFC 是一个独立的渲染区域，规定了内部如何布局，且区域里的子元素不会影响到外面元素。

其中，比较重要的布局规则有：

* box 垂直方向的 margin 不重叠
* 计算 BFC 的高度时，浮动元素也会参与计算
* BFC 区域不会与 float box 重叠

常见用途：防止 margin 重叠、清除浮动

触发 BFC 规则的有：

1. 根元素
2. overflow 不为 visible 的元素
3. float 不为 none 的元素
4. position 为 fixed 和 absolute 的元素
5. display 为 inline-block, table-cell, table-caption, flex, inline-flex 的元素

</details>

<details>

<summary>overflow 的原理</summary>

要讲清楚这个解决方案的原理，首先需要了解块格式化上下文。

A block formatting context is a part of a visual CSS rendering of a Web page. It is the region in which the layout of block boxes occurs and in which floats interact with each other.

翻译：块格式化上下文是 CSS 可视化渲染的一部分，它是发生 block boxes 布局和 floats 交互的区域。

当元素设置了 overflow 样式，且值不是 visible 时，该元素就构建了一个 BFC，BFC 在计算高度时，内部浮动元素的高度也要计算在内，也就是说 BFC 区域内只有一个浮动元素，BFC 的高度也不会发生塌缩，所以达到了清除浮动的目的。

TODO. 感觉答非所问...

</details>

<details>

<summary>外边距折叠</summary>

在常规文档流中，多个相邻（兄弟或父子）块元素的垂直方向 marigin 会重叠。

折叠的结果是：当两个相邻的外边距...

* 都是正数时，取两者间的较大值
* 都是负数时，取绝对值的较大值
* 一正一负时，取之和

</details>

<details>

<summary>block, inline, inline-block 的区别</summary>

1. block 是块级元素
   * 单独占一行，即便 width 不足一行，也会独占一行
   * 能设置 width, height，且 margin 和 padding 的水平垂直方向都有效
2. inline 是行内元素
   * 多个相邻行内元素会排列在同一行，直到一行放不下才会新换一行
   * 其 width 随内容而变化
   * 设置 width 和 height 无效，padding 水平垂直方向都有效，margin 只水平方向有效
3. inline-block 是行内块级元素
   * 既具有 block 的宽高特性，又具有 inline 的同行特性
   * 能设置 width, height，且 margin 和 padding 的水平垂直方向都有效

TODO. 行内替换元素，是可以设置宽高的（待确认）。比如 `<img>` 默认是 inline，但可以设置 width, height

</details>

<details>

<summary>display</summary>

主要取值有 none, block, inline-block, inline, flex 等。

详见 <https://developer.mozilla.org/zh-CN/docs/Web/CSS/display>

</details>

<details>

<summary>position 属性</summary>

1. `static` 默认定位（默认值）
   * 元素出现在正常的文档流中（会忽略 top, bottom, left, right 或 z-index）
2. `relative` 相对定位
   * 是相对于它原本的位置
   * 不脱离文档流：所以相对移动了之后，自己原来的位置还在，且不会顶掉（只会覆盖）别人
3. `absolute` 绝对定位
   * 是相对于离它最近的已定位父元素，如果没有那就相对于 `<html>`
   * 会脱离正常的文档流：所以原来的位置就没了
4. `fixed` 固定定位
   * 是相对于浏览器窗口，所以即使滚动窗口它也不会动
   * 会脱离正常的文档流：所以原来的位置也就没了，即不占据空间
5. `sticky` 粘性定位
   * 先按正常的文档流来定位
   * 然后相对定位：相对于流中的 flow root（BFC）和 containing block（最近的块级祖先元素）定位
   * 最后超过特定阈值之后，固定定位
6. `inherit` 从父元素那里继承

</details>

<details>

<summary>z-index</summary>

设置元素的堆叠顺序，它只在定位元素上生效。

拥有更好堆叠顺序的元素会处于较低顺序元素之前， z-index 可以为负， 可以理解为：z-index 设置一个定位元素的 z 轴位置。正数离用户越近，负数离用户越远。

可取的值：

* auto，默认， 堆叠顺序与父元素相等，
* number，
* inherit，从父元素继承 z-index 属性的值

</details>

<details>

<summary>float 元素的 display 是什么？</summary>

`diplay: block`

</details>

<details>

<summary>清除浮动</summary>

1. clear 属性：
   * 对浮动元素后的元素设置
     * 用空标签 `<div class="clear"></div>`（略冗余）
     * 给跟在它后面的元素设置（不优雅）
   * 对浮动元素的容器设置
     * 通常用 `::after`
2. overflow 属性：对浮动元素的容器设置，触发 BFC
   * 通常 `overflow: hidden` 或 `overflow: auto`
   * IE6 是触发 hasLayout，比如给父设置 `zoom: 1`

代码详见 <https://didyouknow.top/card/63ad91e19db833a2d3ba971b>

</details>

<details>

<summary>flex 布局</summary>

Flex，Flexible Box 的缩写，意为"弹性布局"，用来为盒模型提供最大的灵活性。

布局的传统解决方案，基于盒模型，依赖 display 属性 + position 属性 + float 属性。 它对于那些特殊布局非常不方便（比如垂直居中）

1. 容器相关属性
2. 元素相关属性

</details>

<details>

<summary>grid 布局</summary>

</details>

## \~\~\~\~\~\~\~\~\~\~ 属性 \~\~\~\~\~\~\~\~\~

<details>

<summary>文本溢出</summary>

`text-overflow` 属性的值有：

* `clip`（默认值）按内容区域的大小截，所以截断可能发生在字符中间
* `ellipsis` 用 ... 来表示被裁掉的文本
* `<string>` 用给定的字符串来表示被裁掉的文本

</details>

<details>

<summary>height 和 line-height 的区别</summary>

* height 一般是指容器的整体高度
* line-height 一般是指布局里一段文字上下行之间的高度，是针对字体来设置的

</details>

<details>

<summary><code>rgba()</code> 和 <code>opacity</code> 区别</summary>

都能实现透明效果，区别：

* `rgba()` 只作用于元素的颜色 `<color>`，且子元素不会被继承
* `opacity` 可作用于整个元素，且子元素都会继承

</details>

<details>

<summary><code>1rem</code>, <code>1em</code>, <code>1vh</code>, <code>1px</code> 的含义</summary>

都是长度单位，除了 px 其余都是相对单位。

* 绝对单位
  1. `px`：pixel 像素，是相对于显示器屏幕的分辨率而言的
* 相对单位
  1. `rem`：相对根元素的字体大小
  2. `em`
     * 若是 `font-size` 属性，是相对父元素的字体大小
     * 若是其它属性，则是相对于当前元素的 `font-size`
  3. `vm`, `vh`：相对视口，单位是 1%
     * 通常，处理宽度，用 %
     * 处理高度，用 vh

</details>

<details>

<summary>响应式布局</summary>

详见：响应式布局的常用解决方案对比&#x20;

<https://github.com/forthealllight/blog/issues/13>

</details>

<details>

<summary>calc()</summary>

calc 动态计算长度值，任何长度值都可以使用 calc() 函数计算。

注意：运算符前后都需要保留一个空格，例如 `width: calc(100% - 10px)`

</details>

## \~\~\~\~\~\~\~\~\~\~ 动画 \~\~\~\~\~\~\~\~\~

<details>

<summary>CSS3 动画和 JS 动画的差异</summary>

渲染线程分为 main thread 和 compositor thread。

如果是用 CSS 动画改变了 transform 或 opacity，是不会触发 layout 或者 paint 的，只需要 compositor trhead 就可以完成，而 JS 动画则是在 main thread 执行，然后触发 compositor thread 进行下一步操作。

区别:

* 实现/重构难度：CSS3 更简单更容易
  * 对帧速表现不好的低版本浏览器，CSS3 可以做到自然降级
* 浏览器兼容性：CSS < JS
* 功能涵盖面：CSS < JS

</details>

<details>

<summary>transition 和 animation 的区别</summary>

大部分属性都是相同的，它们都是随时间改变元素的属性值&#x20;

transition <mark style="background-color:blue;">vs</mark> animation：

1. 触发属性的改变：需要触发一个事件 <mark style="background-color:blue;">vs</mark> 不需要事件,会随时间
2. 帧数：2 帧，从 from .... to <mark style="background-color:blue;">vs</mark> 可以一帧一帧的

</details>

<details>

<summary>CSS3 的动画如何实现？</summary>

1. 用 `animation` 和 `@keyframes` 创建动画序列
   * 可以设置动画时间、时长 以及其它动画细节
   * keyframes 定义动画序列
2. `transition` 也可实现动画，是属性的过渡效果
   * 是元素的一个或多个属性发生变化时，产生的过渡效果

</details>

## \~\~\~\~\~\~\~\~\~ 实际应用 \~\~\~\~\~\~\~

<details>

<summary>隐藏元素的方法</summary>

1. `display: none` 元素不可见，会改变页面的\~\~<mark style="color:red;">布局</mark>\~\~（从 DOM 树上移除了）
2. `visibility: hidden` 只是简单的隐藏，不改变<mark style="color:red;">布局</mark>（元素依然占位）
3. `opacity: 0` 让元素完全透明，不改变<mark style="color:red;">布局</mark>，且依然会响应<mark style="color:red;">事件</mark>
4. `position: absolute` 配合 `left` 负值，将元素定位在可视区域之外
5. `scale(0)`, `skrew()` 通过 transform 将元素变形到不可见，原来的位置依然保留
6. `z-index` 把元素放底下

</details>

<details>

<summary>如何画一条 0.5px 的直线？</summary>

1. `transform: scale(0.5)`
2. `border-image`
3. meta viewport

```css
height: 1px;
transform: scale(0.5);
```

```html
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
```

</details>

<details>

<summary>垂直水平居中</summary>

1. flex
   1. 可以给父设置左右居中
   2. 也可以给子设置 margin: auto
2. 定位+移中心
   * 先把左上角移到中心位置（绝对定位）
   * 再把元素的中心移到中心位置
     1. 可以 translate()，更灵活，直接 -50%
     2. 也可以 margin 负值，需要设绝对值（元素宽高的一半）
3. 定位+margin:auto
   * 父元素相对定位
   * 子元素绝对定位，且必须设置 width, height
     * top, bottom 均 0，margin 垂直方向 auto（垂直居中）
     * left, right 均 0，margin 水平方向 auto（水平居中）
4. table-cell
5. 正常文档流，用 margin 撑开
   * 水平居中 margin: 0 auto;
   * 垂直居中
     * 可以 `margin-top: calc( 50vh - 100px )`
     * 也可以先 50vh 再 translate 移动
6. 单行文本
   * line-height = height
   * text-align: center

代码详见：<https://didyouknow.top/card/63ad609a9db833a2d3ba9719>

</details>

<details>

<summary>三栏布局</summary>

两列定宽一列自适应，两侧定宽中间自适应

1. flex
2. grid
3. float
4. absolute
5. table

代码详见 <https://didyouknow.top/card/63ad5a6f9db833a2d3ba9716>

</details>

<details>

<summary>多行元素的文本省略号</summary>

TODO. 为什么不能设置 height ?

代码详见 <https://didyouknow.top/card/63ad6e099db833a2d3ba971a>

</details>

<details>

<summary>CSS sprites</summary>

CSS sprites 是把网页中的很多图片整合到一张图片文件中。

显示的时候，利用 CSS 的 `background-position` 属性定位到想要图片的准确位置。

好处是：合并了多个小的 HTTP 请求，可以为大型网站节约带宽，还能提高用户体验。

</details>

<details>

<summary>画一个三角形？</summary>

用 `border`

</details>

<details>

<summary>ios 手机浏览器字体齿轮</summary>

```css
-webkit-font-smoothing: none:
-webkit-font-smoothing: antialiased | subpixel-antialiased | default:
```

</details>

<details>

<summary>背景色，都会填充哪些区域？</summary>

background-color 会填充元素的 content 区域

</details>

<details>

<summary>父子 div 的 position 都是 absolute，子的 top 是相对于父的哪个位置定位的？</summary>

父盒模型的 content 区域

</details>

<details>

<summary>display:table 和本身 table 的区别</summary>

* display:table 能让一个 html 元素和它的子节点像 table 元素一样，使用基于表格的 css 布局
* table 的局部规则：table 必须在页面完全加载后才显示，而 div 则是逐行显示
* table 的嵌套性太多，没有 div 简洁

TODO.待查阅

</details>

## \~\~\~\~\~\~\~\~\~\~ 其它 \~\~\~\~\~\~\~\~\~

<details>

<summary>重绘、重排</summary>

整个过程：xxx → xxx → xxx → 布局 → 绘制

1. 重排：改变了某个 DOM 元素的几何属性，导致浏览器重新构造渲染树（重新计算该元素以及其它元素的）
   * &#x20;引起重排的原因，比如：
     * 添加或者删除可见的 DOM 元素
     * 浏览器窗口大小发生改变
     * 改变元素的尺寸或位置
2. 重绘：浏览器将更新的部分重新绘制到屏幕上
   * 引起重绘的原因，比如：
   * 改变 color, background-color, opacity 等属性

重排一定导致重绘，重绘不一定导致重排。

减少重绘重排的方法有：

* 不在布局信息改变时做 DOM 查询
* 使用 csstext, className 一次性改变属性
* 使用 fragment 对于多次重排的元素，比如说动画
* 使用绝对定位脱离文档流，使其不影响其他元素

TODO.让文档脱离正常文档流的方法

P2.81

</details>

<details>

<summary>CSS 预处理器</summary>

less，sass 等

</details>

<details>

<summary>CSS 布局</summary>

1. 圣杯布局
   * 布局从上到下分为 header, container, footer
   * container 部分定为三栏布局
   * 缺陷在于 center 是在 container 的 padding 中的，因此宽度小的时候会出现混乱
2. 双飞翼布局
   * 给 center 部分包裹了一个 main，通过设置 margin 主动地把页面撑开
3. 绝对定位布局
4. ~~表格布局~~：使三栏的高度统一
5. flex 布局
6. grid 布局

</details>

<details>

<summary>CSS3 新特性</summary>

1. 布局：新增了 flex
2. 盒模型：新增了 box-sizing
3. 选择器：新增了比如 first-of-type, nth-child 等
4. 动画：增加了 animation, 2d 变换, 3d 变换等
5. 媒体查询
6. 其它
   * 字体：允许嵌入字体和设置字体阴影
   * 边框：border-radius，box-shadow 等
   * 颜色：增加了 opacity, rbga 等
   * 背景：background-size， background-origin 等

详见 <https://www.cnblogs.com/xkweb/p/5862612.html>

</details>
