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