粘性页脚,五种方法

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

粘性页脚的目的是使其“粘贴”到浏览器窗口的底部。但并非总是如此,如果页面上有足够的内容将页脚向下推,它仍然会这样做。但如果页面上的内容较短,粘性页脚仍将悬挂在浏览器窗口的底部。

请注意,此处的“粘性”与上面描述的完全相同。不要将其与position: fixed;混淆,后者可用于即使页面滚动也能将元素“固定”到位。或者,更令人困惑的是,它也不是position: sticky;,后者类似于容器内的固定定位。

包装器上有负底部边距

有一个包装元素包含除页脚之外的所有内容。它具有等于页脚高度的负边距。这是此方法的基础。

<body>
  <div class="wrapper">

      content

    <div class="push"></div>
  </div>
  <footer class="footer"></footer>
</body>
html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  min-height: 100%;

  /* Equal to height of footer */
  /* But also accounting for potential margin-bottom of last child */
  margin-bottom: -50px;
}
.footer,
.push {
  height: 50px;
}

查看 Chris Coyier 在 CodePen 上编写的笔 使用 calc() 实现粘性页脚 (@chriscoyier)。

此方法需要在内容区域内添加一个额外的元素(“.push”),以确保负边距不会向上拉动页脚并覆盖任何内容。push 也非常巧妙,因为它很可能没有自己的底部边距。如果它有,则必须将其考虑在负边距中,并且这两个数字不同步看起来不太好看。

页脚上有负顶部边距

方法不需要 push 元素,而是需要在内容周围添加一个额外的包装元素,以便应用匹配的底部填充。同样是为了防止负边距将页脚提升到任何内容之上。

<body>
  <div class="content">
    <div class="content-inside">
      content
    </div>
  </div>
  <footer class="footer"></footer>
</body>
html, body {
  height: 100%;
  margin: 0;
}
.content {
  min-height: 100%;
}
.content-inside {
  padding: 20px;
  padding-bottom: 50px;
}
.footer {
  height: 50px;
  margin-top: -50px;
}

查看 Chris Coyier 在 CodePen 上编写的笔 使用负边距实现粘性页脚 2 (@chriscoyier)。

此方法与前一个方法之间有点区别,因为它们都需要额外的、不必要的 HTML 元素。

包装器上有 calc() 减少的高度

一种方法是不需要任何额外元素,而是使用 calc() 调整包装器的高度。然后就不会有任何重叠,只有两个元素堆叠在一起,总高度为 100%。

<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>
.content {
  min-height: calc(100vh - 70px);
}
.footer {
  height: 50px;
}

查看 Chris Coyier 在 CodePen 上编写的笔 使用 calc() 实现粘性页脚 (@chriscoyier)。

请注意 calc() 中的 70px 与页脚的 50px 固定高度。这是一个假设。一个假设是内容中的最后一个项目有 20px 的底部边距。需要将该底部边距加上页脚的高度加在一起,然后从视口高度中减去。是的,我们在这里使用视口单位作为另一个小技巧,以避免在设置 100% 包装器高度之前必须设置 100% 的 body 高度。

使用 Flexbox

上面三种方法的主要问题是它们需要固定高度的页脚。固定高度通常在网页设计中很糟糕。内容可能会发生变化。事物是灵活的。固定高度通常是危险信号。 使用 flexbox 实现粘性页脚 不仅不需要任何额外元素,而且允许使用可变高度的页脚。

<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>
html, body {
  height: 100%;
}
body {
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1 0 auto;
}
.footer {
  flex-shrink: 0;
}

查看 Chris Coyier 在 CodePen 上编写的笔 使用 Flexbox 实现粘性页脚 (@chriscoyier)。

您甚至可以在上面添加标题或在下面添加更多内容。使用 flexbox 的技巧是

  • 您想要扩展以填充空间(在本例中为内容)的子元素上的flex: 1
  • 或者,margin-top: auto 将子元素尽可能地从相邻元素推开(或需要边距的任何方向)。

请记住,我们有一份完整的指南来介绍所有这些 flexbox 知识。

使用网格

网格布局比 flexbox 更新(而且支持范围更窄)。我们也有一份完整的指南。您也可以非常轻松地将其用于粘性页脚。

<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>
html {
  height: 100%;
}
body {
  min-height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
}
.footer {
  grid-row-start: 2;
  grid-row-end: 3;
}

此演示应在 Chrome Canary 或 Firefox Developer Edition 中运行,并且可能可以向旧版本的 Edge 网格布局回传

查看 Chris Coyier 在 CodePen 上编写的笔 使用网格实现粘性页脚 (@chriscoyier)。