4、CSS3核心进阶:Flexbox布局、Grid布局、响应式设计、CSS变量与预处理器

好,咱们进入第四章。说实话,CSS3 这部分内容,是我个人觉得前端跨端开发中最「爽」的一块。为什么?因为以前做布局,float、position 各种 hack,写出来的代码自己都不想看第二遍。Flexbox 和 Grid 出来之后,布局这件事变得优雅多了。

这一章我会把 Flexbox、Grid、响应式设计、CSS 变量和预处理器串起来讲。它们不是孤立的,而是现代 CSS 布局体系的四根柱子。你想想看,从网页到小程序,从桌面端到移动端,这套东西几乎通吃。

4.1 Flexbox 布局:一维空间的掌控者

Flexbox,全称 Flexible Box,说白了就是「弹性盒子」。它解决的是在一行或一列上的空间分配问题。我在项目中遇到过很多次,比如导航栏、卡片列表、垂直居中——用 Flexbox 几行代码搞定。

核心概念:主轴(main axis)和交叉轴(cross axis)。默认主轴是水平方向,交叉轴是垂直方向。

/* 最简单的 Flex 容器 */
.container {
  display: flex;
  justify-content: center;  /* 主轴居中 */
  align-items: center;      /* 交叉轴居中 */
  height: 200px;
}

/* 子项自动变成 flex item */
.item {
  flex: 1;  /* 等分剩余空间 */
  margin: 8px;
}

嗯,这里要注意:flex: 1 其实是 flex-grow: 1; flex-shrink: 1; flex-basis: 0% 的缩写。我以前踩过坑,以为 flex: 1 就是等宽,结果内容长了就撑开了。后来养成习惯,明确写 flex: 1 1 0% 或者用 min-width: 0 来兜底。

我的习惯:做移动端适配时,Flexbox 是首选。小程序里也完全支持,放心用。

常用属性速查

属性 作用 常用值
flex-direction 主轴方向 row | column
flex-wrap 是否换行 nowrap | wrap
justify-content 主轴对齐 center | space-between | space-around
align-items 交叉轴对齐 center | stretch | flex-start
align-self 单个子项对齐 center | flex-end

避坑指南:我曾经在微信小程序里用 flex: 1 配合 overflow: hidden,结果内容被截断了。后来发现是 flex-basis 的默认值问题。解决方案:显式设置 min-width: 0overflow: hidden 在父容器上。

4.2 Grid 布局:二维空间的终极方案

Grid 和 Flexbox 的区别?我打个比方:Flexbox 是「排队的队伍」,只管一行或一列;Grid 是「棋盘」,行和列一起管。如果你要做复杂的页面布局,比如后台管理系统、商品展示页,Grid 是更好的选择。

/* 一个简单的 Grid 网格 */
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* 三列等宽 */
  grid-template-rows: auto;
  gap: 16px;  /* 间距 */
}

/* 跨列 */
.item-wide {
  grid-column: span 2;  /* 占两列 */
}

为什么会推荐 Grid?因为它的「显式网格」概念太强了。你可以在 HTML 里放任意数量的子元素,Grid 会自动排列。而且 gap 属性比 margin 干净得多——不用考虑外边距合并的问题。

个人经验:我在做一个多端适配的电商项目时,商品列表用 Grid 实现。PC 端 4 列,平板 3 列,手机 2 列。只需要改 grid-template-columns 的值,其他代码完全不用动。

Grid 和 Flexbox 怎么选?

  • 一维布局(导航栏、按钮组、居中)→ 用 Flexbox
  • 二维布局(页面骨架、卡片网格、仪表盘)→ 用 Grid
  • 内容驱动(不知道有多少项)→ Flexbox 更灵活
  • 布局驱动(固定行列结构)→ Grid 更精确

4.3 响应式设计:一套代码,多端适配

响应式设计的核心就三个字:媒体查询。但光有媒体查询不够,还得配合弹性布局和相对单位。我见过很多新手写死 px,结果换个屏幕就崩了。

/* 移动端优先的写法 */
.card {
  width: 100%;
  padding: 16px;
}

/* 平板及以上 */
@media (min-width: 768px) {
  .card {
    width: 50%;
    padding: 24px;
  }
}

/* 桌面端 */
@media (min-width: 1024px) {
  .card {
    width: 33.33%;
  }
}

嗯,这里有个小技巧:用 min-width 做「向上兼容」,比用 max-width 更符合移动端优先的思路。我习惯把断点设为 576px、768px、992px、1200px,和 Bootstrap 保持一致,方便团队协作。

避坑指南:我曾经在微信小程序里用 rpx 做响应式,结果发现 rpx 是基于屏幕宽度的,和 CSS 的 vw 类似。但要注意,rpx 在小程序里是 750 设计稿的基准,而 vw 是 100 等分。两者混用时容易算错。

4.4 CSS 变量:让样式可配置

CSS 变量(Custom Properties)是我最近两年用得越来越多的特性。它让样式变得像配置一样灵活。说白了,就是你可以把颜色、间距、字体等抽出来,统一管理。

:root {
  --primary-color: #1890ff;
  --spacing-unit: 8px;
  --font-size-base: 14px;
}

.button {
  background-color: var(--primary-color);
  padding: calc(var(--spacing-unit) * 2);
  font-size: var(--font-size-base);
}

/* 在媒体查询中改变变量值 */
@media (prefers-color-scheme: dark) {
  :root {
    --primary-color: #40a9ff;
  }
}

为什么推荐 CSS 变量?因为它可以在运行时改变。比如用户切换主题,你只需要改几个变量的值,整个页面就变了。这在跨端开发中特别有用——小程序和 Web 端共用一套变量定义。

我的习惯:把 CSS 变量放在一个单独的 variables.css 文件中,然后在各个组件中引用。这样改主题时,只需要改这一个文件。

4.5 CSS 预处理器:Sass/SCSS 实战

CSS 预处理器,说白了就是给 CSS 加了「编程能力」。变量、嵌套、混入、函数——这些在原生 CSS 里没有的东西,预处理器全给你补上了。我个人更偏爱 SCSS,因为它的语法和 CSS 最接近。

// 变量
$primary-color: #1890ff;
$spacing: 16px;

// 混入
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// 嵌套
.card {
  @include flex-center;
  padding: $spacing;

  &__title {
    font-size: 18px;
    color: $primary-color;
  }

  &__content {
    margin-top: $spacing / 2;
  }
}

// 循环
@for $i from 1 through 4 {
  .col-#{$i} {
    width: 25% * $i;
  }
}

嗯,这里要注意:嵌套层级不要超过三层。我见过有人嵌套七八层,生成的 CSS 选择器又长又丑,性能也受影响。记住:嵌套是为了方便,不是为了炫技。

避坑指南:我曾经在团队项目中用 SCSS 的 @extend 来复用样式,结果生成的 CSS 文件里出现了大量重复的选择器。后来改用 @mixin 配合 @include,代码更可控。建议:@extend 只用于占位符选择器(%),其他情况用 @mixin

预处理器 vs CSS 变量

特性 SCSS 变量 CSS 变量
编译时机 编译时 运行时
作用域 文件级 DOM 级
动态修改 不支持 支持(JS 修改)
浏览器兼容 完全兼容 现代浏览器
适用场景 构建时配置 运行时主题

两者不是互斥的。我通常的做法是:用 SCSS 变量管理构建时的配置(如断点、间距倍数),用 CSS 变量管理运行时的主题(如颜色、字体)。这样既享受了预处理器的便利,又保留了 CSS 变量的灵活性。

总结一下:Flexbox 管一维,Grid 管二维,响应式设计管适配,CSS 变量和预处理器管可维护性。这四样东西组合起来,基本能覆盖从网页到小程序的全部布局需求。下一章我们会聊到 JavaScript 在跨端开发中的角色,敬请期待。