CSS3 核心基础与布局
CSS3 核心基础与布局
面向读者:有 Go 后端经验的开发者。如果你把 HTML 理解为"数据结构的定义",那么 CSS 就是"视图渲染的配置"。CSS 决定了元素"长什么样、摆在哪里"——类似于 Go 中为结构体字段添加各种 tag 来控制序列化行为。
一、盒模型(Box Model)
CSS 中每个元素都是一个"盒子",从内到外依次为:
┌─────────────────────────────────┐ ← margin(外边距)
│ ┌───────────────────────────┐ │ ← border(边框)
│ │ ┌─────────────────────┐ │ │
│ │ │ content(内容) │ │ │
│ │ └─────────────────────┘ │ │
│ │ ↑ padding(内边距) ↑ │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘.box {
width: 200px; /* 内容区宽度 */
padding: 16px; /* 内边距 */
border: 2px solid #333; /* 边框 */
margin: 20px; /* 外边距 */
}标准盒模型 vs 怪异盒模型
默认情况下,width 只包含 content 宽度。加上 padding 和 border 后,元素实际占据的宽度会更大。
/* 标准盒模型(默认):width = content */
box-sizing: content-box; /* 实际宽度 = 200 + 16*2 + 2*2 = 236px */
/* 推荐:border-box:width 包含 content + padding + border */
box-sizing: border-box; /* 实际宽度 = 200px(padding 和 border 向内挤) *//* 全局重置:所有元素使用 border-box */
*, *::before, *::after {
box-sizing: border-box;
}类比 Go
Go 结构体通过 json:"field_name" tag 控制序列化输出,CSS 通过 box-sizing 属性控制盒模型计算方式——都是"通过声明式配置改变默认行为"。
二、选择器与优先级
2.1 常见选择器
/* 元素选择器 */
div { color: blue; }
/* 类选择器(最常用) */
.card { background: #f0f0f0; }
/* ID 选择器(应少用) */
#header { height: 60px; }
/* 属性选择器 */
[data-role="admin"] { font-weight: bold; }
/* 后代选择器 */
.article p { line-height: 1.6; }
/* 子代选择器 */
.list > .item { border-bottom: 1px solid #eee; }
/* 相邻兄弟 */
h2 + p { margin-top: 0; }
/* 伪类 */
.button:hover { opacity: 0.8; }
.input:focus { border-color: blue; }
li:first-child { font-weight: bold; }
li:nth-child(2n) { background: #f9f9f9; }
/* 伪元素 */
.card::before { content: "★"; color: gold; }
.card::after { content: ""; display: block; clear: both; }2.2 优先级计算
!important > 行内样式 > ID 选择器 > 类/属性/伪类 > 元素/伪元素 > 通配符 *| 选择器示例 | 权重(a-b-c-d) |
|---|---|
* | 0-0-0-0 |
div | 0-0-0-1 |
.class | 0-0-1-0 |
div.class | 0-0-1-1 |
#id | 0-1-0-0 |
#id .class | 0-1-1-0 |
style="color: red" | 1-0-0-0 |
.class + !important | ∞ |
不要滥用 !important
/* 不推荐 */
.button { color: red !important; }
/* 推荐:提高优先级即可 */
.nav .button { color: red; }类比 Go 中不加限制地使用 panic / recover,!important 会破坏层叠规则,导致后续维护困难。
三、Flexbox 布局(重中之重)
Flexbox 是一维布局模型,类比 Go 中sort.Slice 统一了排序逻辑,Flexbox 统一了"如何在容器内排列子元素"这件事。
3.1 容器属性
.flex-container {
display: flex; /* 启用 Flexbox */
flex-direction: row; /* 主轴方向:row | column | row-reverse | column-reverse */
flex-wrap: wrap; /* 是否换行:nowrap | wrap | wrap-reverse */
justify-content: center; /* 主轴对齐:flex-start | center | flex-end | space-between | space-around | space-evenly */
align-items: center; /* 交叉轴对齐:stretch | center | flex-start | flex-end | baseline */
align-content: center; /* 多行时的交叉轴对齐 */
gap: 16px; /* 子元素间距(替代 margin) */
}3.2 子元素属性
.flex-item {
flex-grow: 1; /* 放大比例(默认 0) */
flex-shrink: 1; /* 缩小比例(默认 1) */
flex-basis: auto; /* 基础大小 */
align-self: center; /* 单独对齐 */
order: 1; /* 排列顺序(默认 0) */
}
/* 简写 */
.item { flex: 1; } /* flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
.item { flex: 0 0 200px; } /* 固定宽度 200px,不伸缩 */3.3 常用布局模板
/* 水平居中 + 垂直居中(最常用) */
.centered {
display: flex;
justify-content: center;
align-items: center;
}
/* 圣杯布局:固定两侧 + 中间自适应 */
.holy-grail {
display: flex;
}
.holy-grail > .sidebar { flex: 0 0 240px; } /* 固定宽度 */
.holy-grail > .main { flex: 1; } /* 自适应 */
.holy-grail > .sidebar { flex: 0 0 240px; } /* 固定宽度 */
/* 等分布局 */
.equal-grid {
display: flex;
gap: 16px;
}
.equal-grid > * { flex: 1; }类比 Go
justify-content: space-between:类似 Go 切片操作中完美分配剩余空间flex: 1:类似 Go 中append(slice, elem)动态扩展gap:类似 Go 中for range循环内部处理间距的标准化解决方案
四、Grid 布局
Grid 是二维布局模型,适合页面级的整体骨架:
.grid-container {
display: grid;
/* 列定义 */
grid-template-columns: 240px 1fr 320px; /* 固定 + 自适应 + 固定 */
grid-template-columns: repeat(3, 1fr); /* 3 等分 */
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); /* 响应式列数 */
/* 行定义 */
grid-template-rows: auto 1fr auto; /* 页眉 + 内容 + 页脚 */
/* 间距 */
gap: 16px;
/* 区域命名 */
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
}
.grid-header { grid-area: header; }
.grid-sidebar { grid-area: sidebar; }
.grid-content { grid-area: content; }
.grid-aside { grid-area: aside; }
.grid-footer { grid-area: footer; }Flexbox vs Grid 选择
| 场景 | 推荐 |
|---|---|
| 导航栏、按钮组、卡片排列 | Flexbox(一维) |
| 页面整体骨架、Dashboard | Grid(二维) |
| 未知数量的等宽卡片 | Grid + auto-fill |
| 单个方向的对齐 | Flexbox |
五、响应式设计 — @media 查询
类似于 Go 中通过构建标签(build tags)区分不同平台,CSS 通过媒体查询区分不同屏幕尺寸:
/* 移动端优先(Mobile First):从小到大 */
/* 默认样式 = 手机(< 576px) */
/* 平板(≥ 768px) */
@media (min-width: 768px) {
.container { max-width: 720px; }
}
/* 桌面(≥ 992px) */
@media (min-width: 992px) {
.container { max-width: 960px; }
}
/* 宽屏(≥ 1200px) */
@media (min-width: 1200px) {
.container { max-width: 1140px; }
}
/* 暗色模式 */
@media (prefers-color-scheme: dark) {
body { background: #1a1a2e; color: #eee; }
}/* 实用示例:响应式网格 */
.card-grid {
display: grid;
grid-template-columns: 1fr; /* 手机:1 列 */
gap: 16px;
}
@media (min-width: 640px) {
.card-grid { grid-template-columns: repeat(2, 1fr); } /* 平板:2 列 */
}
@media (min-width: 1024px) {
.card-grid { grid-template-columns: repeat(4, 1fr); } /* 桌面:4 列 */
}六、CSS 变量(Custom Properties)
CSS 变量让样式可维护性大幅提升,类比 Go 中的 const 常量定义:
:root {
/* 颜色系统 */
--color-primary: #409eff;
--color-success: #67c23a;
--color-warning: #e6a23c;
--color-danger: #f56c6c;
/* 间距系统 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* 字号系统 */
--font-size-sm: 12px;
--font-size-md: 14px;
--font-size-lg: 16px;
--font-size-xl: 20px;
/* 圆角 */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* 阴影 */
--shadow-sm: 0 1px 2px rgba(0,0,0,0.06);
--shadow-md: 0 4px 6px rgba(0,0,0,0.1);
}
/* 使用变量 */
.button {
background: var(--color-primary);
padding: var(--spacing-sm) var(--spacing-md);
font-size: var(--font-size-md);
border-radius: var(--radius-md);
box-shadow: var(--shadow-sm);
}
/* 变量可以覆盖(实现主题) */
[data-theme="dark"] {
--color-primary: #66b1ff;
}提示
CSS 变量可以在 JS 中动态修改,这是实现主题切换的基础:
document.documentElement.style.setProperty('--color-primary', '#ff6600');类比 Go 的 os.Setenv 修改环境变量——运行期间改变配置,全局生效。
七、Tailwind CSS 简介
Tailwind 是"工具类优先"(Utility-First)的 CSS 框架,类比 Go 标准库中 strings strconv 等小工具函数组合使用:
<!-- 传统 CSS -->
<div class="card">
<h2 class="card-title">标题</h2>
<p class="card-desc">描述</p>
</div>
<!-- Tailwind:直接在 HTML 中组合工具类 -->
<div class="rounded-lg bg-white p-6 shadow-md hover:shadow-lg transition-shadow">
<h2 class="text-xl font-bold text-gray-800">标题</h2>
<p class="mt-2 text-gray-600 leading-relaxed">描述</p>
</div>/* Tailwind 内部逻辑(简化)*/
.rounded-lg { border-radius: 8px; }
.bg-white { background-color: #fff; }
.p-6 { padding: 1.5rem; }
.shadow-md { box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
.text-xl { font-size: 1.25rem; }
.font-bold { font-weight: 700; }何时使用 Tailwind?
- 适合:团队统一设计规范、快速原型、组件库开发
- 不适合:需要完全定制设计的官网、对 class 命名有严格规范的传统项目
- 类比 Go 中使用
ginvsecho——都是框架,选型取决于团队偏好和项目规模
八、Vue SFC 中的 Scoped CSS
当使用 Vue 单文件组件(SFC)时,<style scoped> 可以让样式仅作用于当前组件,类比 Go 中包级私有变量:
<template>
<div class="card">
<h2>{{ title }}</h2>
</div>
</template>
<style scoped>
/* 这里的样式只对当前组件生效,不会污染全局 */
.card {
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 16px;
}
.card h2 {
font-size: 18px;
color: #333;
}
</style>实现原理
Vue 会为每个组件添加一个唯一 data-v-xxxxx 属性,并将 CSS 选择器自动转换:
/* 你写的 */
.card { border: 1px solid #e0e0e0; }
/* 编译后(自动加属性选择器) */
.card[data-v-abc123] { border: 1px solid #e0e0e0; }全局样式例外
<style scoped>
/* 使用 :deep() 穿透作用域,修改子组件内部样式 */
:deep(.child-component-title) { color: red; }
</style>
<style>
/* 不加 scoped = 全局样式,慎用 */
</style>总结
| 概念 | Go 类比 |
|---|---|
| 盒模型 | 结构体内存对齐(padding 类比填充) |
| 选择器优先级 | 接口覆盖规则 |
| Flexbox | 切片操作(动态分配空间) |
| Grid | 二维数组/矩阵 |
| CSS 变量 | const 常量 |
| Tailwind 工具类 | 标准库工具函数组合 |
| Scoped CSS | 包级私有变量 |
- 盒模型:始终使用
box-sizing: border-box - Flexbox:掌握
flex: 1和center居中,覆盖 80% 布局场景 - Grid:适合页面级骨架
- CSS 变量:定义设计 Token,提升维护性
下一站:JavaScript 核心语法速通,学习 CSS 的"驱动引擎"。