css揭秘 – 结构与布局(二)

这是我参与更文挑战的第14天,活动详情查看: 更文挑战

垂直居中

难题

css 中对元素进行水平居中是非常简单的:如果它是一个行内元素就对它的父元素应用 text-align:center; 如果是一个块级元素,就对它自身使用 margin:auto。但是对一个元素进行垂直居中就比较难了。

基于绝对定位的解决方案

main {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
复制代码

上面的方法可以实现完美的垂直居中,但是有一些需要注意的地方:

  1. 有时候不能使用绝对定位,因为它对整个布局的影响太过强烈;
  2. 如果需要居中的元素已经在高度上超过了视口,那它的顶部就会被视口裁切掉;
  3. 在某些浏览器中,这个方法可能会导致元素的显示有一些模糊,因为元素可能被放置在半个像素上。

基于视口单位的解决方案

视口相关的长度单位:

  1. vw 是与视口宽度相关的。与常人的直觉不符的是, 1vw 实际上表示视口宽度的 1%,而不是 100%。
  2. 与 vw 类似, 1vh 表示视口高度的 1%。
  3. 当视口宽度小于高度时, 1vmin 等于 1vw ,否则等于 1vh 。
  4. 当视口宽度大于高度时, 1vmax 等于 1vw ,否则等于 1vh 。
main {
    width: 18em;
    padding: 1em 1.5em;
    margin: 50vh auto 0;
    transform: translateY(-50%);
}
复制代码

基于 Flexbox 的解决方案

body {
    display: flex;
    min-height: 100vh;
    margin: 0;
}
main {
    margin: auto;
}
复制代码

当使用 Flexbox 时, margin: auto 不仅在水平方向上将元素居中,垂直方向上也是如此。

另外,Flexbox 还可以将匿名容器(即没有被标签包裹的文本节点)进行垂直居中,假设代码结构为:

<main>Center me, please!</main>
复制代码

先给 main 指定一个固定的尺寸,再借助 Flexbox 规范引入的 align-itemsjustify-content 就可以将其内部文本居中。

main {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18em;
    height: 10em;
}
复制代码

紧贴底部的页脚

难题

在网页设计中,存在一个相当古老但又相当常见的问题,它是前端工程师绕不开的坎。这个问题可以简单地概括如下:有一个具有块级样式的页脚(比如它设置了背景或阴影),当页面内容足够长时它一切正常,而当页面较短时(比如错误信息页面,准确的说,当页面内容的长度小于视口高度减去页脚高度时,这个问题就会出现)就会出现问题。此时的问题在于,页脚不能像我们期望中那样“紧贴”在视口的最底部,而是紧跟在内容的下方。

image.png

固定高度的解决方案

在已知 footer 元素的高度的情况下,可以借助视口相关的长度单位以及 calc() 函数 将 main 元素设置一个最小高度,比如 footer 元素高度是 200px,那么可以写如下 css 代码:

#wrapper {
    min-height: calc(100vh - 200px);
}
复制代码

不过,如果页面布局不是这么简单的话,那这个方法就完全不实用了。当改变页脚的尺寸时,都需要跟着调整 min-height 值(也就是说,这不够 DRY);此外,除非我们愿意给页头和内容主体套一层额外的 HTML 元素,否则还要跟着页头的尺寸修改。

更灵活的解决方案

Flexbox 对于此类问题同样是完美的选择。首先需要设置 <body> 元素 display:flex,还需要将 flex-flow 设置为 column,不然子元素会被水平排放在一行上。

body {
    display: flex;
    flex-flow: column;
}
复制代码

需要将 bodymin-height 设置为 100vh,现在只需要给 main 这个容器的 flex 属性指定一个大于 0 的值就可以实现这个效果了:

body {
    display: flex;
    flex-flow: column;
    min-height: 100vh;
}
main { flex: 1; }
复制代码

image.png

最后说一句

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享