«
前端通关手册:CSS

时间:2022-6   


来自力扣《前端通关手册:CSS》

注释

如何写 CSS 注释,作用是什么?

以/开头,/结束。可阻止其中 CSS 解析,给代码增加说明,提升可读性

如何去除 CSS 注释?

选择器

CSS 中哪些选择器?

选择器 示例
通配符选择器 *
ID选择器 #id
类选择器 .class
元素选择器 div
属性选择器 [attr="value"]
伪类选择器 a:hover
伪元素选择器 a::before

CSS 选择器有哪些组合方式?

① 运算符组合选择器(关系选择器) 选择器 示例
后代选择器 #id a
子代选择器 #id > a
相邻兄弟选择器 #id + a
通用兄弟选择器 #id ~ a
② 属性组合选择器 选择器 示例
标签属性选择器 input[type="button"]
类属性选择器 .class[type="button"]
通配符属性选择器 *[type="button"]
③ 群组选择器 选择器 示例
交集选择器 .class#id, div#id
并集选择器 #id, .class, div

对比伪类,伪元素

伪类和伪元素都是选择器,适用于:

两者区别如下:

伪类

用于选择元素的特定状态。单冒号开头。分为:

选择器 选取范围
:first-child 第一个元素
:last-child 最后一个元素
:first-of-type 第一个指定类型的元素
:last-of-type 最后一个指定类型的元素
选择器 选取范围
:hover 被用户鼠标指向
:checked 被用户选中
选择器 选取范围
:enabled 当前元素可用
:lang(en) 选取语言为英文的元素

伪元素

用于选择元素的 特定部分。双冒号开头。举例:

选择器 选取范围 用途
::first-letter 第1行的第1字母 首字下沉
::first-line 第1行 首行缩进
::before 元素的第一个子元素 配合 content 使用
::after 元素的最后一个子元素 配合 content 使用
::placeholder 表单默认文本 更改提示样式

为兼容早期浏览器,实际使用时,多将双冒号写作单冒号

原因:早期规范没有明确伪元素必须双冒号,当时浏览器多用单冒号,现代浏览器同时兼容单和双冒号

如果不考虑兼容,规范应使用双冒号

CSS 选择器命名规则

大小写字母,数字,连字符(-),下划线(_)以及 ISO 10646 字符编码 U+00A1 及以上

什么是 CSS 无效选择器?

无效选择器,即运行环境无法解析的 CSS 选择器 选择器 示例
命名错误 .1, .-, ..class, ##id
运算符未知 #id >> a, #id ++ a
包含无效选择器的群组选择器 #id, div, ..class
不兼容的选择器 如 IE8 不兼容 CSS3 选择器

运行环境会跳过无效选择器

群组选择器包含无效选择器,该群组选择器都被跳过

开发者工具中,调试 CSS 时,现代浏览器会自动更正错误命名

选择器 更正后
..class .class
div >> p div > p
.1 .\31
#-1 #\31

无效选择器有什么用途?

利用浏览器跳过无效选择器和无效属性的特性

无效选择器,无效属性常用于区分运行环境(多为浏览器),进而:

① 选择器 属性 适配 示例
* IE6 *div { }
*+ IE6-IE7 *+div { }
后缀\9 IE6-IE7 div\9 { }
\0前缀 IE8 \0div { }
后缀\0 IE8-IE10 div\0 { }
② 属性 属性 适配 示例
- IE6 -width
*/+ IE6-IE7 *width +width
_ IE6-IE9 _width
\0 IE8-IE10 width\0
\9 IE6-IE10 width\9
\9\0 IE9-IE10 width\9\0
私有前缀 适配
-webkit- webkit 引擎的 Safari、Blink 引擎的 Chrome、Opera、Edge,EdgeHTML 引擎的 Edge 部分支持
-moz- Gecko 引擎 FireFox
-ms- Trident 引擎的 IE 和 EdgeHTML 引擎的 Edge
-o- Presto 引擎的 Opera

什么是渐进性增强样式?

通过组合 CSS hacks 和私有属性,在较低版本的浏览器中,保持页面布局和基本样式,在高版本浏览器,使用更高级属性或运行环境的私有属性,增强页面样式,提升用户体验。

渐进性增强,是改善 CSS 兼容性,开发框架的设计思想之一,核心是:

示例:

<style>
div { /* All */
-width: expression(this.width > 500 ? '500px' : 'auto'); /* IE6 */
max-width: 500px; /* IE7+ */
color: black; /* IE6 黑 */
}
p + div { /* IE7+ */
color: blue; /* IE7 - IE8 蓝 */
}
:not(p) { /* IE9+ */
color: red; /* IE9+ 红 */
-webkit-font-smoothing: antialiased; /* Webkit浏览器 MacOS 平滑文字 */
-moz-osx-font-smoothing: grayscale; /* 火狐浏览器 MacOS 平滑文字 */
}
</style>
<p>p</p>
<div>div</div>

如何优化选择器,提高性能?

ID > 类 > 类型(标签) > 相邻 > 子代 > 后代 > 通配符 > 属性 > 伪类

示例:

.content * {},会先匹配到所有元素,再向上筛选出父元素 className 为 content 的子元素

根据效率和读取顺序,提高性能的方法如下:

  1. 多使用高效率选择器

工作中,多使用类名,少使用关系、伪类选择器,可读和可维护性也会提高

  1. 减少选择器层级

工作中,选择器层次不建议超过 4 级。用 SASS 或 LESS 时,应避免不必要的嵌套

  1. 高效率选择器在前

工作中,避免使用类、标签选择器限制 ID 选择器,避免使用标签选择器限制类选择器。

低效率选择器在前,通常可以优化。示例 .content #id {} 可直接写成 #id {},div .content 可以给 div 起类名

  1. 避免使用通配符选择器

通配符选择器效率低,且使用 * 的场景,通常有其他解决方案

  1. 多用 继承

示例:

<style>
div * { /* bad case */
font-size: 12px;
}
div { /* good case */
font-size: 12px;
}
</style>

<div>
<p></p>
<p></p>
<p></p>
</div>

继承

什么是继承?

CSS 属性分为非继承属性和 继承属性,继承属性的默认值为父元素的该属性的 计算值,非继承属性和根元素的继承属性的默认值为初始值。

对于非继承属性,可以显示的声明属性值为 inherit,让子元素的属性继承父元素。

常见的继承属性:

容易被误认为继承属性的 非继承属性:

如何重置元素的属性值到初始值?

属性值initial可以将属性设为W3C规范初始值

属性all可以将元素的所有属性重置

在规范之外,浏览器还会为部分元素,如表单元素设置默认样式

属性的值来源于开发者定义,用户配置和浏览器默认

all:initial相当于清空了用户配置和浏览器默认样式

工作中,我们更希望重置到默认样式,而不是清空它们

all:revert属性还原。可以将子元素的属性重置按如下规则重置:

<style>
button {
color: yellow;
border: 1px solid red;
background-color: red;
}
button:nth-of-type(2) {
all: initial; /* 清空按钮的样式 */
color: blue;
}
button:last-of-type {
all: revert; /* 保留按钮的默认样式 */
color: blue;
}
</style>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>

优先级

为什么要定义 CSS 优先级?

同一元素可能会被多个 CSS 选择器选中。

选择器中可能包含对相同属性的不同设置值。

需要定义优先级规则,只让优先级最高的选择器的设置值生效。

CSS 优先级规则是什么?

选择器与元素的相关度越高,优先级越高,具体规则如下:

加载 CSS 是否会阻塞页面渲染?

HTML是超文本标记语言,\<元素名>作起始标签,\</元素名>结束标签或唯一标签

浏览器将元素和文本作为节点,将父元素作为父节点,将 HTML 转为 DOM 树。这个过程与 CSS 无关

CSS 会被转为CSS树,并与 DOM 树结合成 Render 树等待渲染

如果 CSS 下载很慢,那么 CSS 解析会被阻塞,后续的渲染也无法进行

通过媒体查询,可以设置link引用的 CSS 不阻塞渲染,但仍会下载

所以,通常情况下:

浏览器是如何解析和渲染 CSS 的?

浏览器解析和渲染 CSS 的步骤:

将 CSS 字符串转换为包括选择器、属性名、属性值的数据结构,长度单位被转换为像素,关键字被转换为具体值,需要计算的函数转为具体值

相同元素相同属性的最终值基本由书写顺序,按先后决定,此外:

ID > 类 > 类型(标签) > 相邻 > 子代 > 后代 > 通配符 > 属性 > 伪类

根据position不为static等属性或弹性布局中的子元素等情况创建层叠上下文。根据z-index决定层的叠加顺序

深度优先遍历之前解析 HTML 得到的 Dom Tree,匹配解析 CSS 得到的 CSSOM

计算元素的位置、宽高,将可见元素的内容和样式放入 Render Tree

分层按照流式布局(块、内联、定位、浮动)、弹性布局、网格布局或表格布局等布置元素,按照尽可能多地展示内容的原则,处理溢出

分层绘制颜色、边框、背景、阴影

将不同图层分格渲染出位图,可交由 GPU 线程处理

处理图层的透明度opactiy,和变形transform等

将所有图层合到一起

JS 更改 CSS 属性,CSS 动画以及伪类(如hover),内容变更等,可能会引起浏览器重新布局、绘制或者合成

对比获取 CSS 样式的接口

什么是重排和重绘,更改哪些属性会触发重排和重绘,如何避免?

什么是重排和重绘?

当DOM的样式或内容会被修改时,将触发重新渲染。除了属性值计算、单位换算外,渲染主要分为三个步骤:

重新渲染一般有三种执行路径:

更改哪些属性会触发重排和重绘?

引起重排的属性,即布局类属性,包括:

类型 属性名
盒模型 displaypaddingmarginwidthheightmin-heightmax-heightborderborder-width
定位和浮动 positiontopbottomleftrightfloatclear
文字及溢出 font-familyfont-sizefont-weightline-heighttext-alignvertical-alignwhite-spaceoverflowoverflow-y

引起重绘的属性,即绘制类属性,包括:

类型 属性名
颜色 color
边框 border-colorborder-styleborder-radius
背景 backgroundbackground-imagebackground-positionbackground-repeatbackground-size
轮廓 outlineoutline-coloroutline-styleoutline-width
可见性 visibility
文字方向 text-decoration
发光 box-shadow

如何避免重排和重绘?

类型 属性名
变形 transform
透明度 opacity