12.3 构建适用于媒体查询的页面
上一节解释了媒体查询是如何发挥作用的。现在你将看到如何将媒体查询应用到完整的页面,从而让页面的布局适应设备视觉区域的大小。这就是Ethan Marcotte的响应式Web设计使用的技术。不过,我不会像响应式设计那样让图像大小适应视觉区域(这不是强制的)。我将使用第11章中作为示例的页面开始以下的讲解。
我不会展示应用于每个媒体查询块内的全部样式规则,因为各个网站的这些样式规则都不一样。重要的是了解如何建立响应式网站,以及用于实现响应式网站的媒体查询类型。完整的页面和代码见www.bruceonthe-loose.com/htmlcss/examples/。
- 创建内容和HTML
一切应该从可靠的、认真考虑过的内容开始。如果你试着用占位符文本(如没有任何含义的lorem ipsum3)设计和构建你的网站,当你填入真正的内容以后,你可能会发现形式与内容并没有结合得很好。因此,应该尽可能地将内容采集工作提前,从而对设计和开发满足访问者(和你)需求的网站更有信心。
3 在西方排版、设计领域常用一段以“lorem ipsum”开头的拉丁文作为占位符,以测试排版、设计的效果。这段文本是经过改造的、没有意义的拉丁文,常用“lorem ipsum”指代这段文本。——译者注
示例页面的底层HTML与第11章的页面的代码是相同的,除了以下三处例外。
我在
head
元素中添加了。关于这行代码的作用,参见“理解视觉区域及使用视觉区域
meta
元素”。如果你在实现一种灵活的布局,建议你在页面中包含此meta
元素。我移除了页面底部的小的缩略图(有20多个这样的图像)。要注意带宽(以及设备能力),这些图片的数量超过了所有设备默认加载的建议数量。如果我想来得花哨些,我可以写一些服务器端代码或JavaScript动态地为较大的屏幕加载这些图像。不过这已经超出了本书的范围。
我在页面底部添加了对
respond.js
的请求,从而让媒体查询对IE8及以下版本也有效。参见“在IE8及以下版本中呈现媒体查询样式”。
- 选择设计实现方法
至少有两种方法可以实现响应式页面。这两种方法使用相同的HTML,只是某些CSS不一样。下面是对这两种方法的概述。
方法1:为所有的设备建立基准样式,再从小屏幕(移动)做起,逐渐覆盖大屏幕(桌面)
首先为所有的设备提供基准样式(如图12.3.1所示)。这通常包括基本的字体格式、颜色,可能还要对默认的外边距和内边距设置进行微调,但不包括元素的浮动或定位。内容将按照常规的文档流由上到下进行显示。网站的目标是在单列显示样式中是清晰的、中看的(如图12.3.2所示)。这样,网站对所有的设备(无论新旧,只要带有Web浏览器)都具有可访问性。在不同设备下,外观可能有差异,不过这是在预期之内的,完全可以接受。
从这种样式开始,使用媒体查询逐渐为更大的屏幕(或其他媒体特性,如
orientation
)定义样式。大多数时候,min-width
和max-width
媒体查询特性是最主要的工具(参见图12.3.3~图12.3.10)。
这种方法通常称为移动优先的响应式Web设计。
方法2:为桌面环境构建网站,再处理不同的设备屏幕尺寸
先为网站的桌面版本添加样式(参见第11章)。
使用媒体查询为其他更小的屏幕尺寸覆盖样式。
第一种方法遵循渐进增强的原则,因此它在Web圈子里具有很大的吸引力。为了让你掌握这种方法,我将在示例中使用这种方法。如果你想尝试第二种方法,可以以第11章结束时的页面为起点,根据你在这里学到的知识,为更小的屏幕尺寸添加媒体查询。
/* 基准样式
----------------------------------- */
body {
color: #1d3d76;
font: 100% "Trebuchet MS", Verdana, sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6,
.logo {
color: #b74e07;
font-weight: bold;
}
h1 {
font-size: 1.25em; /* 24px/16px */
text-transform: lowercase;
}
.nav li {
display: inline;
font-size: .7em;
}
...
图12.3.1 应用于所有设备的基准样式示例。这些样式规则与你在本章之前看到的其他代码是类似的,只是它们没有由媒体查询包围
图12.3.2 iPhone支持媒体查询,但我还未将媒体查询添加到样式表里。我只写好了基准样式,因此这些屏幕截图可以表示不支持媒体查询的浏览器呈现页面的样子。页面的布局是线性的,右侧图像出现在recent entries的下方。页脚在这些内容的下面,但这里没有显示出来
- 逐步完善布局
好了,现在你已经把内容聚集到了一起,用语义化HTML对它们进行了标记,并决定使用方法1实现你的设计。图12.3.1~图12.3.10显示了如何从适用于所有设备的基准样式开始,逐渐添加样式,直到拥有一个适合一系列视觉区域尺寸和设备的布局。
如果用上响应式Web设计的术语,这一过程可以表述为,使用媒体查询为页面中的每个断点(breakpoint)定义样式。断点即内容需作适当调整的宽度。在本例中,我为下列断点创建了样式规则。记住,对于每个最小宽度(没有对应的最大宽度),样式定位的是所有宽度大于该min-width
值的设备,包括台式机。
320像素的最小宽度(如图12.3.3和图12.3.4所示)。定位纵向模式下的iPhone、iPod touch、各种Android以及其他移动电话。
480像素的最小宽度(如图12.3.5和图12.2.6所示)。定位大一些的移动电话,如某些HTC机型,以及横向模式下的大量320像素设备(iPhone、iPod touch及某些Android机型)。
600像素的最小宽度(如图12.3.7和图12.3.8所示)。主要是为窄的桌面浏览器设置这些样式,不过,它们照例适用于任何显示为此最小宽度的设备。
600像素的最小宽度和767像素的最大宽度之间(参见图12.3.7和图12.3.8)。在此范围内,报头的布局被切断了(无论对桌面浏览器窗口大小怎样调整,它基本上是可以看见的),因此我创建了这部分样式对其进行了清理,填补了与最后的断点之间的差距。
768像素的最小宽度(如图12.3.9和图12.3.10所示)。这适应于各种新旧浏览器,以及iPad和其他的平板电脑。
- /* 基准样式
- ----------------------------------- */
- ...
- /* 大于等于320px
- ----------------------------------- */
- @media only screen and (min-width:
- 320px) {
- .photo {
- float: left;
- }
- }
图12.3.3 我为视觉区域至少有320像素宽的设备添加了一条样式规则,让博客文章里的文本包在图像周围(参见图12.3.4)。我并未将这条样式规则包含在基准样式里,因为一些移动电话(甚至是智能手机)的屏幕更窄,会让图像旁边的文本由于显示空间太窄而变得难以阅读
图12.3.4 由于使用了图12.3.3中定义的媒体查询,博客文章中的文本环绕在图像的周围。该样式对iPhone是有效的,因为其纵向模式下的视觉区域有320像素宽
- /* 基准样式
- ----------------------------------- */
- ...
- /* 大于等于320px
- ----------------------------------- */
- @media only screen and (min-width: 320px) {
- ...
- }
- /* 大于等于480px
- ----------------------------------- */
- @media only screen and (min-width:
- 480px) {
- .intro {
- margin: -.9% 0 0 110px;
- }
- .entry .date {
- margin: 0;
- text-align: right;
- position: relative;
- top: -1em;
- }
- #main .continued {
- margin-top: -1%;
- text-align: right;
- }
- }
图12.3.5 现在,样式表中有了定位视觉区域至少为480像素的设备的媒体查询。这样的设备包括屏幕更大的手机(如某些Android机型),以及横向模式下的iPhone(参见图12.3.6)
图12.3.6 这是在480像素宽的屏幕下显示页面中部的样子。由于具有了更多的屏幕空间,我让文本不再包在图像周围,并让日期和continued向右对齐
- /* 基准样式
- ----------------------------------- */
- ...
- /* 大于等于320px
- ----------------------------------- */
- @media only screen and (min-width: 320px) {
- ...
- }
- /* 大于等于480px
- ----------------------------------- */
- @media only screen and (min-width: 480px) {
- ...
- }
- /* 大于等于600px
- ----------------------------------- */
- @media only screen and (min-width:
- 600px) {
- #container {
- background: url(../img/bg-bluebench.jpg) repeat-y;
- margin: 20px auto;
- padding: 30px 10px 0 0;
- width: 90%;
- }
- .logo {
- float: left;
- font-size: 2em; /* 32px/16px */
- }
- ...
- }
- /* 600px~767px之间
- ----------------------------------- */
- @media only screen and (min-width:
- 600px) and (max-width: 767px) {
- .logo {
- background: #eee;
- font-size: 1.825em;
- }
- #masthead form {
- width: 235px;
- }
- input[type="text"] {
- width: 130px;
- }
- .nav li {
- font-size: .625em;
- font-weight: bold;
- padding-left: 1%;
- }
- ...
- }
图12.3.7 这些媒体查询开始让报头从线性布局转为水平样式。它让页面在宽度适中的桌面浏览器上显得更为好看(如图12.3.8所示)
图12.3.8 使用图12.3.7中的样式,页面已经接近其完整形式。现在,内容的布局仍为单栏,但搜索框和主导航移到了标识旁边。同时,页面周围的背景图像也第一次出现了
- /* 基准样式
- ----------------------------------- */
- ...
- /* 大于等于320px
- ----------------------------------- */
- @media only screen and (min-width: 320px) {
- ...
- }
- /* 大于等于480px
- ----------------------------------- */
- @media only screen and (min-width: 480px) {
- ...
- }
- /* 大于等于600px
- ----------------------------------- */
- @media only screen and (min-width: 600px) {
- ...
- }
- /* 600px~767px之间
- ----------------------------------- */
- @media only screen and (min-width: 600px) and (max-width: 767px) {
- ...
- }
- /* 768px
- ----------------------------------- */
- @media only screen and (min-width:
- 768px) {
- #container {
- max-width: 950px;
- }
- #page {
- padding-left: 0;
- width: 97.9167%;
- }
- .nav li {
- display: list-item;
- float: left;
- font-size: .75em; /* 12px/16px */
- }
- #main {
- float: left;
- width: 71%;
- }
- #related {
- margin-left: 72%;
- }
- #footer {
- clear: both;
- }
- ...
- }
图12.3.9 这是最终的媒体查询,定位至少有768像素宽的视觉区域。该媒体查询对大多数桌面浏览器(除非用户让窗口变窄,就像图12.3.8那样)来说都为真,它同时也适用于纵向模式下的iPad及其他一些平板电脑(参见图12.3.10)
图12.3.10 使用图12.3.9中的样式,页面变得完整了。这里显示的是在iPad中页面显示的样子,在桌面浏览器中(尽管要宽一些)也是类似的。由于宽度是用百分数定义的,因此主体内容栏和侧栏会自动伸展
你的断点可能跟此处用的不同。这取决于哪些断点对你的内容、设计和受众来说是合适的。
例如,有人会定义(min-width: 992px)
的媒体查询,有时还会为更高的分辨率再定义一个媒体查询。相反,我在示例页面的#container
选择器中添加了max-width: 950px;
(参见图12.3.9)。这样,页面在950像素内是灵活的,但在超过这一宽度以后就不再继续伸展,因此我不会为大于该值的宽度指定媒体查询。注意这个max-width
是布局的属性,并非像(max-width: 950px)
中的媒体查询特性。
也可以使用与设备视觉区域宽度不完全相同的值作为断点。如果基于(min-width: 700px)
的媒体查询是呈现内容的最佳方式,就可以使用该媒体查询。这样的话,也不一定要用像素作为单位。可以使用em创建媒体查询,如(min-width: 20em)
。
移动编码和测试工具
在移动电话和平板电脑上测试页面是一件很有挑战的事,因为你可能很难真正在各种设备上进行操作。在编码和开始最初的测试时,有一些值得使用的技巧和工具,尽管使用它们与在真实的设备上测试并不完全一样。
在编写样式的时候,调整桌面浏览器窗口的大小,使窗口大约等于各种移动电话和平板电脑的视觉区域大小。这肯定是一种相当粗略的方法,但它确实可以帮你测试样式,从而减少在设备上测试以后进行调整的工作量。此外,来回拖动浏览器窗口也可以测试页面布局为适应不同桌面浏览器进行调整的情况。
在开发的起步阶段,使用ProtoFluid(www.protofluid.com)。这是一款免费的、基于浏览器的工具,提供符合一些流行设备尺寸的视图。需要强调的是,这款软件不能用于正式测试,因为它无法像手机或iPad那样运行,但它在开发的起步阶段还是很有帮助的。(一个小的警告是,该软件并不是一种非常直观的工具。你可能需要捣鼓一会儿才能掌握一些窍门。)要在ProtoFluid中看到页面,需要将页面存放到服务器上。服务器可以是由Web主机提供商提供的(参见第21章),也可以是运行在你自己的计算机上供开发用的服务器(在网上搜索“set up localhost server”)。
使用苹果免费提供的iOS Simulator测试页面在iPhone和iPad上的显示效果。现在我们已经有了一些基础,该软件是除了在真正的设备上测试以外最好的工具。你可能已经注意到了,我在一些屏幕截图上使用了这一工具。不过,该软件只能在OS X上运行,且在Windows上没有可替代的软件。iOS Simulator是免费的Xcode的一部分,下载地址为http://developer.apple.com/xcode/。
使用Electric Mobile Simulator for Windows(www.electricplum.com/dlsim.html)。这可能是运行在Windows上最好的移动设备模拟软件了。当然,该软件并不是苹果的iOS Simulator的替代软件。
使用为其他设备和移动浏览器设计的仿真器和模拟器。Mobile Boilerplate维护了一个针对iOS、Android、Nokia Symbian等设备的移动仿真器和模拟器列表,详情参见https://github.com/h5bp/mobile-boilerplate/wiki/Mobile-Emulators-&-Simulators。
如果幸运的话,你身边的朋友可能有一些不同设备供你进行测试。四处问问吧!
- 在IE8及以下版本中呈现媒体查询样式
对于先编写基准样式,再使用媒体查询对设计进行调整的做法,有一点需要注意,就是Internet Explorer 8及以下的版本不支持媒体查询。这意味着这些浏览器只会呈现媒体查询以外的样式,即基准样式。对大部分网站来说,使用IE6、IE7和IE8的用户合起来仍占有较大的比例,因此你可能希望这些访问者也能看到预期的设计。
Scott Jehl着手修复了这一问题,他创建了一个轻量级的脚本,即respond.js,该脚本可以让min-width
和max-width
媒体查询在IE的旧版本中生效。该脚本位于https://github.com/scottjehl/Respond。激活respond.min.js链接可以查看代码,将代码复制到文本编辑器里,再保存为respond.js即可。
尽管这段脚本还可以让min-width
和max-width
媒体查询对其他旧浏览器有效,但其他旧浏览器并不重要,因此你可以使用条件注释仅让IE8及以下版本加载这段脚本,如图12.3.11所示。
- ...
- <footer id="footer"
- role="contentinfo">
- ...
- </footer>
- </div>
- </div>
- <!--[if lte IE 8]>
- <script src="assets/js/respond.js"> </script>
- <![endif]-->
- </body>
- </html>
图12.3.11 将script
元素放在条件注释里,只有Internet Explorer 8及以下版本会加载respond.js。将src
值里的assets/js/
部分替换为你的网站上指向respond.js的路径(如果与此不同的话)。设置完成后,IE8及以下版本就能理解媒体查询并呈现相应的样式了
此外,如果你计划在项目中使用Modernizr(www.modernizr.com),你可以通过Modernizr的配置工具将respond.js包含在内,从而不必单独下载并在HTML页面中调用这段脚本。关于Modernizr的更多信息,参见14.3节;关于脚本,参见第19章。
- 构建适用于媒体查询的页面的步骤
创建内容和HTML。
在HTML页面的
head
元素中,输入。(参见12.2节的“理解视觉区域及使用视觉区域
meta
元素”。)选择设计实现方法。推荐像示例演示的那样,先创建适用于所有设备的基准样式,再使用媒体查询逐渐进行完善。不过,如果你愿意,你也可以先实现桌面布局(参见第11章),再使用媒体查询为屏幕更小的设备定义样式。
为不同的视觉区域宽度调整适合内容的布局。根据12.2节中介绍的方法(参见图12.2.3、图12.2.5、图12.2.7和图12.2.9),识别断点并创建相关联的媒体查询。在这个过程中,应尽可能地使用百分数表示
width
、margin
和padding
,形成流式页面布局。如果你想让IE8及以下版本呈现
min-width
和max-width
媒体查询内的样式规则,可以获取respond.js(参见“在IE8及以下版本中呈现媒体查询样式”)。如果执行了第5步,应在
结束标记上面输入以下代码,从而让页面指向respond.js(参见图12.3.11)。
<!--[if lte IE 8]>
<script src="path/respond.js"> </script>
<![endif]-->
其中path
指的是你网站上JavaScript文件的位置,respond.js是你保存的JavaScript文件的名称。script
元素周围的条件注释是可选的。
开始测试(参见“移动编码和测试工具”)。
根据需要,修改第4步中的CSS和媒体查询,并进行测试,直到页面在各种设备下都呈现出预期的效果。
提示 如图12.3.3、图12.3.5、图12.3.7和图12.3.9所示,所有示例页面的样式都位于一个样式表里。你也可以采用12.2节中指出的方法,链接到分离的样式表。通常,使用一个样式表的性能更优(只要它没有特别大),因为浏览器需要下载的文件越少,呈现页面所用的时间就越少。
提示 Eivind Uggedal的http://mediaqueri.es)网站汇集了大量现实的响应式站点(数量还在增加),值得借鉴。
提示 Mobile Boilerplate(www.html5boiler-plate.com/mobile)是一个编写网页所用的起动模板,其中包含了很多移动开发的最佳实践。它背后的团队还针对现代移动设备(既包括智能手机,也包括平板电脑)提供了一组方便使用的规范(https://github.com/h5bp/mobile-boilerplate/wiki/Mobile-Matrices)。如该页面所述,这些信息对设计查询是非常有用的。
提示 如果你想定位高像素率设备(如iPhone 4和使用Opera Mobile 11浏览器的手机),可以使用以下媒体查询:
- @media only screen and (-webkit-min- device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (min-device-pixel-ratio: 1.5) {
- / 样式规则 /
- }
这是Mobile Boilerplate推荐的方法。
提示 Andy Clarke 和Keith Clark创建的320 and Up(http://stuffandnonsense.co.uk/projects/320andup/)是另一个用于起动的模板。它反映了这里演示的方法——从一套默认样式开始,逐渐使用媒体查询对布局进行放大。
提示 Luke Wroblewski很好地总结了构建响应式站点有关事项的当前状态,见http://www.lukew.com/ff/entry.asp?1436。他的文章还包含了一些扩展阅读材料的链接。
提示 Maximiliano Firtman维护了一个现代移动设备对HTML5和CSS3支持情况的表格,见http://mobilehtml5.org。(其中大量信息属于HTML5高级特性,本书未涉及这些内容。)
提示 如果respond.js不管用,可以查看https://github.com/scottjehl/Respond上的“Support & Caveats”(支持与注意事项)部分。如果还有问题,可以试着将图12.3.11中突出显示的代码放到页面的
结束标记之上,而非
结束标记之前。
提示 更多关于条件注释的信息,参见www.quirksmode.org/css/condcom.html。