用Flexbox和Grid使网页页脚保持在页面的底部

1,300 阅读3分钟

多年来,我不断地参考Matthew James Taylor的这篇文章,以寻找一种方法,使网页页脚保持在页面的底部,而不管主要内容的长度如何。这种方法依赖于设置一个明确的页脚高度,这不是可扩展的,但却是一个非常好的解决方案BF(在Flexbox之前)。

如果你主要是处理SPA开发,你可能会困惑为什么这个问题仍然存在,但它仍然有可能找到你的页脚漂浮起来的原因:

  • 登录页面
  • 博客/新闻文章(没有广告...)
  • 流程的间歇性页面,如确认行动
  • 产品列表页
  • 日历事件的细节

有两种方法可以用现代CSS来处理:flexbox和grid。

这里是演示,默认为flexbox方法。如果你打开完整的Codepen,你可以将$method 变量换成grid ,以查看该替代方案。

继续阅读演示,了解每种方法。

Flexbox方法#

这种方法是通过定义来完成的。

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

footer {
  margin-top: auto;
}

/* Optional */
main {
  margin: 0 auto;
  /* or: align-self: center */
  max-width: 80ch;
}

它是如何工作的#

首先,我们确保body 元素将至少拉伸到屏幕的全部高度,min-height: 100vh 。如果内容较短,这将不会触发溢出(例外:某些移动浏览器),它将允许内容根据需要继续拉伸高度。

设置flex-direction: column ,可以在保留堆叠的块元素方面保持正常文档流的行为(假设body 的直接子元素确实都是块元素)。

Flexbox的优势在于利用了margin: auto 的行为。这个怪异的技巧将导致边距填补它所设置的项目和它在相应方向上最近的兄弟姐妹之间的任何空间。设置margin-top: auto ,可以有效地将页脚推到屏幕的底部。

骗局#

在演示中,我在main 中添加了一个outline ,以证明在flexbox方法中,main 元素并没有填补高度。这就是为什么我们必须使用margin-top: auto 的技巧。这对你来说不可能有什么影响,但如果有的话,请看网格方法,它可以将main ,以填补可用空间。

网格方法#

这种方法是通过设置实现的:

body {
  min-height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

/* Optional */
main {
  margin: 0 auto;
  max-width: 80ch;
}

它是如何工作的#

我们为这种方法保留了min-height: 100vh ,但我们随后使用了grid-template-rows ,以正确划分空间。

这种方法的怪招是使用特殊的网格单位frfr 意思是 "分数",使用它要求浏览器计算出可用的 "分数 "空间,以分配给该列或行。在这种情况下,它填补了页眉和页脚之间的所有可用空间,这也解决了flexbox方法的 "陷阱"。

哪个更好?#

看到grid之后,你可能会有一瞬间觉得它显然更胜一筹。然而,如果你在页眉和页脚之间添加更多的元素,你需要更新你的模板(或者确保总是有一个包装元素,如div ,以不影响任何嵌套语义/层次)。

另一方面,flexbox方法可用于中间部分有多个块状元素的各种模板--例如,一系列的<article> 元素,而不是单一的<main> ,用于存档页面。

因此,与所有技术一样,这取决于项目 :)但是,我们都可以同意,拥有这些现代的CSS布局方法是很了不起的!