CSS position: sticky 属性值
position: sticky 是 CSS 定位属性中相对较新的值。粘性定位是相对定位和固定定位的混合体:元素在跨越指定的阈值之前表现得像相对定位,之后表现得像固定定位。
这是实现"吸顶导航"、"表格标题固定"等效果的现代解决方案。
单词释义:sticky 意为"粘性的",表示元素会"粘"在某个位置不动。
基本语法
position: sticky 需要配合至少一个方向(top、right、bottom、left)的阈值来指定"粘性"生效的位置。
/* 语法 */
position: sticky;
/* 常用组合:滚动到距离顶部 10px 时固定 */
.sticky-header {
position: sticky;
top: 10px;
}
工作原理
sticky 定位的工作方式可以分解为两个阶段:
阶段 1:正常滚动(相对定位)
当元素在视口中未达到指定的阈值时,元素按照正常文档流布局,会随页面滚动移动。此时它相当于 position: relative。
阶段 2:固定显示(固定定位)
当元素滚动到超过指定的阈值时,元素固定在那个位置,不再随页面滚动。此时它相当于 position: fixed。
阈值条件
| 属性 | 触发条件 |
|---|---|
top: 10px |
元素顶部距离视口顶部 > 10px 时固定 |
bottom: 10px |
元素底部距离视口底部 > 10px 时固定 |
left: 10px |
元素左边距离视口左边 > 10px 时固定 |
right: 10px |
元素右边距离视口右边 > 10px 时固定 |
核心特性
特性 1:双向行为
sticky 兼具 relative 和 fixed 的特点,是两者的完美结合。
特性 2:不需要父元素设置定位
与 absolute 不同,sticky 元素不需要父元素设置任何定位属性。
特性 3:父容器overflow的限制
如果父元素设置了 overflow: hidden、overflow: auto 或 overflow: scroll,sticky 定位可能会失效。
特性 4:激活 z-index
sticky 定位会激活 z-index 属性。
实例
让我们通过实例深入理解 position: sticky 的特性。
示例 1:吸顶导航栏
这是 sticky 定位最常见的应用:实现吸顶导航栏。
实例
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
}
/* 页面顶部大图区域 */
.hero {
height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 36px;
font-weight: bold;
}
/* 粘性导航栏 */
.sticky-nav {
position: sticky;
top: 0; /* 滚动到顶部时固定 */
background-color: #2c3e50;
color: white;
padding: 15px 30px;
z-index: 100;
}
.sticky-nav ul {
list-style: none;
display: flex;
gap: 30px;
max-width: 800px;
margin: 0 auto;
}
.sticky-nav a {
color: white;
text-decoration: none;
}
/* 内容区域 */
.content {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.section {
margin-bottom: 40px;
padding: 20px;
background-color: #f5f5f5;
border-radius: 4px;
}
.tall-spacer {
height: 1500px;
}
</style>
</head>
<body>
<div class="hero">
RUNOOB 教程
</div>
<nav class="sticky-nav">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">教程</a></li>
<li><a href="#">实例</a></li>
<li><a href="#">工具</a></li>
<li><a href="#">关于</a></li>
</ul>
</nav>
<div class="content">
<div class="section">
<h2>第一章:入门</h2>
<p>这是第一章的内容。向下滚动查看导航栏的粘性效果。</p>
</div>
<div class="section">
<h2>第二章:进阶</h2>
<p>这是第二章的内容。</p>
</div>
<div class="section">
<h2>第三章:高级</h2>
<p>这是第三章的内容。</p>
</div>
<div class="section">
<h2>第四章:实战</h2>
<p>这是第四章的内容。</p>
</div>
<div class="section">
<h2>第五章:项目</h2>
<p>这是第五章的内容。</p>
</div>
<div class="tall-spacer"></div>
</div>
</body>
</html>
示例 2:表格标题行固定
sticky 定位非常适合用于固定表格的表头:
实例
<html>
<head>
<style>
.table-container {
max-width: 600px;
max-height: 300px;
overflow-y: auto; /* 需要设置 overflow 才能看到固定效果 */
border: 2px solid #ddd;
}
table {
width: 100%;
border-collapse: collapse;
}
/* 表头使用 sticky 定位 */
th {
position: sticky;
top: 0;
background-color: #3498db;
color: white;
padding: 12px;
text-align: left;
}
td {
padding: 10px 12px;
border-bottom: 1px solid #eee;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
</style>
</head>
<body>
<h2>学生成绩表</h2>
<p>向下滚动查看表头固定效果:</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>语文</th>
<th>数学</th>
<th>英语</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>张三</td>
<td>85</td>
<td>92</td>
<td>88</td>
</tr>
<tr>
<td>002</td>
<td>李四</td>
<td>90</td>
<td>87</td>
<td>95</td>
</tr>
<tr>
<td>003</td>
<td>王五</td>
<td>78</td>
<td>85</td>
<td>82</td>
</tr>
<tr>
<td>004</td>
<td>赵六</td>
<td>92</td>
<td>88</td>
<td>90</td>
</tr>
<tr>
<td>005</td>
<td>钱七</td>
<td>88</td>
<td>91</td>
<td>87</td>
</tr>
<tr>
<td>006</td>
<td>孙八</td>
<td>85</td>
<td>89</td>
<td>93</td>
</tr>
<tr>
<td>007</td>
<td>周九</td>
<td>80</td>
<td>86</td>
<td>84</td>
</tr>
<tr>
<td>008</td>
<td>吴十</td>
<td>91</td>
<td>93</td>
<td>89</td>
</tr>
<tr>
<td>009</td>
<td>郑十一</td>
<td>87</td>
<td>85</td>
<td>88</td>
</tr>
<tr>
<td>010</td>
<td>陈十二</td>
<td>89</td>
<td>90</td>
<td>91</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
示例 3:侧边栏粘性效果
当页面内容很长时,可以让侧边栏在滚动到一定位置后固定:
实例
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
}
.container {
display: grid;
grid-template-columns: 1fr 200px;
max-width: 900px;
margin: 0 auto;
}
.main-content {
padding: 20px;
}
/* 粘性侧边栏 */
.sidebar {
position: sticky;
top: 20px; /* 距离顶部 20px 时固定 */
height: fit-content;
background-color: #3498db;
color: white;
padding: 15px;
border-radius: 4px;
}
.content-block {
background-color: #f5f5f5;
padding: 20px;
margin-bottom: 20px;
border-radius: 4px;
}
.tall-block {
height: 800px;
}
</style>
</head>
<body>
<div class="container">
<div class="main-content">
<h1>主内容区域</h1>
<p>向下滚动查看侧边栏的粘性效果。</p>
<div class="content-block">
<h2>内容区域 1</h2>
<p>这是第一段内容。</p>
</div>
<div class="content-block">
<h2>内容区域 2</h2>
<p>这是第二段内容。</p>
</div>
<div class="content-block">
<h2>内容区域 3</h2>
<p>这是第三段内容。</p>
</div>
<div class="content-block tall-block">
<h2>长内容区域</h2>
<p>这是比较长的内容区域,用来展示侧边栏的粘性效果。</p>
<p>继续向下滚动...</p>
</div>
<div class="content-block">
<h2>内容区域 4</h2>
<p>这是第四段内容。</p>
</div>
<div class="content-block">
<h2>内容区域 5</h2>
<p>这是第五段内容。</p>
</div>
</div>
<aside class="sidebar">
<h3>侧边栏</h3>
<p>我会粘在右侧</p>
<p>直到滚动出视口</p>
</aside>
</div>
</body>
</html>
示例 4:分段标题固定
sticky 定位非常适合用于文章的分段标题固定:
实例
<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
/* 分段标题固定 */
.chapter-title {
position: sticky;
top: 0;
background-color: #2c3e50;
color: white;
padding: 15px;
margin: 20px 0 10px;
border-radius: 4px;
}
.content {
padding: 0 15px;
line-height: 1.8;
margin-bottom: 30px;
}
.tall-content {
height: 600px;
}
</style>
</head>
<body>
<h1>书籍章节示例</h1>
<div class="chapter-title">第一章:初识编程</div>
<div class="content">
<p>编程是一门创造性的艺术。本章将带你了解什么是编程,以及为什么学习编程如此重要。</p>
</div>
<div class="chapter-title">第二章:环境搭建</div>
<div class="content tall-content">
<p>在开始编写代码之前,我们需要先搭建开发环境。本章介绍如何安装必要的工具和配置开发环境。</p>
<p>内容区域足够长,以便产生滚动效果。</p>
</div>
<div class="chapter-title">第三章:基础语法</div>
<div class="content">
<p>本章介绍编程语言的基础语法,包括变量、数据类型、运算符等核心概念。</p>
</div>
<div class="chapter-title">第四章:控制结构</div>
<div class="content tall-content">
<p>控制结构决定了程序的执行顺序。介绍条件语句和循环语句的使用方法。</p>
</div>
<div class="chapter-title">第五章:函数</div>
<div class="content">
<p>函数是组织代码的基本单元。本章讲解如何定义和调用函数。</p>
</div>
</body>
</html>
示例 5:双向粘性定位
可以同时设置水平和垂直方向的粘性定位:
实例
<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
}
.calendar {
width: 350px;
border: 2px solid #ddd;
}
/* 星期标题行 - 顶部固定 */
.weekday {
position: sticky;
top: 0;
background-color: #3498db;
color: white;
padding: 10px;
text-align: center;
}
/* 时间列 - 左侧固定 */
.time-label {
position: sticky;
left: 0;
background-color: #ecf0f1;
padding: 20px 10px;
border-right: 1px solid #ddd;
font-weight: bold;
}
/* 日期单元格 */
.day-cell {
padding: 20px;
border: 1px solid #eee;
text-align: center;
}
.day-cell:nth-child(2) {
position: sticky;
left: 50px; /* 时间列宽度 + 边框 */
background-color: white;
}
/* 模拟日历网格 */
.calendar-grid {
display: grid;
grid-template-columns: 50px repeat(5, 1fr);
}
</style>
</head>
<body>
<h2>课程表(双向粘性)</h2>
<p>向下和向右滚动查看效果:</p>
<div class="calendar">
<div class="calendar-grid">
<!-- 星期标题行 -->
<div></div> <!-- 时间列空白 -->
<div class="weekday">周一</div>
<div class="weekday">周二</div>
<div class="weekday">周三</div>
<div class="weekday">周四</div>
<div class="weekday">周五</div>
<!-- 时间行 1 -->
<div class="time-label">8:00</div>
<div class="day-cell">数学</div>
<div class="day-cell">语文</div>
<div class="day-cell">英语</div>
<div class="day-cell">物理</div>
<div class="day-cell">化学</div>
<!-- 时间行 2 -->
<div class="time-label">9:00</div>
<div class="day-cell">英语</div>
<div class="day-cell">数学</div>
<div class="day-cell">化学</div>
<div class="day-cell">语文</div>
<div class="day-cell">物理</div>
<!-- 时间行 3 -->
<div class="time-label">10:00</div>
<div class="day-cell">物理</div>
<div class="day-cell">化学</div>
<div class="day-cell">数学</div>
<div class="day-cell">英语</div>
<div class="day-cell">语文</div>
<!-- 时间行 4 -->
<div class="time-label">11:00</div>
<div class="day-cell">语文</div>
<div class="day-cell">物理</div>
<div class="day-cell">数学</div>
<div class="day-cell">化学</div>
<div class="day-cell">英语</div>
</div>
</div>
</body>
</html>
注意事项
浏览器兼容性:
position: sticky在现代浏览器中得到良好支持,但 IE 浏览器完全不支持。如果需要支持 IE,需要使用 JavaScript 或其他 polyfill 方案作为降级处理。
父元素 overflow 的影响
如果父元素设置了以下属性,sticky 定位会失效:
overflow: hidden overflow: auto overflow: scroll
必须设置阈值
至少需要设置 top、right、bottom 或 left 中的一个,否则 sticky 不会生效(元素会按照正常文档流布局)。
阈值计算
sticky 定位的阈值是相对于视口计算的,而不是父元素。
与其它定位值的对比
| 定位值 | 是否脱离文档流 | 固定条件 | 兼容性 |
|---|---|---|---|
static |
否 | 无 | 所有浏览器 |
relative |
否 | 无 | 所有浏览器 |
absolute |
是 | 无 | 所有浏览器 |
fixed |
是 | 始终固定 | 所有浏览器 |
sticky |
阈值前否,阈值后是 | 滚动超过阈值 | 现代浏览器(IE 不支持) |
常见应用场景
场景 1:吸顶导航
.nav {
position: sticky;
top: 0;
}
场景 2:表格表头固定
th {
position: sticky;
top: 0;
}
场景 3:侧边栏固定
.sidebar {
position: sticky;
top: 20px;
}
场景 4:文章章节标题
.chapter-header {
position: sticky;
top: 0;
background: white; /* 固定时显示背景 */
}
总结
position: sticky 是现代网页布局中非常实用的技术:
- 是相对定位和固定定位的结合体
- 需要设置至少一个方向的阈值(top/right/bottom/left)
- 滚动超过阈值前:按照正常文档流布局(相对定位)
- 滚动超过阈值后:固定在当前位置(固定定位)
- 不需要父元素设置任何定位
- 父元素设置 overflow 会导致失效
- 现代浏览器支持良好,IE 不支持
- 常用于吸顶导航、表头固定、侧边栏固定、分段标题固定
CSS position 属性
点我分享笔记