响应式 Web 设计






4.75/5 (4投票s)
如何使用灵活的布局来适应几乎任何屏幕。
这一切都始于 Ethan Marcotte 在 A List Apart 上发表的《响应式网页设计》一文。本质上,这篇文章提出通过创建灵活、流动且自适应的网站来应对不断变化的设备、浏览器、屏幕尺寸和方向。与其满足于为桌面网页创建适应最常见屏幕分辨率的版本,以及一个特定的移动版本(通常针对单个移动设备),不如反其道而行之:使用灵活且流动的布局来适应几乎任何屏幕。
核心概念
响应式网页设计的核心是三个关键技术特性
- 媒体查询和媒体查询监听器
- 基于网格的灵活布局,使用相对尺寸
- 灵活的图像和媒体,通过动态调整大小或 CSS
真正的响应式网页设计需要实现所有这三个特性。
关键在于适应用户的需求和设备的功能。假设一个移动用户将在小屏幕上查看您的网站。考虑用户的需求不仅仅意味着调整内容以适应屏幕尺寸。它还意味着首先考虑该移动用户访问您的网站时需要什么,然后相应地布局内容。也许您会以不同的顺序呈现信息。不要假设用户因为使用移动设备就无法访问网站的所有信息。您可能需要更改字体或交互区域,以便更好地响应触摸环境。所有这些因素都会影响响应式网页设计。
虽然移动设备通过越来越多的屏幕出现正在改变显示格局,但不要忘记另一端的景象。显示器也越来越大。服务于这两个细分市场不应阻止设计师在任何一个方面进行创新。
媒体查询
从 CSS 2.1 开始,媒体类型被用于同时应用屏幕和打印的 CSS。您可能还记得这些媒体类型
1. <link rel="stylesheet" type="text/css" href="style.css" media="screen" /> 2. <link rel="stylesheet" type="text/css" href="printfriendly.css" media="print" />
就这些了!幸运的是,W3C 在 CSS3 中改进了媒体查询,使其向前迈进了一大步。
如今,您可以使用媒体查询将样式限定为特定的功能,根据与您的查询匹配的功能应用不同的样式。您甚至可以使用 AND 和 NOT 等语义运算符组合查询,以测试多个功能。功能包括宽度、高度、最大宽度、最大高度、设备高度、方向、纵横比、分辨率等。
有三种方法可以实现媒体查询
使用 @import 规则从其他样式表中导入样式规则
1. @import url(style600min.css) screen and (min-width: 600px);
将媒体查询直接放入样式表中,如**图 1** 所示。这是最常见的方法。
#nav { float: right; } #nav ul { list-style: none; } @media screen and (min-width: 400px) and (orientation: portrait) { #nav li { float: right; margin: 0 0 0 .5em; border:1px solid #000000; } } @media screen and (min-width: 800px) { #nav { width: 200px; } #nav li { float: left; margin: 0 0 0 .5em; border: none; } }</
在链接样式表的 media 属性中包含查询
1. <link rel="stylesheet" type="text/css" media="screen and (max-device-width: 800px)" href="style800.css" />
由于 CSS 的(层叠)特性,默认样式在顶部定义,而匹配规则和样式的媒体查询在下方。顶部定义的样式将层叠到规则中的匹配样式,甚至可能被完全覆盖。
以下图像展示了一种使用媒体查询的响应式网页设计方法。**图 2** 和**图 3** 都显示了一台使用 Internet Explorer 9 的桌面在两种不同分辨率下的情况。**图 4** 显示了同一响应式网站在 Windows Phone(同样使用 Internet Explorer 9)上的情况。
如果您正在寻找一些绝佳的响应式网页设计示例,这些示例充分利用了媒体查询,那么 http://mediaqueri.es/ 这个爱好者网站可能会让人上瘾,**图 5** 显示了这一点。
媒体查询监听器
将媒体查询向前推进一步,W3C 的 CSS 对象模型 (CSSOM) 工作组还创建了媒体查询监听器,它提供了一个响应媒体查询更改的 API。您无需轮询更改或加载多个版本的资源,就可以使用该 API,例如,在触发媒体查询匹配时仅下载特定大小的图像。
如今,Firefox 和 Internet Explorer 10 Platform Preview 都实现了媒体查询监听器;您可以在 IE Test Drive 上观看演示“CSS3 Media Queries & Media Query Listeners”。
关于视口的一点说明
在移动浏览器上测试媒体查询时,您可能会注意到实际没有应用正确的媒体查询。发生这种情况时,移动浏览器会为您处理一些工作,以便在较小的屏幕上最佳地呈现页面。
那么,您认为没有办法获得真实分辨率吗?实际上是可以的,在视口 meta 标签中。视口 meta 标签控制移动浏览器(无chrome)窗口的逻辑尺寸和缩放。将 width 设置为 device-width 可以解决这个问题
<meta name="viewport" content="width=device-width">
其他视口设置包括 maximum-zoom 和 initial-scale。
弹性网格
基于网格的弹性布局是响应式设计的基石之一。“网格”一词使用得比较随意,并不意味着必须实现任何现有的网格框架。在这里,它的意思是使用 CSS 进行定位、设置边距和间距,并以新的方式实现各种网页布局类型。布局和文本大小通常以像素表示。设计师喜欢像素。Photoshop 也喜欢像素。但是,一个像素在一个设备上可能是一个点,而在另一个设备上可能是八个点。那么,如果您的一切都基于像素,如何进行响应式网页设计呢?您可能不喜欢这个答案:停止使用基于像素的布局,开始使用百分比或 em 来设置尺寸。
通过将文本大小、宽度和边距基于百分比或 em(基于字体点大小的度量单位)来设置,您可以将固定大小转换为相对大小。这意味着您需要做一些数学计算才能实现弹性网格和文本大小系统。但计算 em 的公式非常简单
target ÷ context = result
假设 body 字体大小的正常上下文是 16 像素。如果设计师指定 H1 的大小为 24 像素,您可以计算出以下结果
24 ÷ 16 = 1.5
这会产生以下 CSS 样式
h1{ font-size: 1.5em; } }</
始终考虑上下文。继续之前的示例,如果您有一个需要 12 像素大小的元素位于 H1 内部,则使用当前的 H1 作为上下文。现在上下文是 24 像素,因此“H1 a”的上下文计算为
12 ÷ 24 = 0.5
CSS 样式是
h1 a{ font-size: 0.5em; }</
您也可以使用百分比。计算算法相同;您只是得到百分比。
弹性网格使用这种方法。您可以找到一些框架来帮助您构建网格,例如Fluid Grid System 或Fluid 960 Grid System(960 Grid System 的流动版本)。此外,W3C 的几个小组提交了用于改进弹性网格的新规范,并取得了一些有益的成果。
CSS3 网格布局
CSS3 Grid Layout(也称为 Grid Alignment 或简称为 Grid)将典型的网格系统引入 CSS,这类似于 XAML 或 Silverlight 开发人员可能熟悉的。在撰写本文时,该规范是一份“编辑草案”。它允许定义布局中的区域,包含列和行、跨度、间距、填充、网格模板等,强制 HTML 元素和 CSS 之间实现完全关注点分离。与内容是 HTML 表格不同,Grid 允许将 HTML 原始元素放置在与实际内容分开的网格区域中。
将 CSS3 Grid 与媒体查询结合起来,为构建流动、响应式应用程序提供了强大的解决方案。
Grid 如何工作?您首先将 display 属性设置为 'grid'。(您需要使用 CSS 供应商前缀,因为这还不是 CSS3 推荐。目前,只有 Internet Explorer 10 Platform Preview 支持该规范,所以您会看到这里使用了 CSS 供应商前缀 -ms-。)让我们看三个示例,说明如何根据屏幕尺寸设置不同的视图。媒体查询用于根据屏幕宽度应用不同的网格样式。
在第一个示例中,用于定义内容的 HTML 包括一个标题和三块不同的文本(参见**图 6**)。
1. <div id="mygrid"> 2. <header id="myheader"> 3. <h1>Hello world</h1> 4. </header> 5. <div id="block1"> 6. <h2>Lorem Ipsum section 1</h2> 7. <p> 8. Phasellus venenatis sem vel velit tincidunt tincidunt. 9. Curabitur gravida, ante sit amet [... ...] 10. </p> 11. </div> 12. <div id="block2"> 13. <h2>Lorem Ipsum section 2</h2> 14. <p> 15. Nam tempus justo eu massa ultrices eget imperdiet ligula placerat. 16. Suspendisse [... ...]. 17. </p> 18. </div> 19. <div id="block3"> 20. <h2>Lorem Ipsum section 3</h2> 21. <ul> 22. <li>Curabitur ultrices tristique purus, sed pellentesque 23. magna scelerisque ut.</li> 24. <li>[... ...] </li> 25. </ul> 26. </div> 27. </div>
您首先将内容块一个接一个地排列,以便内容适合智能手机(参见**图 7**)。您可以添加背景颜色,如**图 8** 所示,以更清楚地表明您正在处理网格项。
@media only screen and (max-width : 480px) { #mygrid { display: -ms-grid; margin: 3px; -ms-grid-columns: 100%; /*one column taking full width */ -ms-grid-rows: 70px auto auto auto; /*4 rows */ } #myheader { -ms-grid-row: 1; -ms-grid-column: 1; } #block1 { -ms-grid-row: 2; /*place into row 2 / column 1*/ -ms-grid-column: 1; } #block2 { -ms-grid-row: 3; -ms-grid-column: 1; } #block3 { -ms-grid-row: 4; -ms-grid-column: 1; } }
在第二个示例中,一个媒体查询应用了为屏幕宽度大于 481 像素(比典型智能手机宽)定义的样式。您可以使用 Grid 定义两列并将块移动到所需位置(参见**图 9**)。结果显示在**图 10** 中。
@media only screen and (min-width : 481px) { /*make two columns and move block 3 next to 1 — just because we can*/ #mygrid { display: -ms-grid; -ms-grid-columns: 10px 1fr 10px 1fr 10px; /*10px columns to spacing in between*/ -ms-grid-rows: 100px 1fr 1fr; /*100px row and two rows each taking 1 fraction of available space*/ margin: 5px; } #myheader { -ms-grid-row: 1; -ms-grid-column: 1; -ms-grid-column-span: 5; background-color: #EEB215; } #block1 { -ms-grid-row: 2; -ms-grid-column: 2; background-color: #B2B0B0; } #block2 { -ms-grid-row: 3; -ms-grid-column: 2; background-color: #726E6E; } #block3 { -ms-grid-row: 2; /*block 3 can go into row 2*/ -ms-grid-column: 4; background-color: #515050; } }
第三个网格示例显示在屏幕宽度大于 1220 像素的屏幕上。您定义一个具有跨越多个列的宽标题,然后定义三列,每列占据可用空间的一部分,中间有几个 10 像素宽的列(参见**图 11**)。结果显示在**图 12** 中。
@media only screen and (min-width: 1220px) { #mygrid { display: -ms-grid; -ms-grid-columns: 1fr 10px 1fr 10px 1fr; -ms-grid-rows: 100px 1fr; margin: 5px; } #myheader { -ms-grid-row: 1; -ms-grid-column: 1; -ms-grid-column-span: 5; background-color: #EEB215; } #block1 { -ms-grid-row: 2; -ms-grid-column: 1; background-color: #B2B0B0; } #block2 { -ms-grid-row: 2; -ms-grid-column: 3; background-color: #726E6E; } #block3 { -ms-grid-row: 2; -ms-grid-column: 5; background-color: #515050; } }
Grid 规范是实现响应式网页设计的受欢迎的补充。
另外两个新的 CSS 规范也值得一提:Flexbox 布局模块 (Flexbox) 和 多列布局模块。两者在设计响应式网站方面都显示出巨大的潜力。
Flexbox 目前是 W3C 的工作草案,增加了对四种新布局模式的支持:块、内联、表格和定位。它使您能够使用相对位置和恒定大小来布局复杂的页面,即使在屏幕尺寸发生变化时也是如此。
多列布局模块目前是 W3C 的候选推荐。此解决方案适用于需要以多列布局并从一列流向下一列的内容。您可以在这个实验室中查看多列布局的交互式示例。
弹性图像和媒体
响应式网页设计的最后一个方面是弹性图像和媒体。基本上,此功能允许您根据设备以不同的方式加载图像或其他媒体,通过缩放或使用 CSS overflow 属性。
CSS 中的缩放对于图像和视频都非常容易实现。您可以将媒体元素的 max-width 设置为 100%,浏览器将根据其容器的大小调整图像的大小。您应该提供质量和尺寸尽可能好的图像,然后让 CSS 将图像调整到正确的大小。
img, object { max-width: 100%; }
缩放图像的替代方法是使用 CSS 裁剪它们。例如,应用 overflow:hidden 允许您动态裁剪图像,以便在容器调整大小以适应新的屏幕环境时,它们能够适应其容器。
在 CSS 中有几种缩放和裁剪图像的选项可能还不够。您真的需要占用用户所有的移动带宽,仅仅因为您没有较小的图像版本吗?为了更好地服务用户,弹性图像可能意味着使用替代图像,甚至根本不使用图像。Web 设计界的开发者们正在提出基于 JavaScript 和 cookie 的解决方案,并且随着响应式网页设计的不断发展并成为许多高质量网站的基础,您可以期待更多这方面的解决方案。
旧版浏览器
那些不支持媒体查询的旧版浏览器怎么办?不支持图像缩放的 Internet Explorer 8 及更早版本怎么办?Polyfills 形式的解决方案可以提供帮助。这里有一些有用的示例。
- css3-mediaqueries.js by Wouter van der Graaf: code.google.com/p/css3-mediaqueries-js/
- Response.js: github.com/scottjehl/Respond
- Fluid images: unstoppablerobotninja.com/entry/fluid-images/
最后
加入响应式网页设计的大军并非易事。请考虑您需要实现的目标,并考虑是否针对特定版本的桌面或移动设备进行设计是最有意义的。
响应式网页设计仍处于早期阶段。网页设计师将继续提供不同的意见并推荐方向,例如是否应优先考虑移动端开发、如何将这些决策融入设计过程、是否需要将切图分解成所有不同的屏幕尺寸,等等。随着屏幕尺寸和外形尺寸的不断增加,这种讨论将继续下去。
HTML 和 CSS 标准正在不断发展,以帮助网页设计师解决这些问题。显然,某种形式的响应式网页设计将被用于应对挑战,同样明确的是,随着发现处理不断变化的设备和浏览器世界的新方法,标准将继续演进。
以下是一些额外的资源