第19篇:定位系统详解(下)

第19篇:定位系统详解(下) 第19篇定位系统详解下本篇继续讲解定位系统的剩余两种模式固定定位fixed和粘性定位sticky。它们分别解决了始终在视口某位置和到达某位置后固定的布局需求是现代网页中不可或缺的定位工具。学习目标掌握固定定位fixed的特性与使用场景掌握粘性定位sticky的行为与限制条件理解 fixed 定位在滚动容器中的特殊情况学会使用 inset 简写属性了解定位相关的现代 CSS 技巧核心知识点一、固定定位 fixed元素相对于视口定位不随页面滚动而移动。.fixed-header{position:fixed;top:0;left:0;right:0;height:60px;background:white;box-shadow:0 2px 8pxrgba(0,0,0,0.1);z-index:100;}特性完全脱离文档流不占据布局空间参照物永远是视口不受任何祖先元素影响创建新的层叠上下文z-index生效宽度收缩为内容宽度需要显式设置宽高/* 固定在右下角 */.back-to-top{position:fixed;bottom:24px;right:24px;width:48px;height:48px;/* ... */}/* 全屏遮罩 */.overlay{position:fixed;inset:0;/* 填满整个视口 */background:rgba(0,0,0,0.5);}页面布局偏移问题fixed 元素不占据空间后面的内容会顶上去body{padding-top:60px;/* 为固定导航栏预留空间 */}二、粘性定位 sticky元素在滚动到达某个阈值前表现为相对定位到达阈值后表现为固定定位。.sticky-nav{position:sticky;top:0;/* 距离视口顶部 0px 时粘住 */background:white;z-index:10;}关键点不脱流占据正常布局空间需要阈值至少设置top、right、bottom、left中的一个在容器内生效不会超出父容器的边界父元素overflow:hidden会失效如果祖先有overflow: hidden/scroll/autosticky 可能失效粘性定位的生命周期┌─────────────────────────────────┐ │ 视口 │ │ ┌──────────────┐ │ │ │ sticky 元素 │ ← 还在滚动中 │ │ └──────────────┘ 相对定位行为 │ │ │ └─────────────────────────────────┘ ↓ 继续滚动 ┌─────────────────────────────────┐ │ 视口 │ │ ┌──────────────┐ │ │ │ │ │ │ ├──────────────┤ ← 粘在顶部 │ │ │ sticky 元素 │ 固定定位行为 │ │ └──────────────┘ │ └─────────────────────────────────┘常见用法/* 粘性表头 */th{position:sticky;top:0;background:#f9fafb;}/* 粘性侧边栏目录 */.toc{position:sticky;top:80px;/* 为顶部导航预留空间 */align-self:start;/* 在 flex/grid 布局中需要 */}/* 多级粘性标题 */h2{position:sticky;top:60px;/* 一级标题 */background:white;}h3{position:sticky;top:100px;/* 二级标题在一级下方 */background:white;}三、fixed 在滚动容器中的特殊情况transform 的影响如果 fixed 元素的祖先设置了transformfixed 会变成相对于该祖先定位.modal{transform:translate(-50%,-50%);/* 创建新的包含块 */}.modal .fixed-child{position:fixed;/* 实际上是相对于 .modal不是视口 */}这是 CSS 规范定义的行为transform、filter、perspective、will-change等属性会创建新的包含块fixed 元素会相对于这个包含块定位。解决方案!-- 把 fixed 元素移出 transform 祖先 --divclassmodal-wrapperdivclassmodal/div/divdivclassmodal-backdrop/div!-- fixed在 wrapper 外面 --四、inset 简写属性inset是top/right/bottom/left的简写。/* 四值top right bottom left */.overlay{inset:10px 20px 30px 40px;}/* 三值top (right/left) bottom */.overlay{inset:10px 20px 30px;}/* 两值(top/bottom) (right/left) */.overlay{inset:10px 20px;}/* 一值四边相同 */.overlay{inset:0;/* 最常用的写法填满定位上下文 */}inset现代浏览器全部支持是编写定位代码的利器。五、定位实战回到顶部按钮.back-to-top{position:fixed;bottom:32px;right:32px;width:44px;height:44px;border-radius:50%;background:#4a90d9;color:white;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12pxrgba(74,144,217,0.4);opacity:0;transform:translateY(20px);transition:opacity 0.3s,transform 0.3s;pointer-events:none;}.back-to-top.visible{opacity:1;transform:translateY(0);pointer-events:auto;}六、定位实战吸顶导航.site-header{position:sticky;top:0;background:rgba(255,255,255,0.9);backdrop-filter:blur(8px);border-bottom:1px solid #e5e7eb;z-index:100;}七、定位属性对比总结属性参照物是否脱流是否占位滚动行为static无否是正常滚动relative自身否是正常滚动absolute定位祖先是否随容器滚动fixed视口是否不随滚动sticky视口容器否是到达阈值后固定动手练习练习 1吸顶导航栏实现一个页面导航栏页面顶部有导航栏滚动后导航栏吸在顶部吸顶时有阴影效果练习 2固定侧边目录创建一个文章页面左侧是文章目录目录使用 sticky 定位滚动时保持可见右侧是文章正文练习 3模态框系统实现一个模态框半透明黑色遮罩覆盖全屏fixed白色对话框在屏幕正中关闭按钮在对话框右上角absolute使用inset: 0简化遮罩样式常见误区 ⚠️误区真相“fixed永远相对于视口”错误如果祖先有transform/filter/perspectivefixed 会相对于该祖先“sticky和fixed一样”完全不同sticky 不脱流且在父容器边界内生效“sticky不生效是浏览器 bug”最可能是祖先有overflow: hidden/scroll/auto或没有设置阈值top/left等“inset兼容性不好”现代浏览器全部支持可以放心使用“position: sticky不需要 z-index”吸顶元素很可能被后面的定位元素覆盖建议设置 z-index“fixed 元素会遮挡点击”需要设置pointer-events: none让鼠标穿透或调整 z-index速查卡片 fixed 定位.back-to-top{position:fixed;bottom:24px;right:24px;}sticky 定位.header{position:sticky;top:0;}全屏遮罩.overlay{position:fixed;inset:0;background:rgba(0,0,0,0.5);}居中模态框.modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);}扩展阅读MDN: positionMDN: insetCSS-Tricks: position: sticky英文Web.dev: CSS position英文配套代码CODE/19/fixed-sticky-demo.html — fixed 与 sticky 行为演示CODE/19/modal-backtop.html — 模态框与回到顶部实战下一步进入第20篇Flexbox 基础与容器属性开始现代 CSS 布局的学习。