CSS

本人是 CSS 超级苦手,甚至以前都只会写 nocss 页面。但是如果要给别人做东西用,nocss 肯定不太行。当今所有主流 GUI 框架中没一个打得过前端设计,我也想在前端领域玩玩,因此学习一点 CSS 是有必要的。

预处理器

css 本身不带逻辑,处理嵌套也麻烦。因此有各种各样的预处理器可以允许我们写更强大、更有意思的扩展语法,然后由它们在编译器改成标准 css。

上面两个预处理器都兼容原生 css。

盒模型

前端基础概念了。

现在有一种实践是全局所有组件全部使用 IE 盒模型,我觉得还是比较有道理的,特别是前端初学者可以通过 IE 盒避开不少坑。

margin
border
padding
Content Area

定位

Position 描述
static 默认值
relative 元素相对于其正常位置进行偏移。不影响文档流
absolute 元素相对于最近的已定位(非 static)祖先元素进行定位
fixed 元素相对于浏览器窗口进行定位
sticky 元素在跨越特定阈值前(屏幕内)表现为相对定位,之后表现为固定定位

需要注意,使用 sticky 的同时必须指定 top、bottom、left、right 其中之一,并且在其任意级父元素上都不能出现 overflow: auto 和 overflow: hidden。

自适应布局

flex

flex 布局是自适应的绝佳实践,而且对于前端初学者来说,flex 也非常符合界面直觉。

关于版本:flex 有多个版本。2024 年了,不需要考虑 flex 兼容性,可以假定所有浏览器都支持最新版本 flex。

无脑 flex:

  1. 想要让内部的玩意水平垂直居中,可以直接无脑 flex:display: flex; align-items: center; justify-content: center;
    • 注意该元素需要有一定宽高。
  2. 想要让某个元素占满空间,可以给父元素设为 flex(不要设 align-items & justify-content),然后该元素设为 flex: 1。

flex 基础:

  1. 主轴与交叉轴:主轴是元素排布的方向,交叉轴是与主轴垂直的方向。
  2. basis, grow and shrink
    • basis 是每个元素的基础长度。默认为 0,此时使用元素 width (或 height)。
    • grow 是当所有元素填不满 flex 时,对于剩下的空间的瓜分策略。实际上就是按 grow 比例瓜分。
    • shrink 是当所有元素超出 flex 时,对所有元素的压缩策略。每个元素被压缩的空间也是按 shrink 比例压缩。
  3. 对齐:
    • 主轴:justify-content。一般常用的有 center, space-between, space-around, space-evenly
    • 交叉轴:一旦使用了 flex,所有元素就会在交叉轴上被拉到最大(由默认值 align-items: stretch; 控制),非常直觉。
  4. 超出自动换行:flex-wrap: wrap; 换行后又会引入行间对齐问题,使用 align-content 解决。

flex 容易带来的问题:

  1. 由于 flex 元素没有特定位置和大小,如果其子元素使用了百分比高度/宽度,生成的样式可能不是你所希望的。(是我的问题,不是 flex 的问题)
  2. flex 并不保证元素不超过其边界,例如 shrink=0 的情况。
  3. 对于一个 flex: 1 项,我们通常不希望其内部的子元素将该项撑开,导致其比 flex 容器分配给它的空间更大。但是又无法直接设置 width,此时需要使用多种手段。
    css
    .flex-1-div {
      flex: 1;
      overflow: hidden;
      min-width: 0; /* 或 min-height: 0; */
    }
    .flex-1-div > * {
      max-width: 100%;
      box-sizing: border-box;
    }

grid

有时候,flex 并不能解决所有问题,特别是在有换行的情况下。例如我要做一个展示橱窗,有 9 个元素需要在当前区域 justify-content: space-between; 放置。其中五个元素在上面,四个元素被换行到下面。那么单纯用 flex 会导致上下不对齐,非常难受。

这时候就要用到 grid,grid 可以保证所有元素在自适应布局的同时还是对齐的。

vh

一般的响应式布局从获取屏幕宽高(100vw,100vh)开始。然而,100vh 在 safari,chrome 等 Android 浏览器上可能出现问题,因为 100vh 包括了被标题栏遮挡的区域。此时可以使用 svh。类似的新单位可以参考 Demystifying VH, DVH, SVH, and LVH in CSS。

框架

虽说写原生 CSS 也不是不行,但是有框架为什么不用呢。

大多数框架都喜欢将 “写 css” 变为 “写 class”,免去了 html 和 css 之间切来切去的烦恼,用得熟练的话确实可以加快开发速度;特别是对基于 JSX 的前端框架非常有用。而写 vue 的话,css 框架对于初学者来说就是多了查文档的时间,如果文档烂的话还是挺烦人的。

TailwindCSS

把 TailwindCSS 放在前面是因为即使直接上手其他 CSS 框架,也至少需要一点 TailwindCSS 基础。

进阶一些的技巧有:

插件

UnoCSS

UnoCSS 是一个可自定义化程度非常高的 CSS 框架。可以设置任意类名 -> 样式的映射和匹配规则,非常强大,并且可以无缝衔接 TailwindCSS,因此我现在已经转向 UnoCSS。

无缝衔接的条件是需要导入 TailwindCSS 的预设。我可以在此预设之上添加一些个人的 rules。

不过这玩意也不是完全没有缺点,比如文档里好多 404 的链接没人维护,比如 VSCode 插件不如 TailwindCSS 的插件强大等。

external

  1. 学习 CSS 布局
  2. 纯 CSS blur
  3. Tailwind CSS 基础概念、配置、常见问题和使用笔记
  4. The State of CSS Centering in 2026