CSS 基础与实用特性大全

系统的 CSS 基础知识和工程化内容。

简介

CSS(Cascading Style Sheets),层叠样式表。用于描述网页呈现的语言,包括颜色、布局和字体。 独立于 HTML,可以与任何基于 XML 的标记语言一起使用。

历史

CSS1(废弃),CSS2 1996~1999 规范基础样式;CSS3 2001 分模块发布如背景和边框、盒子模型等。

history

工作原理

和 HTML 一样,CSS 内容被加载到网页中后会被解析为 CSSOM,会和 DOM 结合成渲染树,浏览器根据这颗渲染树进行布局、绘制和合成,最终就成了我们看到的网页。

work

使用方式

一般有四种使用方式

style 元素

<style type="text/css">
  ...;
</style>

link 标签。需要指明 rel,rel 指的是 relation(关系),常用的取值还有 perfetch

<link rel="stylesheet" type="text/css" href="basic.css" />

行内样式

<p style="color: gray">text</p>

@import 指令。引入的 sheet.css 是相对于所在 css 的地址,将其他 css 文件的内容读入该位置

@import url(sheet.css);

层叠

若要用一种最简单的方式解释层叠,我觉得就是:决定最终显示效果的规则。

选择器

  • 元素选择器
  • 类选择器
  • ID 选择器
  • 属性选择器
  • 伪元素选择器
  • 通用选择器

属性选择器

  • 简单属性:只需要拥有该属性,对应的样式就会生效
a[href] {
  color: red;
}
a[href][title] {
  color: blue;
}
  • 精准属性值:属性值必须匹配
img[type="fat cat"] { width: 100px } <img type="fat cat" alt="Garfield" />
  • 部分属性值:属性值按照规则匹配
    attr

组选择器

多个选择器可以通过不同的符号进行组合,以实现不同的选择效果

分组选择器

, - 选择器列表,将不同选择器组合在一起,选择所有能被列表中任意一个选择器选中的节点
示例:div, span 会同时匹配 <span><div>

组合器

(空格)- 后代组合器,选择所有指定的后代元素
示例:A B
> - 直接子代组合器,选择所有指定的直接子代节点
示例:A > B
~ - 一般兄弟组合器
示例:A ~ B
+ - 紧邻兄弟选择器
示例:A + B

连写

多个选择器连续书写
select

特指度

特指度由四个权重组成,为 a-b-c-d。这四个权重是相互独立的,没有进位一说。不同选择器有不同的权重、合起来就是特指度。需要特别记住的就是 0 特指度比没有特指度更优,后面会举例说明。

特指度a-b-c-d的规则

  • a = 样式声明来自行内属性 ? 1 : 0
  • b = 选择器中 ID 属性的数量
  • c = 选择器中其他属性和伪类的数量
  • d = 选择器中元素名和伪元素的数量
  • 继承和连接符没有特指度,通用选择器特指度为 0

很生动的一张图:
weight

通过认真阅读图片,可以得知以下结论

  • 通用选择器不影响特指度
  • 各个权重互独立计算,没有进位计算
  • 同级选择器特指度都只增加 1
  • !important 重要声明始终覆盖选择器声明

继承

不少属性是可以通过父元素继承的,例如 color,可以通过查看 mdn 的文档的 inherited 属性看看属性是否是可以继承的,当然你也可以手动修改该属性。
w3c-inherited

但是继承的样式是没有特指度的,所以 0 特指度会胜过无特指度,观察下面例子:

<style>
  * {
    color: grey;
  }
  .title {
    color: red;
  }
</style>
<div class="”title”">
  Title
  <p>sub title</p>
</div>

最终结果是,可以看到在 p 中,sub title 的颜色是 0 特指度的灰色而不是继承的红色
inherited

层叠计算

  • 权重
    !important > 行内样式 > ID > 其他属性(Class 等)、伪类 > 元素、伪元素

  • 来源(开发者、读者、用户代理)
    读者!important > 开发者!important > 开发者 > 读者 > 用户代理

  • 特指度
    a-b-c-d 特指度高的生效

  • 前后位置
    排在后面的规则生效

读者指的是网站的用户通过浏览器的接口修改的样式。读者样式一个最直接的例子就是在 chrome 浏览器的外观设置中的字体,其中有有默认字号和字号两个选项
reader

读者样式样式就是默认字号,网页中的文字默认的大小 我们日常开发中 使用 font-size 直接就覆盖了。
而最小字号就是读者样式 + !important ,你会发现你的 font-size 无论设置多小,始终都不会小于 12px,就是因为设置中的这个用户选项限制的。

布局方式

视觉格式化基础

视觉格式化的内容非常多,这里只列举了三个常用的概念、知识点

  • 视觉格式化模型:使文档显示时的一套计算规则,根据盒子模型将文档中的元素转换为盒子。
  • 盒子模型:内容、内边距、边框、外边距
  • 纵向格式化:计算容纳块的高度,同一 BFC 的块级元素之间会折叠纵向外边距

box

块级格式化上下文

Block Formatting Context(BFC),块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
创建格式化上下文

  • 根元素(html)
  • 浮动元素( float 值不为 none)
  • 绝对定位元素(position 为 absolute 或 fixed)
  • 行内块元素(display 为 inline-block)或 flow-root
  • overflow 不为 visible

清除浮动

典型的浮动流就是将浮动元素从他的普通流位置中剔除,放到行的开始。这么做的问题就是原本的容器不会再考虑浮动元素的高度,会有高度塌陷的问题,后面如果有别的块级元素的话,会继续填充在浮动流的空白处。
float
用得最多的方法就是 clear: both,但是在 p 有兄弟元素想 float 成侧边栏时就不好使了,此时就可以将 float 用 BFC 包装起来,不是同一个 BFC 的元素就不会互相影响了
float-bfc

其他格式化上下文

  • IFC(Inline Formatting Context,内联格式化上下文),块容器盒子在不只包含块级盒子的情况下创建 IFC

  • GFC(GridLayout Formatting Context,网格布局格式化上下文)display: grid

  • FFC(Flex Formatting Context,弹性格式化上下文),display: flex 等 flex 相关值

常用布局

布局 说明 场景
float 布局 兼容性好。浮动元素会一个跟着一个,以实现横向布局。不推荐。 导航栏、圣杯布局等行布局
table 布局 兼容性好。同一行的元素等高,同一列的元素等宽。不推荐。 等高布局、代码差异(react-diff-viewer)
flex 布局 轻松控制同一方向各元素的位置。 通过结合垂直和水平方向的布局,实现各种响应式布局
多列布局 column-count 列数 类报纸的多列文本显示。
层模型 position 为 relative、absolute、fixed、stickily 为所欲为、吸顶
grid 布局 二维的响应式布局。 未知

工程化

首先我们需要明确的是工程化到底要解决的问题是什么: 多人协同时 CSS 的可维护性。
推荐 facebook 工程师的一次演讲:React: CSS in JS

我这边仅列四条认为比较重要的问题:

  • 命名冲突
  • 冗余代码
  • 压缩
  • 变量

命名冲突

  • 规范命名:OOCSS,BEM,SMACSS
  • Web Components
  • <style scope></style>
    在 js 中会通过函数作用域起到局部命名空间的作用,在 css 中需要使用 webcomponents 才可以有局部的命名空间。规范命名可以说是最初的模块化 Bootstrap antd 等都在用。style scope 其实是有官方提案的,但是浏览器的支持程度惨不忍睹。vue 的 scope 是类似 css modules 的实现。

变量

CSS 已经原生支持,github 和 tailwindcss 都在用,放心使用
css-var
使用示例:
css-var-sample

PostCSS

在 node 生态下,聊工程化就离不开 postcss,他是专门用来处理的 css 的。。目前热门的 css 工具基本上都是基于他来实现的,例如 css-loader、cssnano、autoprefixer。
他核心的作用就是把 css 转成抽象语法树:
css-ast

基于他实现的工具,理论上可以解决目前所有问题
postcss-tools

构建工具

基于 webpack 等构建工具,会有很多插件和工具库可以选择,此处列出常用的四种

  • css modules:进行一定配置,最后自动生成带有哈希值的 class name
    css-modules
  • CSS in JS(React):styled-components、emotion 等
  • scope(Vue):vue cli 集成的 css modules 方案
  • 行内样式

其他

CSS 中还有很多重要的组成部分,例如字体、单位、阴影和动画等,推荐阅读 CSS 权威指南一次性爽够。若对新兴的 CSS 技巧感兴趣的话可以阅读 CSS 一姐 Lea Verou 的 css 揭秘和 more css 系列的演讲。

other