CSS 学习指南

# CSS 简介

# 什么是 CSS

层叠样式表 (Cascading Style Sheets,缩写为 CSS),是一种 样式表 语言,用来描述 HTML 或 XML(包括如 SVG、MathML、XHTML 之类的 XML 分支语言)文档的呈现。CSS 描述了在屏幕、纸质、音频等其它媒体上的元素应该如何被渲染的问题。

大白话:CSS 是用来让网页变好看的。

CSS 本身只是一些规则的描述,具体的渲染是依靠浏览器的渲染引擎完成的。
它不是图灵完备的通用编程语言,所以 CSS 肯定有它的局限性。

而且,虽然 CSS 现在也有编程接口的草案,提高了一点它的能力,但也不完善。
Is Houdini ready yet‽ (想想当你要兼容 IE 或者小程序…)

所以,不是所有的设计稿的效果都能通过 CSS 直接或方便地实现。
或许需要借助 JS 或其他工具手动进行。

不过,仅仅要实现“让 HTML 页面变好看”这件事,CSS 做得还算不错。

# 什么是 W3C

万维网联盟(英语:World Wide Web Consortium,縮寫 W3C),又称 W3C 理事会,是万维网的主要国际标准组织。

大白话:CSS 是他们修订的标准之一。

# 为什么要学习 CSS

  • 当你要让 HTML 页面变好看

HTML 一样,现代前端开发可以直接利用现成的框架和组件,
但如果涉及定制开发,或当我们谈到框架组件的实现,归根结底总还是要接触 CSS。

# 学习 CSS

CSS 的知识体系很大,大量的规则细节需要在实践中不断踩坑。

# 概览

通过快速浏览 W3C 标准文档和 MDN,了解 CSS 的大致样貌。并尝试自己练习。

  • 耗时:
    • 从入门到了解 CSS 的基本知识体系,10~30 小时
    • 通过刻意训练和实战熟悉 CSS 的很多效果,20~60 小时
    • 在实际工作中踩坑各种细节,……
  • 难点:
    • CSS 本身的表达能力不足,想提高生产力还需要学习 Sass/Less 等额外工具(基本使用其实没多难)
    • 写出漂亮的页面,完美还原设计稿
    • 响应式设计
    • 如何写出可维护的 CSS 代码
  • 工具:

# 学习路线

  • 前置学习
  • 学习 CSS
    • 快速阅读文档
      • 翻阅 CSS 标准文档
      • 翻阅 MDN 中 CSS 的文档,查看例子和实际效果
      • 建立自己的 CSS 知识体系
    • 动手玩,亲自尝试各种样式效果
    • 学习 Sass/Less 等 CSS 预编译工具
  • 实战
    • 你可以直接开发一个 Web 应用,随用随查,通过完成实际的需求来熟悉 CSS。
  • 进阶
    • 了解和处理不同浏览器的兼容性问题
    • 尝试实现酷炫的效果,比如曲线裁切、叠加混合、水波纹、动画
    • CSS houdini 编程
    • 了解视觉格式化模型

# 资料

# 自学教材

# 入门

通过 MDN 的教程学习 CSS 基本使用。

# 视频

  • CSS Crash Course For Absolute Beginners:85 分钟,CSS 从入门到了解
    • 2:02 - 什么是 CSS,准备开发基本环境
    • 5:33 - 添加 CSS 的三种方式:行内(元素的 style 属性),内嵌(<style> 标签),外链(<link> 标签引入外部 .css 文件)。以 color 为例进行演示
    • 11:14 - 选择器,基本语法结构
    • 13:31 - 颜色(color)
    • 15:46 - 文字样式
    • 20:00 - class 和 id
    • 24:53 - 盒子模型
    • 33:00 - 文字样式、列表(li)
    • 39:10 - 链接(a)、图片(img)
    • 44:20 - 表单(form)样式
    • 51:20 - 浮动(float)
    • 57:10 - 定位(position)
    • 63:41 - 背景(background)
    • 66:20 - 伪类
    • 68:55 - 通过一个简单的页面 Demo 练习 CSS,支持响应式。

# 布局

以及几种来自新标准的布局方案:

# CSS 框架、库

如果你打开搜索引擎搜索 css frameworks,你会发现相比预处理器,CSS 的框架要多得多。

现在的前端开发可以使用组件框架,直接内置了很多风格统一的组件,
比如 Ant DesignElement UI
又例如 Material Design 有 React 组件版本的 MATERIAL-UI

如果不使用第三方组件库而是自行开发,也可以选择 CSS 框架。
(我近几年接触 CSS 不太多,这里就简单列举几个我了解过的高星 CSS 框架。)

  • 布局和组件,配合它们提供的 JS 文件还能实现交互效果。
  • 2D 动画,提供元素的简单动画效果
  • 其他

# 现代 CSS 技术

正如 The State of CSS 所描绘的那样,CSS 的世界也像 JS 那样在爆发式发展,各种新技术的使用率在不断上升。例如 React SSR 框架 Next.js,就同时集成并运用了 css-modules、styled-jsx、Sass、PostCSS 多种 CSS 技术。

# CSS 预处理器

CSS 预处理器是一个能让你通过预处理器自己独有的语法来生成 CSS 的程序。

CSS 预处理器是近年来前端开发的标配,
不同工具各有差别,但它们的目的都是提高编写样式的效率,
有一些公共的主要特性:

  • 嵌套结构:你可以用类似 HTML 同样的结构编写样式,使代码具有更高的可读性
  • 变量系统:满足 DIY 原则,提高代码可维护性
  • 预处理:比如 PostCSS 可以自动为属性添加 prefixes

主流的预处理器有以下这些,通常会选择 Sass/Less + PostCSS 搭配使用:

# CSS 方法论

这些理论不属于 CSS 规范,它们是实践中产生的方法论,
目的都是为了提升大型项目中,样式代码的可维护性和可扩展性。

# CSS in JS

现代 Web 框架可以通过 JS 编写 HTML 和业务逻辑,
同样的,借助额外的工具,还可以用 JS 来编写 CSS。
(当然,不用这些高科技,直接编写 CSS 或使用预处理器的方案也很常见,胜在简单方便。)

其实 CSS in JS 技术主要是 React 技术圈在使用。
像 Vue 有 单文件组件 的开发方案,Angular 也有标准的 文件结构
唯独 React 只解决了 JS 和 HTML 的问题,没怎么照顾到 CSS,产生了技术缺口。

一些 CSS in JS 的库:

  • styled-components:通过 JS 函数生成绑定样式的 React 组件。
  • css-modules:可模块化的 CSS,可以用于组件的样式计算和切换。
  • styled-jsx:在 JSX 中写样式,使 React 也能单文件编写组件。

# 工具和网站

  • CSS-Tricks:CSS 实践技巧和前沿资讯
  • CODEPEN:平台网站,包含大量酷炫的设计(其实这个站点不完全是关于 CSS,还包括了 JS,只是偏设计的作品比较多)

# 动画和性能

鄙人前几年做过一段时间 CSS 动画开发,踩过一些坑。
关于 CSS 的渲染性能和动画性能。要点是如何选择合适的属性。
(比如避免重布局、利用硬件加速等等)

不过说到动画,纯 CSS 有它的局限性(比如复杂场景下的性能)。
而且如果要支持交互或动态动画,一般还需要额外的编程工具。
进一步深入,甚至可能会涉及游戏开发和图形学的知识。
这里我没有太多的经验。贴几个略微使用和了解过的工具,权当开眼。

# 扩展阅读

# CSS 知识体系

通过阅读标准文档,建立 CSS 知识体系

根据我自己的开发经验,以及交叉对比不同的资料,我粗略总结出了一套 CSS 知识体系。
基于这套体系,快速阅读官方文档和示例,就能够系统地了解 CSS 的整体概念。
在实际的开发任务中,随用随查(如字体、边框等细节样式),即可满足开发需求。

以下列表中的所有链接都来自:

(还有什么比标准文档更权威呢?)

# CSS 典型代码

# 元素样式

#demo-element {
  background-color: #1766aa;
  margin: 20px;
  border: 5px solid #333;
  width: 150px;
  height: 150px;
  border-radius: 50%;
}

# 动画

animation - MDN

#demo-animation {
  animation: 1s ease-in-out 1s infinite alternate slidein;
}

@keyframes slidein {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(100%);
  }
}

# Flex

flex-grow

.parent {
  display: flex;
  height: 100%;
}
.child:nth-child(3) {
  flex-grow: 1;
}

# Sass

Sass 支持变量和嵌套,还有很多其他功能。

以下 Sass 代码:

$brandColor: #f60;
$size: 1em;

.selector {
  margin: $size;
  background-color: $brandColor;

  .nested {
    margin: $size / 2;
  }
}

会被编译成如下 CSS 代码:

.selector {
  margin: 1em;
  background-color: #f60;
}

.selector .nested {
  margin: 0.5em;
}

# Less

同样的,Less 也支持变量和嵌套,还有很多其他功能。

以下 Less 代码:

@width: 10px;
@height: @width + 10px;

#header {
  width: @width;
  height: @height;
}

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

会被编译成如下 CSS 代码:

#header {
  width: 10px;
  height: 20px;
}
#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

# PostCSS

Post 之于 CSS,像是 Babel 之于 JS。作用之一是提高代码兼容性。

以下 CSS 代码:

.example {
  display: grid;
  transition: all 0.5s;
  user-select: none;
  background: linear-gradient(to bottom, white, black);
}

会被预处理成如下 CSS 代码:

.example {
  display: -ms-grid;
  display: grid;
  -webkit-transition: all 0.5s;
  -o-transition: all 0.5s;
  transition: all 0.5s;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  background: -webkit-gradient(
    linear,
    left top,
    left bottom,
    from(white),
    to(black)
  );
  background: -o-linear-gradient(top, white, black);
  background: linear-gradient(to bottom, white, black);
}

# CSS 相关

这一小节中的内容比较琐碎,以及有一些经验知识。

# 伪类和伪元素

经典的面试题:这两者有何异同。

其实很简单,看看它们的名字,伪“类”、伪“元素”。

伪类,就像 class 类一样,相当于筛选,找出符合条件的一部分元素。
常见如 :first-child:visited:hover
语法用 1 个冒号。

伪元素,重点在元素,可以理解为当前元素的隐式子元素。
常见如 ::before::after::placeholder
语法用 2 个冒号。

# 浏览器的默认样式

Default style sheet for HTML 4

不同显示设备和浏览器具有不同的默认样式,比如:

  • 输入框样式
  • 进度条样式
  • 设备自带哪些字体
  • 浏览器的最小字号
  • 手机上的最小字号

等等。

# 浏览器兼容性

随时通过 Can I use 查询兼容性。

PostCSS 可以有限地处理 CSS 兼容性问题。