粘性页脚的目的是使其“粘贴”到浏览器窗口的底部。但并非总是如此,如果页面上有足够的内容将页脚向下推,它仍然会这样做。但如果页面上的内容较短,粘性页脚仍将悬挂在浏览器窗口的底部。
请注意,此处的“粘性”与上面描述的完全相同。不要将其与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)。
这对我来说一直有效。body 上的 position relative 是使其生效的必要条件。
这里的问题是它需要固定高度才能工作。如果内容在浏览器调整大小时换行,或者如果动态添加内容(可能根据页面不同而内容不同),则固定值将不起作用。
对于 Flexbox 示例,您还可以使用 vh 单位,代码量略少
http://codepen.io/acordova/pen/WxepQb
当然,这取决于您的浏览器支持级别。但它是一个不错的选择!(请注意,如果出于某种原因您有一个无法摆脱的内容包装器——我在使用 Ember 应用程序时遇到了这种情况——则
body
代码应该位于该包装器上。)我认为 vw 和 vh 单位在早期 Android 操作系统上不起作用——不确定更新版本的情况,或者这是一个多大的问题。
vh
和vw
不会考虑滚动条,也不会考虑移动版 Safari 上的滑动地址栏。我建议避免使用它们。早在 Flexbox 之前,也有一种方法可以使用
display:table
和display: table-footer-group
制作粘性页脚:http://codepen.io/SelenIT/pen/QELpww。它有一些缺点(例如,仅为了添加填充就需要额外的包装器),但它支持回溯到 IE8。是否也应该在这里提及?哇……我从未想过这个。看起来很可靠。很糟糕的是您必须拥有包装器,但我喜欢它!
在我切换到 Flexbox 之前,我一直使用这个。对于不支持 Flexbox 的浏览器,我不在乎页脚的粘性。
我认为我们可以在没有额外元素(没有“push”或“content-inside”)的情况下做到这一点
http://codepen.io/thierry/pen/zBOZvz
缺少通过 display table-cell 实现粘性页脚的方法:https://gist.github.com/goldsky/7322156
是的!display: table-cell; 在我工作中的大多数情况下都被证明是一种非常有效的方法。我相信随着我们逐渐远离传统功能,我最终会依靠现代功能。Flexbox 非常强大,可以以多种方式使用——令人惊叹。无论如何,这篇文章是各种方法的绝佳集合!
我更喜欢 Flexbox 的方法,但只是想在其中添加另一种选择……
使用
display: table-row
实现粘性页脚http://codepen.io/puglyfe/pen/QELpGy
我一直使用一个 jQuery 函数,如果内容高度小于页面高度,则为页脚添加“fixed”类。只需将其放入 JS 函数中,无需额外操作。
虽然我更喜欢纯 CSS 解决方案,但这取决于额外的标记或页面内容是否为(窗口高度 - 页脚高度),有时内容高度要短得多。
当内容动态变化时,该解决方案将成为一场噩梦。
不要忘记 position: sticky!将其用于此目的将是一件非常糟糕的事情,但它确实(有点)有效——可以添加到列表中。
(演示仅在 Firefox 或 Safari 中有效)
http://codepen.io/basement31/pen/bebqRd
我喜欢 Flexbox 方法。仅供参考。在最近的一个项目中,我尝试将容器的高度设置为 calc(100vh - 50px),虽然它适用于 Android 和所有桌面浏览器,但它不适用于 iOS 设备。特别是 calc 内部的 vh。非常烦人。因此感谢您展示 flex: 1; 非常有帮助。
使用 Flex 简写时要小心,不同的浏览器(在发货时使用不同的规范)具有不同的默认值 https://github.com/philipwalton/flexbugs#6-the-default-flex-value-has-changed - 现在最好避免使用简写(或构建一个为您执行此操作的 mixin)
这也是解决一些跨浏览器 Flexbox 问题的绝佳资源,其中大多数都有相当简单的解决方法
https://github.com/philipwalton/flexbugs
不幸的是,Safari 不行(Flex 方法)
很好的概述——但此处显示的 Flex 方法在不同浏览器中的效果并不符合预期。当我最近在 IE11 中打开我的项目时,它刚刚咬了我一口。Phillip Walton 提供了一个改进的版本,虽然稍微复杂一点,但到目前为止对我来说效果很好,我建议在此处更新示例(代码位于最底部): http://philipwalton.com/articles/normalizing-cross-browser-flexbox-bugs/
从 Kriesse 在此处链接的 Philip 文章中推断而来
我通读了这些评论,只是想看看是否有人发布了关于此内容的信息。谢谢!在尝试简单地使用
flex: 1;
并发现 IE 中存在问题后,我们在项目中解决了这个问题;此处的解决方案是我们采用的方案,并且效果完美。网格版本在我的 Firefox 开发者版中有效,但在 Chrome Canary 中无效,除非我启用实验性 Web 平台功能标志。
我使用了此解决方案: http://blog.karenmenezes.com/2014/jan/14/ryan-faits-sticky-footer-responsive/
它考虑了页脚的高度可能会根据页面的宽度而变化。对于响应式布局以及您无法使用 Flexbox 时很有用。
我也使用了 Menezes 女士的解决方案,尽管我修改了她的代码以使其不需要 jQuery。我去年切换到响应式布局,但我想为旧版 IE 浏览器提供合理的体验,因此我无法使用 Flex。
我将包装器上的底部边距设置为负值,并将推杆的高度在 CSS 中设置为页脚的正常高度,以避免大多数情况下高度发生较大变化,并且我使用 window.onload 在第一次设置高度以等待图像加载。
如果您只需要一个“视觉”底部页脚,则为 BODY 提供 FOOTER 的背景颜色,为内容提供页面的背景颜色。 http://codepen.io/herrfischer/pen/VjwVrP
在大多数情况下,这对我来说是最好的方法。
Flexbox 示例在 IE11(Windows 7)中不起作用。
这让我想起了我曾经想要一个不会与内容重叠的粘性页脚: http://stackoverflow.com/questions/30470296/how-to-avoid-an-unknown-height-sticky-footer-to-overlap-content-with-css-only
对于现代浏览器,
flex
解决方案是最佳选择,对于旧版浏览器支持,请使用table
解决方案。如果您不知道页脚的确切高度,可以使用简单的 js,例如