在CSS中,position: sticky 是一种用于创建粘性布局的属性,它使得元素在页面滚动时可以在特定条件下保持可见。这种定位方式结合了相对定位(relative)和固定定位(fixed)的特点,在页面滚动到一定位置之前,元素按照正常文档流的位置显示;一旦页面滚动超过了设定的阈值,元素就会固定在视口中的某个位置,直到再次滚动回阈值以内。
MDN资源链接:https://developer.mozilla.org/zh-CN/docs/Web/CSS/position
元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block(最近块级祖先 nearest block-level ancestor),包括 table-related 元素,基于 top、right、bottom 和 left 的值进行偏移。偏移值不会影响任何其他元素的位置。 该值总是创建一个新的层叠上下文(stacking context)。注意,一个 sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的 overflow 是 hidden、scroll、auto 或 overlay 时),即便这个祖先不是最近的真实可滚动祖先。这有效地抑制了任何“sticky”行为)。
为了实现一个有效的粘性布局,你需要确保满足以下条件:
这是最常见的一种使用场景。当页面向下滚动时,导航栏可以粘贴在屏幕顶部,方便用户始终可以看到导航,快速跳转到不同页面,从而提高用户体验。
下面是一个简单的示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>页面标题</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
* {
margin: 0;
padding: 0;
font-family: "Source Sans Pro", -apple-system,
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
}
.nav {
padding: 0 2rem;
background-color: #007bff;
color: #fff;
height: 36px;
line-height: 36px;
text-align: center;
position: sticky;
top: 0px;
display: flex;
align-items: center;
}
.nav ul {
list-style: none;
display: flex;
align-items: center;
gap: 20px;
}
.nav ul li a {
color: #fff;
text-decoration: none;
}
.nav ul li a:hover {
text-decoration: underline;
}
.article-list {
padding: 20px;
}
.article-list div {
padding: 10px 14px;
border-radius: 0.2rem;
box-shadow: inset 0 -0.1rem 0 rgba(0, 0, 0, 0.25);
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="nav">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">文章</a></li>
<li><a href="#">照片</a></li>
<li><a href="#">关于我</a></li>
</ul>
</div>
<div class="article-list" id="article-list"></div>
<script>
const $articleListContainer = document.querySelector("#article-list");
for (let index = 1; index <= 100; index++) {
const element = document.createElement("div");
element.append(`${index}. 这是本站第 ${index} 篇文章。`);
$articleListContainer.append(element);
}
</script>
</body>
</html>
对于长表格来说,表头可能会随着滚动而消失,这会影响用户的阅读体验。可以通过将表头设置为 sticky,可以让其在滚动过程中始终显示在视口顶部,确保用户始终能看到每一列的数据含义。
请看下面这个示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>页面标题</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
* {
margin: 0;
padding: 0;
font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
}
table {
border-collapse: collapse;
border: 2px solid rgb(140 140 140);
font-family: sans-serif;
font-size: 0.8rem;
letter-spacing: 1px;
margin: 0 auto;
width: 610px;
height: 240px;
display: block;
overflow-x: auto;
}
caption {
caption-side: center;
padding: 10px;
font-weight: bold;
text-align: center;
}
tbody {
white-space: nowrap;
}
thead,
tfoot {
background-color: rgb(228 240 245);
}
th,
td {
border: 1px solid rgb(160 160 160);
padding: 8px 10px;
}
th {
position: sticky;
top: 0;
background: #fff;
vertical-align: bottom;
}
td:last-of-type {
text-align: center;
}
tbody>tr:nth-of-type(even) {
background-color: rgb(237 238 242);
}
</style>
</head>
<body>
<table>
<caption>
这是一个冻结表头的长表格
</caption>
<colgroup>
<col />
</colgroup>
<tbody>
<tr>
<th>名称</th>
<th>HEX</th>
<th>HSLa</th>
<th>RGBa</th>
</tr>
<tr>
<td>Teal</td>
<td><code>#51F6F6</code></td>
<td><code>hsla(180, 90%, 64%, 1)</code></td>
<td><code>rgba(81, 246, 246, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
<tr>
<td>Goldenrod</td>
<td><code>#F6BC57</code></td>
<td><code>hsla(38, 90%, 65%, 1)</code></td>
<td><code>rgba(246, 188, 87, 1)</code></td>
</tr>
</tbody>
</table>
<script>
</script>
</body>
</html>
总之,position: sticky 提供了一种简便的方法来创建交互式的用户体验,但它也有一些限制和注意事项,我们应该根据具体的应用场景合理选择是否使用以及如何优化其性能。