如何使用 Position: Sticky for Sidebars with Pure CSS and Bootstrap

介绍

粘性侧边栏是一种网页设计技术,即使用户已经滚动到它最初显示的位置,也可以将侧边栏保持在屏幕上。这对于使子导航易于访问、在用户滚动时更多地突出侧栏中的内容以及可能增加您的广告展示次数、点击次数和页面浏览量非常有用。

过去,此功能经常通过 JavaScript 计算来完成,以检测滚动位置并将元素切换positionabsolutefixed

目前,W3C 规范已经定义了sticky定位,许多现代浏览器已经采用了它。

在本教程中,您将创建一个带有侧边栏的网页,该网页使用position: stickyBootstrap 4。

先决条件

此演示不需要任何本地环境设置。您可以使用您选择的代码编辑器和浏览器。

要完成本教程,您需要:

步骤 1 — 使用 position: sticky

using 的规范position: sticky需要一个类似topor的方向bottom,指定一个不是 的值auto

使用此属性的 CSS 类示例如下所示:

.sticky {
  position: sticky;
  top: 0;
}

要体验position: sticky,可以新建一个项目目录:

  • mkdir position-sticky-example

并切换到该目录:

  • cd position-sticky-example

在此项目目录中,example.html使用以下代码创建一个文件:

示例.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Sticky Position Example</title>
    <style>
      * {
        box-sizing: border-box;
      }

      html,
      body {
        margin: 0;
        padding: 0;
      }

      .placeholder-example {
        background: lavender;
        height: 100vh;
        padding: 1em;
      }

      .sticky-example {
        background: cornflowerblue;
        padding: 1em;
      }

      .sticky {
        position: sticky;
        top: 0;
      }
    </style>
  </head>
  <body>
    <div class="sticky-example sticky">Sticky</div>
    <div class="placeholder-example">Placeholder</div>
  </body>
</html>

此代码创建一个divsticky类和其他divplaceholder是视口的全高度类。

index.html在您的网络浏览器中打开并观察position: sticky您上下滚动页面时的行为。

检查浏览器支持和使用回退

在采用新的 CSS 属性之前,您应该研究各种浏览器对它的支持程度。如果目标受众的浏览器不支持某个功能,那么它可能不适合在您的项目中采用。

检查浏览器支持的一种工具是Can I Use此时,“我可以使用”页面用于position: sticky报告position: stickyInternet Explorer不支持的报告支持 Edge、Firefox、Chrome、Safari 和 Opera 的现代版本。并且有两个已知的问题,其中某些方面的position: sticky行为在某些浏览器中不符合预期。

一个明智的回退position: stickyposition: relative. 它不会导致相同的浏览器体验,但会确保使用不受支持的浏览器的用户仍然可以访问position: sticky元素中的内容

您可能还需要考虑为 CSS 属性使用供应商前缀,例如position: -webkit-sticky,以解决旧版本的 Safari 和 iOS Safari。

sticky具有后备支持的重写类将类似于:

.sticky {
  position: relative;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

此代码利用浏览器如何忽略它无法识别的属性值并仅使用最后一个有效值。

position: sticky行为的简要介绍到此结束让我们看看将其应用于高级场景。

第 2 步 — 使用 Bootstrap 4 构建粘性侧边栏

所需的布局将有一个侧边栏,将位于一长段内容旁边。您可以使用 Bootstrap 4 库来实现这一点。

这是预期布局的图表:

所需布局的图表,左侧有一个内容部分,右侧有一个侧边栏部分,侧栏中有多个项目。

Atitle-section跨越页面顶部。Acontent-section占据了屏幕左侧的大部分。多侧边栏元素占据了屏幕的右侧:container 1container 2container 3,和container n

创建一个新index.html文件并添加 Bootstrap 4 库:

索引.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Sticky Position Sidebar</title>
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
      integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
      crossorigin="anonymous"
    />
    <style>
    </style>
  </head>
<body>
</body>
</html>

为了实现所需的布局,您的body内容需要采用 Bootstrap 标记结构:

索引.html
<body>
  <article>
    <div class="container-fluid">
      <div class="row">
        <div class="col">
          <div class="title-section">
            <h1>Stacking Sticky Sidebars with Bootstrap 4</h1>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-7">
          <div class="content-section">
            Content Section
          </div>
        </div>
        <div class="col-5">
          <div class="sidebar-section">
            <div class="sidebar-item">
              <div class="sidebar-content">
                Container 1
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </article>
</body>

此标记建立了一个content-section可延伸 7 个列宽的区域和一个可延伸 5 个列宽的侧边栏部分。这总共有 12 列,这是 Bootstrap 4 中的默认网格系统。

申请 sticky-top

Bootstrap 4 还附带了一个名为的实用程序类sticky-top该类在功能上与sticky您之前创建相同

在应用之前sticky-top,添加一些样式以帮助使内容和侧边栏部分在视觉上更加明显:

索引.html
<style>
  .content-section {
    background: lavender;
    height: 1000px;
    min-height: 100vh;
    padding: 1em;
  }

  .sidebar-section {
    height: 100%;
  }

  .sidebar-content {
    background: cornflowerblue;
    padding: 1em;
  }
</style>

此代码为内容和侧边栏部分定义了background-colorheightpadding

注:height这里规定的内容部分是用于演示目的的任意量。如果您的内容足够大,您可以依靠它来定义您的布局并删除该height属性。

index.html在您的网络浏览器中访问时,您应该看到一个内容部分和一个较小的侧边栏部分。

现在,将sticky-top添加sidebar-item

索引.html
<div class="col-5">
  <div class="sidebar-section">
    <div class="sidebar-item sticky-top">
      <div class="sidebar-content">
        Container 1
      </div>
    </div>
  </div>
</div>

向下滚动页面时,侧边栏应该具有“粘性”行为。

这可能是大多数情况下最常见的功能请求。接下来的步骤将探索更具想象力的场景。

第 3 步 — 试验高级场景

在下面的部分中,您将使用index.html之前创建文件并探索添加多个项目、堆叠侧边栏项目以及最后将侧边栏项目推离屏幕。

尝试使用粘性侧边栏和多个项目

在示例的基础上,您可以向侧边栏添加其他项目:

索引.html
<div class="col-5">
  <div class="sidebar-section">
    <div class="sidebar-item sticky-top">
      <div class="sidebar-content">
        Container 1
      </div>
    </div>

    <div class="sidebar-item sticky-top">
      <div class="sidebar-content">
        Container 2
      </div>
    </div>

    <div class="sidebar-item sticky-top">
      <div class="sidebar-content">
        Container 3
      </div>
    </div>

    <div class="sidebar-item sticky-top">
      <div class="sidebar-content">
        Container 4
      </div>
    </div>
  </div>
</div>

index.html在您的网络浏览器中访问时,您应该看到一个内容部分和多个侧边栏项目。

如果您将侧边栏部分转换为一个 flexbox,其中的项目排列在columnwith 中space-between,您可以创建一个视觉上更有趣的侧边栏:

索引.html
<style>
  /* ... */

  .sidebar-section {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
  }

  /* ... */
</style>

index.html在您的网络浏览器中访问时,您应该观察一个内容部分和多个侧边栏项目,它们之间有空间。向下滚动时,您应该观察到侧边栏项目变得粘在屏幕顶部。

尝试堆叠所有侧边栏项目

一个常见的功能要求是将所有侧边栏项目“堆叠”在屏幕上。

这需要知道height每个侧边栏项目的 ,并抵消粘性top值。您将提供前面侧边栏项目的高度总和,而不是top: 0提供的默认值sticky-top

由于侧边栏项目的数量及其高度在本演示中是已知的,您可以使用以下方法将偏移量应用于每个侧边栏项目nth-child

索引.html
<style>
  /* ... */

  .sidebar-item:nth-child(2) {
    top: 3.5em;
  }

  .sidebar-item:nth-child(3) {
    top: 7em;
  }

  .sidebar-item:nth-child(4) {
    top: 10.5em;
  }

  /* ... */
</style>

index.html在您的网络浏览器中访问时,您应该观察一个内容部分和多个侧边栏项目,它们之间有空间。向下滚动时,您应该观察侧边栏项目堆叠。

但是,这仅限于知道侧边栏包含4每个3.5em高的侧边栏项目的情况任何额外的复杂性都会强调纯 CSS 的局限性,您的时间可能更适合使用 JavaScript 解决方案。

尝试将侧边栏项目推送到屏幕外

继续构建前一个示例,一个较少限制的替代方法可能是将前一个侧边栏项目“推”出屏幕。

首先,您应该使用nth-child.

此新配置将使用以下flex-grow属性.sidebar-item

索引.html
<style>
  /* ... */

  .sidebar-item {
    flex-grow: 1;
  }

  /* ... */
</style>

现在,将sticky-top类从sidebar-item元素移动sidebar-content元素:

索引.html
<div class="col-5">
  <div class="sidebar-section">
    <div class="sidebar-item">
      <div class="sidebar-content sticky-top">
        Container 1
      </div>
    </div>

    <div class="sidebar-item">
      <div class="sidebar-content sticky-top">
        Container 2
      </div>
    </div>

    <div class="sidebar-item">
      <div class="sidebar-content sticky-top">
        Container 3
      </div>
    </div>

    <div class="sidebar-item">
      <div class="sidebar-content sticky-top">
        Container 4
      </div>
    </div>
  </div>
</div>

index.html在您的网络浏览器中访问时,您应该看到一个内容部分和多个侧边栏项目。向下滚动时,您应该观察到“堆叠”行为,因为侧边栏项目“推”了前一个侧边栏项目。

注意:本教程的先前版本使用了一种position: absolute方法,这是由于当时 Web 浏览器display: flexboxposition: sticky浏览器中所经历的限制

此 CodePen 示例描述了该position: absolute方法。

但是,在本次修订时,此flexbox方法提供了更大的灵活性,并且需要较少地处理不同数量的侧边栏项目、高度和偏移量。

可以通过调整宽度、高度和偏移量来执行进一步的实验。

结论

在本教程中,您了解了 CSS 属性position: sticky以及如何将其用于网页设计布局中的侧边栏。

请记住,由于浏览器支持存在限制。position: absolute根据受众的浏览器使用情况,您可能需要回退到 JavaScript 或替代方法。

如果您想了解有关 CSS 的更多信息,请查看我们的 CSS 主题页面以获取练习和编程项目。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁