CSS布局与动效知识梳理

CSS布局与动效知识梳理

概述

本文将布局和动效中使用频率最高的知识点串成一条线:定位处理层叠与脱离文档流,Grid 处理二维复杂布局,多列处理文本流排版,2D/3D 变换处理视觉变形,过渡与动画处理时间维度的状态切换。

一、定位布局

定位的核心价值:控制元素脱离正常流、层叠顺序以及相对于谁定位。

position:定位模式

css 复制代码
/* position: static | relative | absolute | fixed | sticky */
  • static :默认值,元素在正常文档流中,top/left 等偏移属性无效。
  • relative :相对于元素自身原位置 偏移,仍占据原空间,不影响其他元素布局。常用于为子元素创建定位参照。
  • absolute :脱离文档流,相对于最近的定位祖先 (非 static 的父级)定位。若无,则相对于 <body>。日常写 absolute 时务必在父级设 position: relative
  • fixed :脱离文档流,相对于浏览器视口定位,滚动不改变位置。用于固定导航栏、悬浮按钮、弹窗遮罩。
  • sticky :滚动到达阈值前为 relative,到达后切换为 fixed。典型场景是吸顶导航。
css 复制代码
.nav {
  position: sticky;
  top: 0;           /* 滚动到顶部时吸附 */
  z-index: 10;
}

注意:sticky 的父级不能设 overflow: hidden,否则会退化为 relative

偏移属性

top / right / bottom / left 仅对 positionstatic 的元素生效。百分比值相对于包含块的对应维度计算。

z-index 与层叠上下文

z-index 控制定位元素在 Z 轴上的堆叠顺序,值越大越靠前。仅对定位元素(非 static)生效。

新层叠上下文的触发条件(除 positionstatic + z-indexauto 外,高频触发项):opacity < 1transformnonefilternone。一旦触发,子元素的 z-index 仅在当前上下文中比较,不会跨上下文穿透。

区分:z-index: 9999 不一定最高------如果它所在的层叠上下文整体低于另一个层叠上下文,再大也无效。

常见模式

绝对定位居中(宽高已知)

css 复制代码
.box {
  position: absolute;
  top: 50%; left: 50%;
  width: 400px; height: 300px;
  margin-left: -200px;   /* 负宽度一半 */
  margin-top: -150px;    /* 负高度一半 */
}

遮罩层 + 弹窗

css 复制代码
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 99; }
.modal  { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 100; }

insettop/right/bottom/left 的四合一简写,inset: 0 即铺满包含块。

二、网格布局

Grid 是 CSS 首个真正的二维布局方案,同时控制行和列。与 Flex(一维)互补。

grid-template-columns / grid-template-rows:轨道定义

定义网格的列宽和行高。三个核心工具:fr 单位、repeat() 函数、minmax() 函数。

css 复制代码
.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;           /* 三列,中间列占一半 */
  grid-template-columns: repeat(4, 1fr);         /* 四等分 */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* 响应式核心 */
  grid-template-rows: auto 1fr auto;             /* 经典 header-content-footer */
}
  • fr :弹性单位,按比例分配剩余空间,类似 Flex 的 flex-grow
  • repeat(次数, 轨宽):减少重复书写。
  • minmax(min, max) :轨道最小/最大尺寸约束,配合 auto-fill 实现无断点换行。

gap:轨道间距

css 复制代码
.container {
  gap: 20px;              /* 行和列间距统一 */
  gap: 20px 16px;         /* 行间距 20px,列间距 16px */
}

替代传统 margin 方案,间距仅作用在轨道之间,容器边缘无多余空隙。

grid-auto-rows / grid-auto-flow:隐式网格

显式网格是 grid-template-* 定义的轨道,超出部分由隐式网格接管。

css 复制代码
.container {
  grid-auto-rows: 200px;           /* 隐式行高 */
  grid-auto-flow: dense;           /* 紧密填充,不留空洞 */
}

dense 适合图片瀑布流,但会改变元素视觉顺序,注意无障碍影响。

grid-column / grid-row:项目跨轨

css 复制代码
.item {
  grid-column: 1 / 3;       /* 从第 1 条线跨到第 3 条线 = 占 2 列 */
  grid-column: span 2;      /* 跨 2 列,等价写法 */
  grid-row: 1 / -1;         /* -1 表示最后一条线,占满全部行 */
}

网格线从 1 开始编号,负值从末尾倒数。

grid-template-areas:命名布局

给网格区域命名,直观表达页面结构。

css 复制代码
.container {
  grid-template-areas:
    "header header header"
    "sidebar content content"
    "footer footer footer";
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer; }

区域必须组成矩形,不规则形状无效。

对齐属性

  • place-items :控制项目在各自单元格内的对齐(align-items + justify-items 简写)。
  • place-content :控制整个网格在容器内的对齐(align-content + justify-content 简写)。
css 复制代码
.container {
  place-items: center;      /* 每个单元格内居中 */
  place-content: center;    /* 整个网格在容器内居中 */
}

auto-fill 和 auto-fit

两者的差异仅在空间有剩余时体现:

  • auto-fill:保留空轨道占位,空间有多余时留白。
  • auto-fit:折叠空轨道,已有项目拉伸填满。
css 复制代码
/* 两者在内容溢出时行为一致,差异在内容不足时 */
.container { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
/* 一行只放 3 个卡片时:auto-fill 右边留白,auto-fit 卡片拉伸填满 */

三、多列布局

多列布局专为文本流设计,让长文自动分列,类似报纸排版。与 Grid 不同,它不创建二维网格,而是让内容像水流一样自动灌入各列。

column-count / column-width

css 复制代码
.container {
  column-count: 3;              /* 固定列数 */
  column-width: 250px;          /* 固定列宽,列数由容器宽度自动计算 */
  columns: 3 250px;             /* 简写:列数 + 列宽 */
}

column-widthcolumn-count 同时设置时,以 column-count 为最大列数上限。

column-gap / column-rule

css 复制代码
.container {
  column-gap: 30px;             /* 列间距 */
  column-rule: 1px solid #ddd;  /* 列间分隔线,语法同 border */
}

column-rule 不占空间,仅视觉分割。

column-span: all

让某个子元素跨越多列,常用于文章中的小标题。

css 复制代码
h2 { column-span: all; }

注意:Firefox 早期不支持,现在已全面可用。

break-inside: avoid

防止元素在多列中断裂,保证卡片、图片等整体在一列内。

css 复制代码
.card {
  break-inside: avoid;          /* 避免内容被拆分到不同列 */
}

适用场景

长文排版(博客正文、帮助文档)用多列可提升阅读体验;卡片列表用 Grid,不建议用多列------多列的列高不可控,且项目顺序是"从上到下再从左到右",不符合大多数 UI 的阅读习惯。

四、2D/3D 变换

transform 在元素渲染的最后阶段生效,不影响文档流 ------元素变形后原位置仍被占据,类似 position: relative 的占位行为。

2D 变换核心函数

css 复制代码
.element {
  transform: translate(20px, 10px);     /* 平移:右移 20px,下移 10px */
  transform: translateX(20px);          /* 仅水平平移 */
  transform: translateY(-10px);         /* 仅垂直平移(负值向上) */
  transform: rotate(45deg);             /* 旋转 45 度 */
  transform: scale(1.2);               /* 缩放 1.2 倍 */
  transform: scale(1.2, 0.8);          /* 水平 1.2,垂直 0.8 */
  transform: skew(10deg, 5deg);        /* 倾斜 */
}

translate 的百分比相对于元素自身尺寸 ------这是用 translate(-50%, -50%) 实现绝对定位居中的原理。

transform-origin:变换原点

默认原点在元素中心 (50% 50%)。旋转和缩放围绕此点进行。

css 复制代码
.element { transform-origin: top left; }     /* 原点在左上角 */
.element { transform-origin: 0 100%; }       /* 原点在左下角 */

3D 变换

三个前置条件:① 父级设 perspective 提供景深,② 父级设 transform-style: preserve-3d 保持 3D 空间,③ 必要时 backface-visibility: hidden 隐藏背面。

css 复制代码
.scene {
  perspective: 800px;                   /* 景深,值越小 3D 效果越强烈 */
  transform-style: preserve-3d;         /* 保持子元素在 3D 空间内 */
}
.card {
  transform: rotateY(180deg);           /* 绕 Y 轴翻转 */
  backface-visibility: hidden;          /* 翻转后隐藏背面 */
}

3D 平移:translateZ(50px)(向屏幕外移动)、translate3d(x, y, z)。3D 旋转:rotateX() / rotateY() / rotate3d()

注意:transform 多个函数的书写顺序影响最终结果------先右乘 ,书写靠右的函数先执行。transform: rotate(45deg) translateX(100px)translateX(100px) rotate(45deg) 结果不同,因为前者先移动再旋转(移动方向已偏转 45 度)。

常见模式

绝对居中(宽高未知)

css 复制代码
.center {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}

卡片 hover 浮起

css 复制代码
.card:hover { transform: translateY(-4px); }

卡片翻转

css 复制代码
.card-inner {
  transition: transform .6s;
  transform-style: preserve-3d;
}
.card:hover .card-inner { transform: rotateY(180deg); }
.front, .back { backface-visibility: hidden; }
.back { transform: rotateY(180deg); }

五、动画

CSS 动效分两层:过渡 描述属性值变化的平滑过程,关键帧动画定义多阶段状态序列。

transition:过渡

当元素属性值发生变化时(如 hover、class 切换),过渡让变化平滑展开。

css 复制代码
.box {
  transition-property: opacity, transform;   /* 参与过渡的属性 */
  transition-duration: .3s, .5s;             /* 对应时长 */
  transition-timing-function: ease;          /* 缓动函数 */
  transition-delay: 0s;                      /* 延迟 */
  /* 简写:transition: opacity .3s ease, transform .5s ease; */
}

常用 timing-function

特征 场景
ease 快起 → 慢 → 慢停(默认) 大多数 UI 过渡
linear 匀速 颜色渐变、无限旋转动画
ease-in-out 慢起 → 快 → 慢停 模态框出入
cubic-bezier(.4, 0, .2, 1) 自定义曲线 需要精确控制节奏时

注意:并非所有属性都能过渡。displaybackground-image(渐变除外)等不可过渡;能过渡的包括 opacitytransformcolorwidth/height 等数值型属性。优先过渡 opacitytransform------它们只触发合成阶段,性能最优,不引起重排。

过渡触发后立即完成,无法暂停或循环。需要更复杂的控制时用 animation

animation:关键帧动画

css 复制代码
/* 定义 */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 使用 */
.element {
  animation-name: fadeIn;
  animation-duration: .4s;
  animation-timing-function: ease;
  animation-delay: 0s;
  animation-iteration-count: 1;            /* infinite 无限循环 */
  animation-direction: normal;             /* alternate 交替反向 */
  animation-fill-mode: forwards;           /* 结束后保持终态 */
  animation-play-state: running;           /* paused 暂停 */
  /* 简写:animation: fadeIn .4s ease forwards; */
}

关键属性解析:

  • animation-fill-mode: forwards:动画结束后保留最后一帧状态,避免跳回初始值。日常使用率极高。
  • animation-play-state: paused:hover 时暂停动画,常用于轮播和加载指示器。
  • animation-direction: alternate :奇数次正向,偶数次反向,配合 infinite 实现来回动画。

@keyframes 百分比

多阶段动画用百分比:

css 复制代码
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

常见模式

淡入 + 滑入

css 复制代码
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

无限旋转(loading)

css 复制代码
@keyframes spin {
  to { transform: rotate(360deg); }
}
.spinner { animation: spin .8s linear infinite; }

骨架屏闪烁

css 复制代码
@keyframes shimmer {
  100% { background-position: 200% 0; }
}
.skeleton {
  background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}

hover 时的过渡暂停与恢复

css 复制代码
.carousel { animation: slide 10s linear infinite; }
.carousel:hover { animation-play-state: paused; }   /* hover 暂停轮播 */

总结

  1. 定位处理元素与文档流的关系------脱离流(absolute/fixed)、半脱离(sticky)、微调(relative)和层叠(z-index)。
  2. Grid 处理二维布局------用轨道定义(grid-template-*)画结构,用 fr/auto-fill/minmax 做响应式,用 grid-area 命名语义化。
  3. 多列 处理长文本排版------用 column-count/column-width 分列,column-rule 分隔,break-inside: avoid 防断裂。
  4. 变换 在合成阶段调整视觉------用 translate/rotate/scale 做 2D 变形,加 perspective + preserve-3d 进入 3D。
  5. 过渡动画 处理时间维度------过渡管"从 A 到 B"的平滑,动画管"多阶段循环"的编排。优先操作 opacitytransform 保性能。
相关推荐
ljt27249606611 小时前
Vue笔记(二)--组件的属性和方法
前端·vue.js·笔记
Boop_wu1 小时前
[前端] CSS 常用样式(聊天界面 / 网页布局专用)
前端·css·css3
声声codeGrandMaster1 小时前
React框架的基础代码使用
前端·react.js·前端框架
叫我少年1 小时前
Vue 3 集成 Vue Router:从基础配置到项目实践
前端·路由
Highcharts.js1 小时前
Highcharts React 5.0 正式版:支持 ES 模块化、组件更精简、开发体验全面升级
前端·javascript·react.js·elasticsearch·前端框架·highcharts
大江东去浪淘尽千古风流人物1 小时前
【X-Restormer++】全天候图像恢复赛冠军方案:三项创新解析及对VIO/SLAM前端的工程价值
前端
LaughingZhu1 小时前
Claude Code 时代的写作:为什么 HTML 正在取代 Markdown
前端·人工智能·html
Shadow(⊙o⊙)1 小时前
qt中自定义槽函数 内部继承逻辑、GUI+CLI协同1.0
开发语言·前端·c++·qt
hexu_blog2 小时前
前端VUE后端java实现智能抠图
前端·javascript·vue.js·java处理抠图·vue实现智能抠图