Skip to content

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 注意事项:

  1. 粘性范围受最近的 overflowvisible 的祖先元素限制——如果祖先元素(包括父元素)设置了 overflow: hidden/scroll/auto,sticky 只能在该元素范围内生效。如果该元素本身不可滚动(如 overflow: hidden),sticky 效果将不可见。
  2. 必须指定 top / bottom / left / right 至少一个值,否则等同于 relative
  3. 粘性范围取决于最近的滚动祖先——如果父元素有滚动条,sticky 只在该父元素内生效,不会粘在视口上。
  4. 相邻的 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?

  1. 清除浮动时父元素高度塌陷:父元素包含浮动子元素时,父元素高度会变成 0。创建 BFC 后,父元素会包含浮动子元素的高度。
  2. 防止 margin 穿透:子元素的 margin-top 会穿透到父元素外面,导致父元素也被推下去。创建 BFC 可以阻止这种穿透。
  3. 阻止元素被浮动元素覆盖:普通元素会和浮动元素重叠,创建 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%;
}

参考

个人学习笔记,部分内容借助 AI 辅助整理,仅供查阅参考,请以官方文档为准