CSS 核心知识
CSS(Cascading Style Sheets,层叠样式表)是用来给 HTML 元素"化妆"的语言——控制颜色、大小、位置、动画等一切视觉表现。日常开发中最常用的布局方案、选择器、响应式技巧和经典问题都在这里。
选择器优先级
权重计算
大白话解释: 当多条 CSS 规则同时作用于同一个元素时,浏览器按"权重"决定谁生效。权重高的覆盖权重低的,同权重则后写的覆盖先写的。!important 是一个特殊声明,不是选择器,它直接把某条属性提升到最高优先级,慎用。
权重用 A-B-C-D 四位数表示(IDs-Classes/Pseudo-classes/Attributes-Elements/Pseudo-elements):
| 选择器类型 | 权重值 | 示例 |
|---|---|---|
内联样式 style="" | 1-0-0-0(即 1000) | style="color: red" |
| ID 选择器 | 0-1-0-0(即 100) | #header |
| 类 / 伪类 / 属性选择器 | 0-0-1-0(即 10) | .card、:hover、[type="text"] |
| 元素 / 伪元素选择器 | 0-0-0-1(即 1) | div、::before |
通配符 * / 继承的样式 | 0(最低) | * |
注意:
!important不是选择器,它是声明级别的修饰符,可以覆盖任何权重。但会导致样式难以维护,应尽量避免使用。
css
/* 权重:0-1-0-0 */
.card { color: red; }
/* 权重:0-1-0-1 */
div.card { color: blue; }
/* 权重:0-2-0-0 */
.card.active { color: green; }
/* 权重:1-0-0-0 */
#header { color: black; }常见陷阱
css
/* ❌ 过度使用 !important */
.error { color: red !important; }
/* ❌ 过高权重导致无法覆盖 */
#app .main .content .card .title { color: red; }
/* ✅ 保持选择器扁平 */
.card-title { color: red; }盒模型
标准盒模型 vs IE 盒模型
css
/* 标准盒模型(默认) */
/* width = content width */
.standard { box-sizing: content-box; }
/* IE 盒模型 */
/* width = content + padding + border */
.border { box-sizing: border-box; }标准盒模型: IE 盒模型:
┌─────────────┐ ┌─────────────┐
│ margin │ │ margin │
│ ┌─────────┐ │ │ ┌─────────┐ │
│ │ border │ │ │ │ border │ │
│ │ ┌─────┐ │ │ │ │ padding │ │
│ │ │ pad │ │ │ │ │ content │ │
│ │ │content│ │ │ └─────────┘ │
│ │ └─────┘ │ │ └─────────────┘
│ └─────────┘ │ width 包含 border + padding
└─────────────┘
width 只是 content全局推荐设置
css
*,
*::before,
*::after {
box-sizing: border-box;
}Flex 布局
大白话解释: Flex 布局就像"排队"。把一堆元素放进一个容器里,让它们按一定规则排列:
- 主轴:排队的方向(从左到右、从上到下)
- 交叉轴:垂直于主轴的方向
- justify-content:在主轴方向上怎么分布(靠左、靠右、居中、等间距)
- align-items:在交叉轴方向上怎么对齐(靠上、靠下、居中、拉伸)
什么时候用 Flex?
- 导航栏(元素水平排列,两端对齐)
- 按钮组(元素水平排列,居中)
- 卡片列表(元素换行排列)
- 水平垂直居中(最简单的方式)
容器属性
css
.container {
display: flex;
/* 主轴方向 */
flex-direction: row; /* 默认:从左到右 */
/* flex-direction: row-reverse; 从右到左 */
/* flex-direction: column; 从上到下 */
/* flex-direction: column-reverse; */
/* 主轴对齐 */
justify-content: flex-start; /* 默认:起点对齐 */
/* justify-content: flex-end; 终点对齐 */
/* justify-content: center; 居中 */
/* justify-content: space-between; 两端对齐 */
/* justify-content: space-around; 等间距 */
/* justify-content: space-evenly; 完全等分 */
/* 交叉轴对齐 */
align-items: stretch; /* 默认:拉伸 */
/* align-items: flex-start; 起点对齐 */
/* align-items: flex-end; 终点对齐 */
/* align-items: center; 居中 */
/* align-items: baseline; 基线对齐 */
/* 换行 */
flex-wrap: nowrap; /* 默认:不换行 */
/* flex-wrap: wrap; 换行 */
/* flex-wrap: wrap-reverse; 反向换行 */
/* 多行对齐(需 flex-wrap: wrap) */
align-content: flex-start;
}项目属性
css
.item {
/* 放大比例(默认 0,不放大) */
flex-grow: 1;
/* 缩小比例(默认 1,会缩小) */
flex-shrink: 0;
/* 初始大小(默认 auto) */
flex-basis: 200px;
/* 简写:flex: grow shrink basis */
flex: 1; /* 等价于 flex: 1 1 0% */
flex: 0 0 200px; /* 固定 200px,不放大不缩小 */
flex: none; /* 等价于 flex: 0 0 auto */
/* 单独对齐 */
align-self: center;
/* 排序(默认 0) */
order: -1;
}常见布局
css
/* 水平垂直居中 */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* 两端对齐,中间等分 */
.nav {
display: flex;
justify-content: space-between;
}
/* 固定侧栏 + 自适应主内容 */
.layout {
display: flex;
}
.sidebar {
flex: 0 0 240px;
}
.main {
flex: 1;
}
/* 底部固定 */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
flex: 1;
}
.footer {
flex-shrink: 0;
}Grid 布局
大白话解释: Grid 布局就像"画表格"。把页面划分成行和列的网格,然后把元素放到指定的格子里。
Flex vs Grid 怎么选?
- Flex:一维排列(一行或一列),像排队
- Grid:二维布局(行+列),像画表格
什么时候用 Grid?
- 整体页面布局(头部、侧边栏、主内容、底部)
- 卡片网格(自动适应列数的卡片列表)
- 复杂的表单布局
基本用法
css
.grid {
display: grid;
/* 定义列 */
grid-template-columns: 200px 1fr 200px; /* 固定-自适应-固定 */
/* grid-template-columns: repeat(3, 1fr); 三等分 */
/* grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); 自动填充 */
/* 定义行 */
grid-template-rows: 60px 1fr 60px; /* 头-内容-底 */
/* 间距 */
gap: 16px;
/* row-gap: 16px; */
/* column-gap: 16px; */
}常见布局
css
/* 圣杯布局 */
.layout {
display: grid;
grid-template:
"header header header" 60px
"sidebar main aside" 1fr
"footer footer footer" 60px
/ 200px 1fr 200px;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* 自适应卡片网格 */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
/* 瀑布流 */
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 10px;
}Flex vs Grid 选择
| 场景 | 推荐 | 原因 |
|---|---|---|
| 一维排列(行或列) | Flex | 简单直观 |
| 二维布局(行+列) | Grid | 天然支持 |
| 内容驱动 | Flex | 自动适应内容 |
| 布局驱动 | Grid | 精确控制区域 |
| 导航栏、工具栏 | Flex | 单行排列 |
| 整体页面布局 | Grid | 区域划分 |
定位
position 属性
| 值 | 定位参考 | 是否脱离文档流 |
|---|---|---|
static | 无(默认) | 否 |
relative | 自身原始位置 | 否 |
absolute | 最近的非 static 祖先 | 是 |
fixed | 视口 | 是 |
sticky | 滚动容器 | 否 |
常见用法
css
/* 子元素绝对居中 */
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 粘性导航 */
.nav {
position: sticky;
top: 0; /* 滚动到距顶部 0px 时开始粘住 */
z-index: 100;
}
/* 遮罩层 */
.overlay {
position: fixed;
inset: 0; /* 等价于 top: 0; right: 0; bottom: 0; left: 0 */
background: rgba(0, 0, 0, 0.5);
z-index: 999;
}
/* 角标 */
.badge-wrapper {
position: relative;
}
.badge {
position: absolute;
top: -8px;
right: -8px;
}
sticky注意事项:
- 粘性范围受最近的
overflow非visible的祖先元素限制——如果祖先元素(包括父元素)设置了overflow: hidden/scroll/auto,sticky 只能在该元素范围内生效。如果该元素本身不可滚动(如overflow: hidden),sticky 效果将不可见。- 必须指定
top/bottom/left/right至少一个值,否则等同于relative。- 粘性范围取决于最近的滚动祖先——如果父元素有滚动条,sticky 只在该父元素内生效,不会粘在视口上。
- 相邻的 sticky 元素会"叠在一起",需要通过不同的
top值错开。
响应式
媒体查询
css
/* 移动优先(min-width) */
.container {
padding: 0 16px;
}
@media (min-width: 768px) {
.container {
padding: 0 24px;
max-width: 720px;
margin: 0 auto;
}
}
@media (min-width: 1024px) {
.container {
max-width: 960px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1200px;
}
}常用断点
css
/* 手机 */
@media (max-width: 767px) { }
/* 平板 */
@media (min-width: 768px) and (max-width: 1023px) { }
/* 桌面 */
@media (min-width: 1024px) { }响应式单位
css
/* rem —— 相对于根元素 font-size */
html {
font-size: 16px;
}
.title {
font-size: 1.5rem; /* 24px */
}
/* vw/vh —— 视口宽高百分比 */
.hero {
height: 100vh;
width: 100vw;
}
/* clamp() —— 响应式值 */
.title {
font-size: clamp(1.25rem, 4vw, 2.5rem);
/* 最小 1.25rem,首选 4vw,最大 2.5rem */
}BFC(块级格式化上下文)
什么是 BFC?
BFC(Block Formatting Context)是 CSS 中一个独立的渲染区域,内部元素的布局不会影响到外部。你可以把它理解成一个"隔离的盒子",盒子内部的布局规则和外部互不干扰。
什么时候需要主动创建 BFC?
- 清除浮动时父元素高度塌陷:父元素包含浮动子元素时,父元素高度会变成 0。创建 BFC 后,父元素会包含浮动子元素的高度。
- 防止 margin 穿透:子元素的 margin-top 会穿透到父元素外面,导致父元素也被推下去。创建 BFC 可以阻止这种穿透。
- 阻止元素被浮动元素覆盖:普通元素会和浮动元素重叠,创建 BFC 可以让元素避开浮动元素。
触发条件
css
/* 以下任一条件都会创建 BFC */
.bfc {
overflow: hidden; /* 最常用 */
/* display: flow-root; 最干净的方式,专门为 BFC 设计 */
/* float: left/right; */
/* position: absolute/fixed; */
/* display: inline-block/flex/grid; */
}解决的问题
css
/* 1. 清除浮动(父元素高度塌陷) */
.parent {
overflow: hidden; /* 创建 BFC,包含浮动子元素 */
}
/* 2. 外边距重叠 */
.parent {
overflow: hidden; /* 子元素的 margin 不会穿透到父元素外 */
}常见经典问题
水平垂直居中
css
/* 方案一:Flex(推荐) */
.center-flex {
display: flex; /* 开启 Flex 布局 */
justify-content: center; /* 主轴(水平)方向居中 */
align-items: center; /* 交叉轴(垂直)方向居中 */
}
/* 方案二:Grid */
.center-grid {
display: grid;
place-items: center;
}
/* 方案三:绝对定位 + transform */
.center-absolute {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 方案四:绝对定位 + margin auto */
.center-margin {
position: absolute;
inset: 0;
margin: auto;
width: fit-content;
height: fit-content;
}文字溢出省略号
css
/* 单行 */
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 多行(Webkit) */
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}清除浮动
css
/* 方案一:clearfix(伪元素) */
.clearfix::after {
content: '';
display: block;
clear: both;
}
/* 方案二:BFC */
.parent {
overflow: hidden;
}
/* 方案三:现代布局(推荐) */
.parent {
display: flex;
/* 或 display: grid; */
}1px 边框问题(移动端)
css
/* 方案一:伪元素 + transform */
.border-1px {
position: relative;
}
.border-1px::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background: #ccc;
transform: scaleY(0.5);
}
/* 方案二:viewport 缩放 */
/* 在 meta 标签中设置 viewport scale */自适应正方形
css
/* 方案一:aspect-ratio(现代浏览器推荐) */
.square {
width: 100%; /* 宽度随父元素自适应 */
aspect-ratio: 1; /* 宽高比 1:1,自动计算高度形成正方形 */
}
/* 方案二:padding hack(兼容旧浏览器) */
.square {
width: 100%; /* 宽度随父元素自适应 */
padding-bottom: 100%; /* padding 百分比相对父元素宽度计算,所以等于宽度 */
height: 0; /* 高度设 0,由 padding 撑开 */
}CSS 变量
css
/* 定义变量(:root 即 <html>,变量全局生效) */
:root {
--primary: #1890ff; /* 主题色:按钮、链接等主色调 */
--success: #52c41a; /* 成功色:成功提示 */
--danger: #ff4d4f; /* 危险色:错误、删除 */
--spacing-sm: 8px; /* 小间距 */
--spacing-md: 16px; /* 中间距 */
--spacing-lg: 24px; /* 大间距 */
--font-size: 14px; /* 基础字号 */
--radius: 4px; /* 基础圆角 */
}
/* 使用变量:var() 函数读取变量值 */
.button {
background: var(--primary);
padding: var(--spacing-sm) var(--spacing-md);
font-size: var(--font-size);
border-radius: var(--radius);
}
/* 修改变量(暗色模式):在 data-theme 属性上覆盖变量值 */
[data-theme='dark'] {
--primary: #177ddc;
--bg: #141414;
--text: #fff;
}
/* 媒体查询中修改:跟随系统暗色模式偏好 */
@media (prefers-color-scheme: dark) {
:root {
--bg: #141414;
--text: #fff;
}
}Vue 中使用 CSS 变量
vue
<template>
<!-- 通过绑定 style 动态修改 CSS 变量 -->
<div :style="{ '--theme-color': themeColor }">
<button class="btn">按钮</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 主题色可通过 JS 动态修改,无需切换 class
const themeColor = ref('#1890ff')
// 切换暗色模式:直接修改根元素的 CSS 变量
function toggleDark() {
document.documentElement.style.setProperty('--bg', '#141414')
document.documentElement.style.setProperty('--text', '#fff')
}
</script>
<style scoped>
/* 在 Vue 组件中直接使用 CSS 变量 */
.btn {
background: var(--theme-color); /* 读取父元素通过 :style 绑定的变量 */
color: #fff;
border: none;
padding: 8px 16px;
border-radius: var(--radius); /* 读取全局 :root 变量 */
}
</style>常用技巧
三角形
css
.triangle {
width: 0;
height: 0;
border: 10px solid transparent;
border-top-color: red; /* 向下的三角 */
}滚动条样式
css
/* 自定义滚动条(Webkit) */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #999;
}平滑滚动
css
html {
scroll-behavior: smooth;
}禁止选中
css
.no-select {
user-select: none;
}图片自适应
css
img {
max-width: 100%;
height: auto;
}
/* 填充容器,裁剪超出 */
.cover {
object-fit: cover;
width: 100%;
height: 100%;
}参考
- MDN CSS 参考
- CSS-Tricks
- Flexbox Froggy — Flex 交互学习
- Grid Garden — Grid 交互学习