CSS秘密花园: 流体背景,固定内容

CSS Secrets》是@Lea Verou最新著作,这本书讲解了有关于CSS中一些小秘密。是一本CSSer值得一读的一本书,经过一段时间的阅读,大漠@南北@彦子一起将在W3cplus发布一系列相关的读后感,与大家一起分享。

CSS Secrets

问题

在过去的几年中,有种网页设计趋热是越来越受欢迎:这就是我所说的“自适应的背景,固定宽度的内容”。这种模型常用于以下几种场景中:

  • 有多个内容部分<section>,每个内容都占据整个视窗宽度而且都有不同的背景。
  • 固定宽度的内容,即使宽度会根据不同的媒体查询修改。在某些情况之下,不同的区域<section>会有不同的内容宽度

有时候整个网站都是由这种风格组成,如下图所示:

相邻元素样式

更微妙点的如下图:

相邻元素样式

特定的区域使用这种模式的要属页脚,使用最频繁:

相邻元素样式

完成这样的效果最常见的方法就是使用两个元素,一个用于流体的背景,另一个用于固定宽度的内容。后者使用margin: auto,让内容保持水平居中。例如,页脚的区域,他的结构如下:

<footer>
 <div class="wrapper">
 <!-- 这里放页脚的内容 -->
 </div>
</footer>

CSS通常这样写:

footer {
 background: #333;
} 
.wrapper {
 max-width: 900px;
 margin: 1em auto;
}

看上去是不是很熟悉。大多数网页设计师或者开发人员都写过类似的代码。添加额外的标签元素是问题争执所在,或者说我们使用现代的CSS能不能避免添加额外的标签元素?

解决方案

让我们思考一下这个例子中使用的margin:auto。这个margin的值等于视窗一半的宽度减去页面内容一半宽度值。因为视窗宽度我们不知道他具体有多大的值,所以他的一半宽度只能用百分比来计算(假设其祖先元素没有显式的设置宽度),在这个示例中,可以使用50% - 450px来表达。在CSS Values and Units Level 3定义了一个calc()函数,允许我们做一些简单的数学表达式运算。通过calc()可以来替代auto值,此时,.wrapper样式变成:

.wrapper {
 max-width: 900px;
 margin: 1em calc(50% - 450px);
}

使用margin:auto让固定内容元素居中,唯一的原因是不得不用第二个容器来包裹内容。然而,现在使用calc()来替代autocalc()只是另一个CSS长度值,而且任何接受长度值的属性都可以使用。这也意味着,如果我们想要,我们现在可以将其运用其父元素的padding值上:

footer {
 max-width: 900px;
 padding: 1em calc(50% - 450px);
 background: #333;
}
.wrapper {}

警告:别忘了,在calc()中表达式的运算符之间要用空格符隔开,否则将会出错。这是一个非常奇怪的规则,主要原因是向前兼容,或许在未来,calc()可以识别标识符,甚至也可以包含连字符。

正如你所见,通过这样方式的处理,.wrapper容器的没有任何CSS代码,这意味着我们不需要了,也可以放心的从结构中删除这个容器元素。现在已经达到我们需要的风格,而且没有多余的HTML标签出现。那么我们还可以进一步改善它吗?像往常一样,这个问题的答案是肯定的。

请注意,如果我们把width样式注释掉,其实什么也不会发生。无论视窗大小,视觉上的效果完全相同。那是为什么呢?因为padding的值是50% - 450px,其有效空间始终没离开900px2 × 450px),只有宽度是900px以外,不管是更大还是更小,我们才能看到不同效果。但900px是我们得到的可用空间,所以它是多余的,我们可以直接删除它。

如果我们做一下改进,可以提高向后兼容性,通过添加一个备用的padding,这样一来,当浏览器不支持calc()属性,至少还会有一些内距的填充:

footer {
 padding: 1em;
 padding: 1em calc(50% - 450px);
 background: #333;
}

就是这样简单,我们只使用了三行CSS代码,而且没有添加额外的HTML标签,就实现了一个灵活的,干净的,可向后兼容的流体背景,固定宽度内容的效果。

来看一个简单的示例:

这个解决方案在屏幕宽度小于内容宽度的时候,会没有padding!其实可以通过媒体查询来修复。

原文链接:https://www.w3cplus.com/css3/css-secrets/fluid-background-fixed-content.html

发表评论

登录后才能评论