如何使用位置:使用纯CSS和Bootstrap粘住侧边栏

来自菜鸟教程
跳转至:导航、​搜索

介绍

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

过去,此功能经常通过 JavaScript 计算来实现,以检测滚动位置并将元素的 position 切换为 absolutefixed

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

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

先决条件

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

要完成本教程,您需要:

第 1 步 — 使用 position: sticky

使用 position: sticky 的规范要求使用 auto 以外的值指定像 topbottom 这样的方向。

使用此属性的 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>

此代码创建一个具有 sticky 类的 div 和另一个具有 placeholder 类的 div ,它是视口的全高。

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

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

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

检查浏览器支持的一种工具是 Can I Use。 此时,Can I Use page for position: sticky 报告 Internet Explorer 中不支持 position: sticky。 支持现代版本的 Edge、Firefox、Chrome、Safari 和 Opera。 还有两个值得注意的已知问题,即 position: sticky 的某些方面在某些浏览器中的行为不符合预期。

position: sticky 的合理回退是 position: 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 库来实现这一点。

这是预期布局的图表:

title-section 跨越页面顶部。 content-section 占据屏幕左侧的大部分。 多个侧边栏元素占据屏幕右侧:container 1container 2container 3container 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 时,您应该看到一个内容部分和多个侧边栏项目。

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

索引.html

<style>
  /* ... */

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

  /* ... */
</style>

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

尝试堆叠所有侧边栏项目

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

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

由于本演示中侧边栏项目的数量及其高度是已知的,因此您可以使用 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 时,您应该看到一个内容部分和多个侧边栏项目,它们之间有空格。 向下滚动时,您应该观察侧边栏项目的堆叠。

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

尝试将侧边栏项目推离屏幕

继续以前面的例子为基础,一个限制较少的替代方法可能是将前面的侧边栏项目“推”出屏幕。

首先,您应该删除以前使用 nth-child 的实验。

此新配置将为 .sidebar-item 使用 flex-grow 属性:

索引.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 时,您应该看到一个内容部分和多个侧边栏项目。 向下滚动时,您应该观察到“堆叠”行为,因为侧边栏项目会“推动”前一个侧边栏项目。

注意: 由于当时在 Web 浏览器中使用 display: flexboxposition: sticky 时遇到的限制,本教程的上一版本使用 position: absolute 方法。

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

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


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

结论

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

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

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