2019独角兽企业重金招聘Python工程师标准>>>
本文为大家讲解如何使用一种科学的方法实现网页设计,从原理上搞清楚什么是响应式设计,并实现一个简易的响应式设计框架,以此为基础,编写出第一个响应式页面。
不知道现在大家还读村上春树吗?在我刚上大学那会儿,一本《挪威的森林》在大伙儿中间传来传去,到最后书都散了架了。这是一种和以前完全不同的阅读体验,那淡淡的忧伤仿佛从书中弥漫出来,感染了已处于青春期尾巴上的我们。
然而,这和响应式页面有什么关系呢?
村上春树这位大叔很可爱,最近,他推出了一个网站,在上面回答读者来信。对于读者抛来的各种问题,他回答的一板一眼,颇有些黑色幽默。下面是该网站首页的截图:
图 1. 村上春树的答读者问网站
很朴素的页面对吗?如果你这样想,那又被“狡猾”的日本人骗了?在平板上、在手机上访问这个网站试试!
或者试试调整浏览器窗口的大小,大家会看到,同样的页面,在不同设备、不同浏览器窗口大小的情况下,页面的显示方式发生变化了。这就是响应式页面,页面会根据不同设备显示尺寸的大小,自动调整页面布局和显示内容,来适应设备,带给读者更好的用户体验。
所以说,村上春树回答读者来信的这个页面看似朴素,实则设计精巧,充分契合了他的写作风格和低调随和的气质。
无独有偶,在作者准备写作此篇文章时,美国白宫的主页也改版为响应式设计,果壳新推出的在行也是响应式的……响应式页面的春天仿佛要来了!欢迎大家上网搜寻一些响应式页面,把地址贴在留言中。
准备
在我们动手实现自己的响应式页面之前,先得掌握几个重要的概念。
HTML 简介
HTML 是 Web 的基本语言,它描述了文档的结构。比如拿一张报纸,我们会看到上面有标题、引文、正文、脚注等等。HTML 也一样,它用各种带有语义的标签,描述了网页的结构。它的语法很简单:
清单 1. HTML 标签语法
<tag attribute=”value”>content</tag>
网页结构全部由 HTML 提供的标签描述,您可参考 MDN 提供的HTML 参考手册自行学习常用的标签。下面给出了一段示例代码,读者可将其复制到文本编辑器中,保存为 HMTL 格式,然后使用浏览器打开,会对 HTML 有一个直观的感受。
清单 2. 示例 HTML 代码
<html>
<body>
<p>
云对雨,雪对风,晚照对晴空。来鸿对去燕,宿鸟对鸣虫。三尺剑,六钧弓,
岭北对江东。人间清暑殿,天上广寒宫。两岸晓烟杨柳绿,一园春雨杏花红。
两鬓风霜,途次早行之客;一蓑烟雨,溪边晚钓之翁。
</p>
<q>
从前,有一个程序员,他得到了一盏神灯 。灯神答应实现他一个愿望。
然后他向神灯许愿, 希望在有生之年能写一个好项目。后来他得到了永生。
</q>
<a href="http://www.ibm.com/developerworks/cn/">http://www.ibm.com/developerworks/cn/</a>
<blockquote>
浪漫的爱是病态的,因为你无法爱很多人,你累积爱的能力,然后将它泛滥出来。
每当你找到一个人,这个泛滥的爱就被投射出来,一个平凡的女人就变成一个天使,
一个平凡的男人就变成神圣的。但当那个洪水过去后,你再度变正常,你会觉得被骗了。
他只是一个平凡的男人,她只是一个平凡的女人。
</blockquote>
</body>
</html>
这里有两个地方值得注意:
选择标签时,应使用语义相匹配的标签。比如上面的很多标签,也可以使用一个<div>标签代替,但这就使相应部分失去了语义,是一种不好的实现方式。
HTML 只描述文档结构,不描述样式!读者如果用浏览器打开上述示例 HTML 代码,可能会觉得有些疑惑,文中的三段话在样式上看起来很明显不一样啊,这难道不是不同标签带来的效果吗?不是,浏览器会为 HTML 标签提供默认样式,如果在浏览器中禁用所有样式,就会发现它们看上去并无差别。以 Chrome 浏览器为例,可安装 Web Developer 插件来禁用样式。
CSS 简介
CSS(Cascading Style Sheets),中文译作级联样式表,用来定义文档的样式,比如字体、颜色、布局等。它的语法也非常简单:
清单 3. CSS 语法
selector {
property: value;
…
}
您可自行参考CSS 手册,熟悉其使用方法。
CSS 可以定义在 HTML 文档头部、元素里,也可以定义在一个单独的 css 文件中。在实际开发中,为了达到内容和样式的分离,一般都在单独的文件中定义 CSS,这时,就需要在 HTML 文档头部引入 CSS:
清单 4. 引入 CSS 文件
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
</body>
</html>
CSS 中所谓的级联是指子元素会继承父元素的样式,所以在定义样式时,应先从最上层的元素开始,先定义那些通用的样式,然后再一层层下来,定义各子元素独特的样式。
一切皆盒子
图 2. 盒子模型
您可以随便在浏览器的开发者工具中审查页面上的任意元素,都会发现其外观符合上图所示的一个盒子模型。以该图为例:元素的尺寸为 200×200,内边距为 30,边框为 10,另外上下左右各有 20 和 59 的外边距。在页面上显示时,一个元素的尺寸即包含自身大小,也包含内边距和边框,即图中黑色实线围起来的部分。前端开发人员在编写 CSS 时,要不断计算一个元素的实际显示大小,实在有点繁琐。
万幸的是 box-sizing 属性可以改变 CSS 的盒子模型,将该属性指定为 border-box 后,元素显示时的实际大小即为 CSS 中定义的 width 和 height,而元素的大小则在此基础之上减去内边距和边框的大小,自动适应。以下图为例,如果在 CSS 中加入如下代码,则元素的大小会自动适应,变为 120×120。试试吧!
清单 5. box-sizing
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;}
后续内容都基于您了解了什么是盒子模型,并且使用上述 CSS 片段改变盒子模型的行为基础之上,如果对于这个知识点还有疑问,请参考文末的参考资料自行学习掌握。
设计自己的响应式 CSS 框架
上面我们对 HTML 和 CSS 做了简要的介绍,从本节开始,将把重点放在如何实现响应式设计上。为实现响应式页面,必须具备两种能力:首先需要灵活方便的布局方式;其次需要在恰当的时机对页面布局进行调整。在重点讨论这两种方式之前,我们先花点时间研究一下网页的设计原则。
一切皆网格
您打开一个网页,目光会首先聚焦到页面顶部,然后自顶向下,自左向右移动,这是最符合人类行为习惯的。网页设计也遵循同样的原则,将网页自顶向下,自左向右分成不同的单元格。不信的话,您可以随便打开一个网站,看看是否遵循这样的原则。下图是作者的豆瓣页面,我用红颜色的方框画出了大致的单元格,当然,这只是一个粗略的划分,单元格里面的内容还可以划分得更精细。
事实上,一个前端开发者拿到一个设计时,就会对设计进行这样的划分,以此定义 HTML 结构,然后使用 CSS 对页面进行布局,并且调整字体、颜色等,最终实现出符合设计师要求的页面。
那些常用的 CSS 框架对页面也是以网格划分,一般将整个页面划分为 12 列,之所以选择 12,是因为 12 是 2、3、4、6 的最小公倍数,这样就很容易将整个页面划分为 2、3、4……列。
图 3. 一切皆网格
下面我们看看如何使用 HTML 和 CSS 实现这样的网格系统。简单来说,我们将页面从横向划分为若干行,从纵向划分为 12 列,每一列占整个行宽度的 1/12,这样当页面的大小变化时,每一列的宽度也会按比例放大或缩小。比如下面的 HTML 片段,把页面分成了 4 行,前两行分成两列,后两行分成三列,每列占用不同的页面宽度。
清单 6. 网格-HTML
<div class="grid">
<div class="row">
<div class="col-2">2 Columns</div>
<div class="col-10">10 Columns</div>
</div>
<div class="row">
<div class="col-3">3 Columns</div>
<div class="col-9">9 Columns</div>
</div>
<div class="row">
<div class="col-4">4 Columns</div>
<div class="col-4">4 Columns</div>
<div class="col-4">4 Columns</div>
</div>
<div class="row">
<div class="col-3">3 Columns</div>
<div class="col-6">6 Columns</div>
<div class="col-3">3 Columns</div>
</div>
</div>
我们使用如下的 CSS 定义网格,为了调试方便,特意为元素加了 1 个像素的边框。在 CSS 中,我们定义了行宽为 100%,且分别定义了 1 列、2 列……12 列的宽度。
清单 6. 网格-CSS
* {
border: 1px solid red !important;
} .row {
width: 100%;
}.col-1 {
width: 8.33%;
}.col-2 {
width: 16.66%;
}.col-3 {
width: 25%;
}.col-4 {
width: 33.33%;
}.col-5 {
width: 41.66%;
}.col-6 {
width: 50%;
}.col-7 {
width: 58.33%;
}.col-8 {
width: 66.66%;
}.col-9 {
width: 75%;
}.col-10 {
width: 83.33%;
}.col-11 {
width: 91.66%;
}.col-12 {
width: 100%;
}
用浏览器打开页面,效果并不如我们期望的那样,虽然每列的宽度符合我们的预期,但是它们并没有排在同一行内,而是从上到下排列。这一点也不意外,这是浏览器对 HTML 元素默认的布局方式。幸运的是,我们只需要一个 CSS 元素,就可以将布局调整为我们期望的方式。
图 4. 未完成的网格
flex 布局
flex 布局非常强大,它可以将一个元素的所有子元素以一种弹性的方式布局,按照比例自动填充满元素的宽度。我们只需在上述 CSS 的.row 类更改如下:
清单 7. flex 布局
.row {
width: 100%;
display: flex;
}
如同变戏法一般,我们想要的网格出来了!
图 5. 完成后的网格
flex 布局还有一个 flex-wrap: wrap 属性,当父元素剩下的宽度容纳不下更多子元素时,会自动将子元素放在下一行显示,这在响应式设计中特别有用。
事实上,这个页面现在已经是响应式页面了,您可以调整浏览器大小,或者在平板、手机上访问该页面,它的内容会根据分辨率大小做出相应调整。
图 6. 响应式的网格
当然,通常的响应式页面要做的工作更多,不光内容可以自动适应浏览器窗口的大小,布局也要做出相应的调整,甚至在手机或平板上,由于有限的分辨率,需要隐藏一些不重要的内容,以此带给用户更好的体验。
Media Query
这一切都可以通过 media query 实现,media query 可以根据一些判断条件,对页面应用不同的 CSS。比如下面的 CSS 片段,会在浏览器窗口小于 500 像素时,隐藏第一行第二列,并将第三行的背景色改为黄色。
清单 8. Media query
@media only screen and (max-width: 500px) {
.col-4 {
background-color: yellow;
}.col-10 {
display: none;
}
}
图 7
事实上,我们已经实现了一个响应式 CSS 框架,使用这一框架我们已经有能力实现一些简单的响应式页面。当然,在实际工作中我们一般不会这么做,我们通常选用已有的 CSS 框架,比如Bootstrap,这些框架的功能更加强大,我们只用编写很少的代码就能实现一个响应式页面。之所以我们要自己设计一个响应式 CSS 框架,是为了理解背后的原理,这样使用其他框架会变得更加容易,而且在框架不能满足需求时,还可以定制自己的框架。
结束语
本文通过实例,为大家讲解了什么是响应式页面,并且介绍了实现响应式页面所需要的基础知识,最后实现了一个简易的响应式 CSS 框架。希望本文能帮助大家开始自己的响应式页面之旅。