聊聊 CSS 中的布局模式

960 阅读20分钟
原文链接: click.aliyun.com

一、聊聊 CSS 中的布局模式

在大家的印象中,CSS 非常的简单,在此我想再强调一下,虽然 CSS 简单,但并不代表容易。随着 Web 技术的发展飞快,CSS 经过二十多年的发展,其变化也是非常的大。

CSS 涵盖的技术点也非常的多,其中的每一个点都足够我们发很多的时间去探讨。今天我们就一起来聊聊 CSS 中的布局模式,因为在任何的 Web 网站和 Web 应用都离不开布局。

对于众多的布局模式,我们应该怎样给 Web 产品选择最适合的布局模式呢?希望这篇文章对大家了解或者给 Web 产品选择布局模式有所帮助。

二、Web 的演化路程

在互联网的演化过程中,Web 网站(网页制作)是 Web 1.0 时代的产物,那时网站的主要内容都是静态的,用户使用网站的行为也以浏览为主。

随着网页从学术机构走向公众社会,网页承载的功能便超出了学术范围而变得愈加丰富,因此早期网页的局限性也逐渐显露出来。

2005 年以后,互联网进入了 Web 2.0 时代,各种类似桌面软件的 Web 应用大量涌现,网站的前端也由此发生了翻天覆地的变化。

网页也不再只是承载单一的文字和图片,各种富媒体让网页的内容更加生动,网页上软件化的交互形式为用户提供了更多好的使用体验,这些都是基于前端技术实现。

技术发展日新月异,现在业内人员开始提出 Web 3.0 的概念。

最常见的解释是,网站内的信息可以直接和其他网站相关信息进行交互,能通过第三方信息平台同时对多家网站的信息进行使用;用户在互联网上拥有自己的数据,并能在不同网站上使用;完全基于 Web,用浏览器即可实现复杂系统程序才能实现的系统功有;用户数据审计之后,同步于网络数据。

Web 的整个演化走过了 Web1.0 和 2.0,即将迎接 Web3.0(或者说 Web 3.0 已经到来了),在每个过程都有相应的产物出来,比如下图所示:

6c0e79fa95051c7d148dd4a135d54d44ebd7cddc

上图来自于 evolutionoftheweb.com。这个网站演示了整个网络的演进过程以及演进过程中相应产生的产物。感兴趣的可以至 http://www.evolutionoftheweb.com/?hl=zh-tw 详细了解。

上面的网站只演示到 2012 年,与当今相比,已有近六年的差距,但对于 Web 的前面发展史还是足以帮助我们进行 Web 发展的进程。

今后的发展,将会是 Web 4.0 的世界,智能化机械、生物科技等,可能正如电影 Matrix 所言,做成 “天网” 的电脑智能系统,希望电脑不会控制人类。

扯了这么多,简单的归纳一下 Web(说互联网技术更为准确)的演变的历史大致如下:

  • 1990~2000 年,Web 1.0(Web,网作用:连接知识):主要包括网页搜索引擎、网站、数据库、文件服务器等;

  • 2000~2010 年,Web 2.0(Scocial Web,社会网作用:连接知识):引入了社区、RSS、Wiki、社会化书签、社会化网络等概念;

  • 2005~2020 年,Web 3.0(Sementic Web, 语义网作用:连接知识):由本体、语义查询、人工智能、智能代理、知识结点、语义知识管理等构成;

  • 2015~2030 年,Web 4.0(Ubiquitous,无所不在的网作用:连接情报):具体内容还不大清楚,我想 Web 4.0 的含义关键在于它在任何时候,任何地方能够提供给你任何需要的东西。

用下图来展示 Web 每个阶段的发展历程:

0eee390889bb553b22d58d00f11550f391563e4a

三、布局演变史

通过前面的内容,或许你对 Web 的发展历史有了一定的了解。可以说整个 Web 在不断的演进,那么为 Web 服务的理念与技术等等也在不断的进行演化。

而我们今天要要聊的话题是 Web 布局(Web 网站或 Web 应用程序的布局),它也在 Web 不同的演化过程也有相应的演进。接下来就回到我们今天要聊的主题当中。

在 Web 布局整个演进过程当中,经历了没有任何布局、表格布局、定位布局、浮动布局、Flexbox 布局等布局模式。

除了这些我们常看到的布局之外,即将还会有 Grid、Shapes(类似杂志不规则布局)这些现代的布局模式。这些布局模式从侧面也反映出其自身是 Web 演进过程中的一种产物,都承载了自己在当时那个时期的史命。

用 @Jen Simmons 的一张图来表达,更为贴切一些:

e84ebb50828b385f71d8f857fdbe9c78f2458870

对于布局,我们还可以按类型和功能来进行分类。先来看按类型分类的布局模式:

  • 无任何布局模式;

  • 表格布布局模式;

  • 浮动布局模式;

  • 定位布局模式;

  • 多列布局模式;

  • Flexbox 布局模式;

  • Grid 布局模式;

  • 不规则布局模式;

另外除了类型分类,还可以按功能模式来分类:

  • 静态布局(Static Layout);

  • 流式布局(Liquid Layout);

  • 自适应布局(Adaptive Layout);

  • 响应式布局(Responsive Layout)。

接下来简单的看看每种布局的模式承载的史命。

1. 无任何布局模式

历史上最早的一个网页是 1990 年 12 月 20 日,欧洲核子研究组织(CERN)的科学家家蒂姆 . 伯纳斯 . 李在瑞士的研究中心创建的,最初仅为 CERN 内部的科学家所使用。

在这个阶段,网站的内容主要是文字内容和图片为主,制作方法非常的简易。比如万维网(WWW),欧洲核子研究组织的一帮科学家为了方便看文档,传论文而创造的。

这个时候的 Web 网页主要是基于 Document。Document 就是用标记语言加上超链接写成的由文字和图片构成的 HTML 页面,这样的功能已经完全能满足学术交流的需要,所以网页的早期形态和 Document 一样,完全基于 HTML 页面,并且所有内容都是静态的。如下图:

c50d64dfcee76ed5ea32289b4aba971d1fd3e97e

2. 表格布局模式

很长的一段时间,,多页就只有文字信息和图片组成,而且只是为了查看内容。为了让页面好看一点,主要装饰还是依赖于 HTML 自带的标签的属性。

随着 Web 技术的发展,HTML 也越来越成熟。而 Web 呈现给用户的不仅仅是文字浏览,网络制作者希望制作出来的页面能更适合用户的浏览,或者想让其能像 Word 这样的排版软件制作出来的文档。

这个时候很多网页开始依赖 HTML 的表格标签来对 Web 进行布局。在那个时候喜欢使用可视化软件来直接制作网页,比如 FrontPage、DW 这样的。

下图就是 DW 制作网页的一个简易图:

1b7c221c7faf911c31308a7b04c6d283d40a2287

比如 2005 年的淘宝页面,就是用表格制作的,如下图所示:

fd90b0a1cfd9e83085a2b276afe09ba4e87d1ab7

也可以说表格的布局是 Web 早期 CSS 不存在的时候兴趣的,是对table标签不正规使用(它是表格标签),天生就是用来显示数据的,而不是用来给网页布局的。

W3C 说,表格可以用来容纳文字、图片、链接、表单以及表格等。

但表格不应该单纯用来做网页布局,理由是,当 Web 被非可视化设备渲染的时候,表格会出问题,他们指定是屏幕阅读器以及盲文浏览器。

另外,表格在大型显示设备上会强迫用户左右滚动。虽然 W3C 说不建议用表格来布局,特别是在 CSS 出现之后,更是被人嫌弃,事实上对表格的责难主要有:

  • 代码臃肿;

  • 页面渲染性能问题;

  • 不利于搜索引擎优化;

  • 可访问性差;

  • 不够语义。

事实上,表格也并不是一无是处,他也有自己的优点:

  • 可观性好,当用户插入一个表格的时候就可以立即看到效果;

  • 简单方便,适合初入门的用户操作;

  • 可读性好,稍微懂一点 HTML 的同学就能看懂。

特别是 CSS 越来越成熟的时候,表格对于布局而言已经退出了历史的舞台,但并不是说<table>标签就再也不使用了。

前面也说过了,<table>表生就是用来显示数据的,所以不管什么时候,表格用来显示数据还是最佳的一种方式。

如果你追求完美,又不想使用表格的显示数据,那也不要紧,你可以使用tabletable-cell来模拟表格的布局模式。比如:

<table>                     //display:table;    <thead>                 //display:table-header-group;        <tr>                //display:table-row;            <td>1</td>      //display:table-cell;            <td>2</td>        <tr>    </thead>    <tbody>                 //display:table-row-group;        <tr>            <td>3</td>            <td>4</td>        <tr>    </tbody> </table>    

特别是在移动端,如果你想对底部的工具栏有一个等分列的布局效果,使用display:tabledisplay:table-cell将也是种完美的方案。只不过你需要添加 width: 100%table-layout:fixed

3. 定位布局

随着 CSS 的强大和 HTML 更多元素标签的出现,布局不在局限于表格。而对于后端或者说早期的前端人员(网页设计师),常采用的布局是 CSS 中的position各属性( fixedabsolute等)来布局。

这种方式的布局能让你快速达到想要的布局效果。当然也有很多同学直接尝试采用 PSD2HTML 这样的类似工具,直接将设计图转换成 Web 页面。

虽然这种方式能快速实现 Web 的布局效果,但也受到很多的局限性:

  • 需要明确指定元素的大小;

  • 需要明确计算元素位置坐标;

  • 难于维护。

或许其中还有很多其他不利的因素。因此,这样的布局也并算是一种好的布局模式,但对于不太懂 CSS 的同学而言,这是一种简单易懂的布局。

在实际布局当中,模态弹出框和固定页头,页脚有常见定位布局的身影,特别是水平垂直居中:

.center {    width: 300px;    position: absolute;    top: 50%;    left: 50%;    transform: translate(-50%,-50%) }

如果你使用 PSD2HTML 这样的工具转换出来的页面(特别早期的 Photoshop 或者 Firework 制图软件切片导出的页面),基本上都是使用定位布局。

4. 浮动布局

其实 CSS 中的浮动布局,它的初衷并不是用来布局的,而是用来处理文本的一种排版方式。但是广大的 CSSer 发挥其无穷的智慧,硬是将其用于 Web 的布局中。

这种布局方式成为一种主流的布局方式,并且持续了很多年。直到 Flexbox 布局的出现和移动端的兴起,浮动布局才慢慢的被其取替。

特别是在 2004 年傅捷、王宗义和祝军翻译了美国塞尔达曼(Zeldman J.)的著作《网站重构》一书。

d57776b9b4b15b53772fe1daba9dd59739115c59

这本书受到广大 Web 爱好者的青眯,可以说让国内整个前端行业(那时候还没有前端这样的职位)发生了很大的一个变化。我记得那时候,淘宝 UED 说:“我们要做地球上最优秀的前端”。

这本书称得上是给整个行业带来了革命性的变化,而就这场革命也造就了 “21 世界最大的 IT 冤案”。为什么说是 21 世界最大的 IT 冤案呢?

只要 2004 年以后看了这本书的同学,只要看到 Web 页面源码中有table标签,就会说这个不行,写这个页面的人不专业,页面也是垃圾,不符合 W3C 规范。

其实这本书从来也没有说网页出现table标签就是垃圾网页,就是不符合 W3C 标准的页面。

除了造成 21 世纪最大的 IT 冤案之外,还有灾难性的 DIV+CSS 的泛滥。出现最多的词就是div,大家觉得我会 div,我就很高大上。

而且整个页面下来,除了div,就是div。什么 p标签、span标签基本上是找不到。这个时候就是div的泛滥,根本也没有什么语义化,可读性一说。

感觉有点跑题了,还是回到正题中来。在使用浮动布局这些年当中,从中还演变出来很多布局方式,比如后面要聊的静态布局、流式布局、自适应布局和响应式布局等。

在 CSS 的布局模式当中,浮动布局经历的时期是最长的,持续了十多年的历史。在这个时期也演变出很多经典的布局。

其中要属 “圣杯” 和 “双飞翼” 两者最为经典。这两种方法实现的都是三栏布局,两边的固定宽度,中间自适应,它们实现的效果是一样的,差别只是实现的思想。

圣杯布局

圣杯布局:左、中、右。中间的宽度为100%,独占一行。使用负边距(margin-left)把左右两列拉到和中间列同一行。

  • 左列使用margin-left:-100%;

  • 右例使用margin-left: -右列宽度;

同时左、中、右三列的容器设置左右padding来给左右两列留下相应宽度(左、右列宽度)。

<!-- 圣杯的 HTML 结构 --> <div class="container">    <!-- 中间的 div 必须写在最前面 -->    <div class="middle"> 中间弹性区 </div>    <div class="left"> 左边栏 </div>    <div class="right"> 右边栏 </div> </div> /*CSS*/ .container {    width: 480px;    margin: 20px auto;    padding-left: 240px;    padding-right: 240px;    overflow: hidden;    border: 1px solid red; } .middle {    width: 100%;    background: green;    float: left; } .left {    margin-left: -100%;    width: 220px;    background: orange;    position: relative;    float: left;    left: -240px; } .right {    margin-left: -220px;    width: 220px;    background: yellow;    position: relative;    right: -240px;    float: left; }

双飞翼布局

双飞翼布局和圣杯布局类似,也是左,中,右三列,中列里面会再套一个容器。

  • 中列宽度设置为100%;

  • 使用负边距margin-left 把左右两列拉到和中列同一行;

  • 在中列内的容器div 设置margin-leftmargin-right 给左右两列留下对应的空间。

实现代码也很简单:

<!-- 双飞翼的 HTML 结构 --> <div class="container">    <!-- 中间的 div 必须写在最前面 -->    <div class="middle">        <div class="middle-inner"> 中间弹性区 </div>    </div>    <div class="left"> 左边栏 </div>    <div class="right"> 右边栏 </div> </div> /*CSS*/ .container {    width: 960px;    margin: 20px auto;    overflow: hidden; } .middle {    float: left;    width: 100%; } .middle-inner {    margin: 0 240px; /* 留出距离 */    background-color: yellow; } .left {    float: left;    width: 220px;    margin-left: -100%;    background-color: red; } .right {    float: left;    width: 220px;    margin-left: -220px;    background-color: green; }

圣杯布局和双飞翼布局解决的问题是一样的,都是两边定宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。

这样做主要是因为早年的网络和设备没有现在这么优秀,为了让主要的内容先向用户呈现,所以很多时候都使用这两种布局方式。

甚至可以说,现在很多人都还在使用这两种布局方式。但如果你继续阅读后面的内容之后,你会慢慢放弃浮动布局。

虽然在布局的历史中,他承载了相当长的一段时间的使命,但有更好的,更适合的方式,我们应该要学会选择与放弃。

5. 多列布局

这里要说的多列布局,并不是前面的布局模式产生的多列模式。而是 CSS 的 Multi-column 布局模块。

你可能想得到,这个模块给予了我们脱离positionfloat这些属性,就能在网页上实现多列布局的能力。

同样,根据容器的大小,就可以控制创建栏目的数量,这是非常了不起的一个特点。Multi-column 对应的 CSS 属性还具有以下一些功能:

  • 定义栏目的最大宽度;

  • 定义在多栏目之间的间距;

  • 在多个栏目中平均分配好显示的内容。

Multi-column 好就好在能够自动为你安排好流体内容,你用不着计算确定栏目的数量,让他们排排站好就行了。

这种布局,就算是在现在,使用的人也不多,必须像报纸这样的多列布局的风格并不多,但借助他的特性,我们可以实现一些特殊的布局风格。比如瀑布流的布局:

0c6e21430959cacf80efff5b90d4ec082d33c075

由于代码过多,就不在这里列出了,如果对代码感兴趣的话,可以至 https://codepen.io/airen/full/ybyvEM/ 查看。具体实现的步骤,可以阅读《纯 CSS 实现瀑布流布局》一文。

除此之外,多列布局还常用于下图这样的布局风格:

dae3040bdb02d04507ba5e2a2e44eaaf98c013c0

6. Flexbox 布局

Flexbox 是 CSS 的一个新特性,这个新特性解决我们以前在 CSS 中很多麻烦问题,比如说内容的伸缩与扩展、垂直居中、等分列、等高列等等。

当然,这个属性也大量的运用于布局当中,特别是在面对品种繁多的移动端的局面下,Flexbox 用于布局的优势也显现的更为强大。从而慢慢的用来取代了 CSS 中的浮动布局。

使用 Flexbox 来布局,现在随处可见。比如 @Zoe Gillenwater 整理的相关教程和资料(https://goo.gl/mB61yM)。里面有很多关于 Flexbox 的内容。这里我放几张图来演示 Flexbox 实现布局是多么的简单和灵活。

14f62879bcadcc8176040410fe97dfb6d8d8bc7a

e9c83588c2b1640b80c7247f42f54b1ca3b6ab24dafd9522b18affbbf82dfa2f5055f407826c093ddafd9522b18affbbf82dfa2f5055f407826c093d

时到今日,使用 Flexbox 的场景也越来越多,在将来使用 Flexbox 场景将会更多(https://www.w3cplus.com/blog/tags/157.html)。

7. 网格布局

前面说过早期的 Web 页面仅仅是用来展示文本信息和图片。但对于现在的 Web 页面,不仅仅是这样了。

随着这么多年的发展。现在大量的网页设计都是基于网格布局。虽然人们通常注意不到它,但事实上杂乱无章的布局时代确实已经过去了,现在是整齐结构化的天下。

无论从理论、美学和整齐来说,这样的布局都很好平衡。网格结构是所有现代网站的基础,它总能级最终用户完美无暇的设计。

对于网格系统而言,它也经历了一个漫长的演变。表格布局虽然痛苦,但可以说表格是网格系统布局的最初模型。

259eb48e9fd17d9e17f0d0c13547597e6242a95c

正因为有表格布局的存在,才有了后面的 CSS 网格系统,不管是早期基于浮动完成的网格系统,还是后期依赖于 Flexbox 完成的网格系统。当然,你可有会说,网格系统的鼻祖不是 960gs(http://960.gs/)?

264cf1212b45f3c8bc083ccd9697cd58de1d4887

虽然 960gs 是最早出现的网格系统(基于浮动布局),但其网格的思路是来源于表格的。因为表格具有明显的栅格风格,只不过是使用其它的布局模式,快速模拟了表格的风格,甚至是嵌套表格的网格。

加上网格系统让 Web 的设计变得结构整齐、布局平衡等。受到众多设计师的青眯,也让撸码的同学更易实现,并且可以依据此思路制定一套系统,比如很多 CSS 的 Framework 都有类似的网格系统布局(不管是浮动还是 Flexbox 实现的)。

不管怎么说,这些网格系统可以达到较好的效果,甚至还可以基于此系统制作工具,通过工具帮助大家快速完成布局。

前面我们说了很多种 Web 的布局模式,但这些布局模式都局限于单维(一维)方向。但对于现代 Web 页面的布局,很多时候我们需要的不仅仅是单维的布局,希望在两个维度都能更好的控制我们的布局。

比如下面这样的一种布局:

45ff53bf50e88afe2cdf5b2744649864493d05cc

前面介绍的每种布局模式都可以实现上图这样的布局效果,但要实现具有可扩展性,并且自适应强的并不容易实现。

归根究底,前面的这些方法都是单维控制的,只能控制一个方向,对于另一个方向就不好控制了。

不过,值得庆幸的是。CSS 推出的 CSS Grid 布局模块,可以很好的解决这个问题。因为 CSS Grid 布局打破了以前所有布局方式的维度,它是一个双维度的布局模块。

它除了可以灵活的控制水平方向之外,还能轻易的控制垂直方向的布局模式。对于上图那样的九宫格布局,它就可以轻而易举的完成。

可以说,CSS Grid 布局才是 Web 中的布局模块,随着浏览器对其支持度越来越强的情况下,它将更会受到青眯。也将成为未来 Web 布局中的霸主。

特别是将 CSS Grid 布局和 Flexbox 布局两种模式结合在一起,那对于布局言就不会有什么难事。比如下图这样的布局:

390a1b67f11082173e891399f5206e47f6e68828

8. 不规则布局

我们常看到的 Web 布局一般都是遵循按行和列等线性原则,Web 网站的布局到今天为止很大程度上受到这些原则的影响。

虽然 CSS Grid 的出现让布局变得更好,更灵活,但相对于印刷媒体而言,Web 布局总体上还是受到很多的限制,特别是内容流上。

杂志和报纸一直有很好的办法来安排内容。比如文本绕着非矩形排列。

88694930b5797f8b1c5984b1d916a879cbcc41e2

而 CSS 的 Shapes 模块(https://drafts.csswg.org/css-shapes/) 让 Web 布局能像杂志和报纸一样让文本内容实现不规则矩形排列。

CSS Shapes 使网页设计师能更好的实现自己的创意,除了简单的长方形和正方形,还可以实现任何几何图形布局。


原文发布时间:2018年01月29日

作者:GitChat技术杂谈

本文来源:CSDN    如需转载请联系原作者