HTML5 和 CSS3 响应式 Web 设计入门指南(一)

原文:Beginning Responsive Web Design with HTML5 and CSS3

协议:CC BY-NC-SA 4.0

一、响应式设计导论

在过去的 20 年里,网站的构建方式已经发生了变化。20 世纪 90 年代,以表格形式构建的网站占主导地位,尽管级联样式表(CSS)规范于 1996 年发布,但 CSS 直到 2003 年中期才真正占据中心舞台。这带来了 CSS Zen Garden 的推出,它展示了 CSS 的力量,以及如何用它来完全重新设计一个站点,甚至不需要接触 HTML。随着后来 CSS 的流行,开发社区标准化了分辨率为 1024×800 的目标屏幕,较大的屏幕边缘留有空白,较小的屏幕需要滚动。这是为了使网站的设计和建设能够为尽可能多的受众服务,因为大多数用户都是通过 1024×800 的分辨率访问网站的。

随着 2007 年 iPhone 的推出,互联网的完整体验随处可见。过去简单、难用的移动浏览器一去不复返了,突然间我们口袋里有了一个完整的桌面级浏览器。各公司的第一反应是创建一个独立的、针对移动设备进行优化的网站,他们认为提供有针对性的用户体验会增加销售额。通常情况下,这些网站是完整网站的缩小版,往往无法向访问者提供他们想要的内容,这意味着最终他们要么离开网站,要么转向完整的网站。

2010 年,手机浏览器实现了 CSS3(层叠样式表 3)媒体查询,从 Android 2.1 开始,到 iOS 3.2。媒体查询的到来带来了针对不同屏幕分辨率的特定风格的能力。

除了屏幕尺寸的变化,随着高像素密度屏幕变得越来越普遍,也有一个巨大的驱动力来提高正在使用的屏幕的质量。retina display 一词是苹果公司在 2010 年 6 月构想出来的,用来描述他们自己手机上的高 dpi(每 CSS 英寸点数)屏幕,他们被认为是将高 dpi 屏幕带入主流的人。因为他们不是唯一部署该技术的公司,所以在构建过程中考虑高 dpi 显示变得越来越重要,以确保您的网站在这些设备上看起来非常棒。确保和实现这一点的最佳方式是通过使用响应式设计方法。

响应式设计已经迅速成为当前 web 开发的趋势,本书旨在带您了解实现响应式设计的不同方法。本章将向你介绍响应式设计。本章包含的部分有:

What is responsive design?   Why is mobile so important?   Responsive design vs. device-specific experiences   Responsive web design is not limited just to mobile   When would you not use responsive web design?   Examples of responsive web design   Looking at HTML5 technologies   What’s new in CSS3

什么是响应式设计?

响应式设计这个术语来源于浏览器对其环境做出反应的方式。响应式设计是一种开发网站的方法,旨在为网站用户提供良好的体验,而不管使用什么浏览器、设备或屏幕大小。使用响应式设计方法设计的网站通过使用流动网格、流动内容(例如,图像、视频和文本)和 CSS3 媒体查询来调整其布局。

响应式设计不再使用像素等固定单位,而是更倾向于百分比等相对单位。这意味着站点不同部分的宽度被设计为视口的百分比。

伊桑·马科特在他的文章《一份清单之外》中首次创造了响应式网页设计这个术语,他将网页比作建筑。他提出了一个关键观点,即我们应该如何将日益增多的网络设备视为同一体验的不同方面。

我们可以把越来越多的网络设备视为同一体验的不同方面,而不是为每一个设备量身定制不相关的设计。我们可以为最佳的视觉体验而设计,但是将基于标准的技术嵌入到我们的设计中,使它们不仅更加灵活,而且更加适应呈现它们的媒体。简而言之,我们需要练习响应式网页设计。1

Ethan Marcotte, off the list.

Ethan 在这里建议的是所有的显示器应该接收相同的内容。然而,它需要被构建为灵活的,以便正确地适合显示器。网站应该以优化设备体验的方式进行调整。

为什么移动如此重要?

随着智能手机的进步,人们可以在任何时候从口袋或包里简单地取出东西来访问互联网。从在当地电器商店查看您感兴趣的电视机的评论,到找到最近的比萨饼店,互联网不再要求您被束缚在一台有过多电缆的计算机上,但它可以与您形影不离。考虑到这一点,开发一个不适合在移动设备上运行的网站的想法是荒谬的。

智能手机市场不再是手机行业的利基部分,而是随着普及而蓬勃发展,智能手机占 2013 年全球手机销量的 57.6%。虽然你可能会认为这些销售中的一部分只是智能手机作为手机计划的一部分的结果,但这仍然是一个惊人的数字。

关于智能手机市场的增长,最有趣的事情之一是来自移动设备的网络流量的百分比正在迅速增加,WalkerSands Digital 估计仅在 2013 年移动流量就增加了 67%(见图 1-1 )。当我们更详细地查看这些统计数据时,我们可以清楚地看到,移动的增长不容忽视。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-1。

Percentage of web traffic coming from mobile devices in 2012-2013

需要记住的一点是,这些数据并没有将商业和消费者流量分开。如果数据是专门针对消费者流量的,我们可能会发现来自移动端的流量比例要高得多。我们之所以会有这样的预期,是因为在工作时间,大多数用户会使用台式电脑来访问互联网。

2013 年 11 月,乔·麦肯在布莱顿正面全裸的演讲中讨论了移动对大型零售商的预期在线影响。在谈到移动的重要性时,他提到了他与一位来自 Target.com 的人就移动对其业务的影响进行的讨论,他的说法支持了我们的预期,即移动的消费者流量将高于商业和消费者流量的总和。他说:

“今年,预计有史以来第一次有超过一半的 Target.com 流量来自移动设备。”3

—— Joe McCann, creative and technical director of new york’s mother, August 11th, 2013

这将是一个令人难以置信的数字,随着移动设备的使用越来越普遍,预计这一数字还会继续上升。移动设备有潜力实现真正的无处不在,这可能是台式电脑和笔记本电脑永远不可能实现的。原因有两个:首先,入门成本低得多,现在购买平板电脑不到 50 美元,购买智能手机不到 30 美元。第二,触摸界面比桌面界面更直观,这意味着以前在使用电脑时可能有问题的人更有可能使用移动平台。虽然现在有触摸界面的台式机和笔记本电脑,但这些都被认为会导致手臂劳损,特别是在肩部,使移动平台更具吸引力。 4

移动市场好转的另一个指标是移动电话的销售数据。它们揭示了智能手机市场尚未饱和,50 亿手机用户群中只有 15 亿是智能手机。此外,2012 年第四季度,平板电脑的销量超过了台式电脑和笔记本电脑的总销量。 5

响应式设计与特定设备体验

正如刚才所讨论的,移动是一个巨大的增长领域,您可能会问,为什么我们不针对我们的目标平台量身打造特定于设备的体验。

当比较响应式网站和独立网站时,很容易断言一个独立的网站会让你提供更好的体验。这是雅各布·尼尔森(Jakob Nielsen)的观点,他写的一篇文章的摘要如下:

“在不同的媒体形式之间重复使用内容和设计,比如平面媒体与网络媒体,或者桌面媒体与移动媒体,虽然成本低廉,但却有失身份。卓越的 UX 需要紧密的平台集成。”6

—Jacob Nelson

事实上,我认为这是一个被误导的观点。响应式开发允许您定义移动设备接收的用户体验,因此,可以通过隐藏和显示不特定于平台的内容来调整内容。

响应式网站设计的主要好处之一就是简单。不需要单独的移动存在,因为 responsive 允许使用相同的 URL 和相同的代码库。有了一个代码库,测试变得更简单,如果您在使用测试驱动开发的工作场所工作,这尤其有用,因为两个代码库可能会导致需要更多的单元测试。

这种简单性的一部分是,使用响应式设计,您只需管理一批内容,而不是本质上管理多个站点上的相同内容。这在网站内容需要由几个人或法律团队批准的组织中尤其重要。这当然会加快速度,从而节省时间和金钱。

对于大多数网站来说,在搜索引擎上获得好的排名是很重要的,谷歌提供了他们希望你如何建立网站的指导。作为他们指南的一部分,Google 建议使用以下注释进行响应式开发:

A single URL for content makes it easier for your users to interact with and share the content.   A single URL for content helps Google’s algorithms index your site.   No redirection or server side device detection is needed for users to get to the device-optimized view, which reduces loading time.   Googlebot user agents have to crawl your pages once, as opposed to crawling multiple times with different user agents, to retrieve your content.

有了这些建议,走响应路线就更有意义了,尤其是如果你的业务依赖于通过谷歌找到。

在权衡使用响应式网站设计或独立网站的利弊时,考虑如何通过更新、修改和添加新功能来继续支持网站也很重要。两个代码库需要两倍的工作、时间和精力来更新和支持。

如果你已经有了一个满意的网站,你可以考虑转换你当前的网站,而不是完全重建。虽然这种方法首先不是移动的(所以根据定义,你将采取一种优雅的降级方法,而不是渐进的增强方法),但它可能允许你使你的站点响应更快。转换现有的站点部分包括重构现有的代码和向 CSS 添加媒体查询。

这种比较似乎严重倾向于响应性开发;但是,单独的站点构建也有一些好处。首先,优化移动站点的性能要容易得多,因为您不需要担心桌面站点所需的媒体查询、JavaScript 和 JavaScript 库的开销。此外,拥有单独的站点构建意味着您不需要接触现有的桌面站点,这反过来意味着不需要重新构建和重新测试。

响应式网页设计不仅限于手机

到目前为止,很多关于响应式 web 设计的讨论都集中在响应式开发如何让你构建在移动设备上运行良好的网站。然而,不仅仅是移动设备可以从响应式网页设计技术中受益。

尽管基于网络的电视服务如 BBC 的 iPlayer、网飞和亚马逊的 Lovefilm 都可以在移动设备上使用,但电视仍然是家庭娱乐的中心。电视最常见的用途是消费媒体:观看电视节目、在视频游戏控制台上玩游戏,或者只是用来播放背景音乐或听广播。

2013 年 4 月,德勤的媒体和娱乐业务进行了一项调查,发现现在 50%的家庭都可以找到视频游戏机;他们还发现,26%的电视直接或通过机顶盒(机顶盒的例子包括游戏控制台、媒体电脑)连接到互联网。在展望这一领域的未来增长时,我们还需要记住,自 2012 年 10 月以来,所有主要的游戏主机都包含网络浏览器,这意味着随着更多用户将这些设备连接到互联网,还有进一步增长的潜力。

除了电视,分辨率更高、显示器更大的台式机或笔记本电脑正变得越来越普遍。如前所述,历史上的网站宽度是以 1024×800 分辨率的屏幕为目标的,然而,截至 2012 年 3 月,1366×768 屏幕已经成为最常见的分辨率。使用响应式技术,你可以利用这些额外的空间,而不仅仅是在网站的两边留有很大的空白。图像可以更大,内容可以间隔更大,用户甚至可以在开始滚动之前看到更多的内容。

如果我们只看一小部分设备,很容易发现屏幕分辨率各不相同。图 1-2 显示了来自同一个制造商(本例中为苹果公司)的移动设备的不同屏幕分辨率,以及最常见的屏幕分辨率和常见的电视分辨率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-2。

Screen resolutions of Apple devices

正如这个简单的例子所展示的那样,仅一家设备制造商就需要支持多种分辨率,当您考虑到其他制造商的大量设备时,现在常见的不同分辨率的绝对水平是惊人的。我们还必须记住,具有新屏幕分辨率的新设备会定期被开发和发布,所以你需要确保你的网站足够灵活,能够与这些新设备一起工作,不管它们是什么。

响应式设计不仅仅是简单的移动与桌面的对比;因此,当您考虑响应式设计时,重要的是不要简单地从这些方面考虑,而是要考虑如何让您的设计在尽可能多的设备上工作,而不管屏幕大小和它们的功能如何。一个很好的例子是,不要假设所有移动浏览器都支持地理位置 API(应用程序编程接口),您可以使用功能检测来识别用户浏览器支持的功能,并逐步增强站点。

什么时候你不会使用响应式网页设计?

有时,使用响应式设计技术并不总是合适的,但相反,对于用户体验来说,构建特定于设备的体验会更好。

响应式设计不适合的一个主要例子是在浏览器中提供类似桌面体验的 web 应用程序。谷歌文档就是这样一个网络应用,在桌面浏览器上你可以得到一个全功能的文字处理器,但由于这种体验在移动浏览器上无法实现,你只能得到一个大大简化的移动版本。原因是对于像 Google Docs 这样功能丰富的网络应用程序来说,小屏幕尺寸是一个很大的挑战。在一个更大的视窗中,很容易将所有的功能放到一个工具栏中,但是,在移动设备上,这是不可能的。因此,为了提供更好的用户体验,将界面剥离回典型用户实际使用的界面是有意义的。这种条带化的后界面将与桌面界面非常不同,以允许代码库精简,这样移动和桌面体验分开构建就有意义了。

除了大型 web 应用程序之外,如果您希望转换现有的站点而不是重建它,查看现有的代码库以确保它不会臃肿是很重要的。只有在现有的代码库相当精简的情况下,才应该将现有的代码库转换为响应式构建。如果你发现你现有的网站过于臃肿,你可以选择在转换网站之前花时间精简它;但是,如果这是不可能的或者预算不允许重建,您可以选择单独构建移动站点。

了解视口

响应设计中的一个重要概念是视口。顾名思义,视口是用来查看网站的视图。

在 HTML5 和 CSS3 之前,我们通常认为网站与浏览器窗口的大小有关。通常情况下,我们的用户会使用 1024×800 的最小显示尺寸,窗口全屏显示,因此,我们会将我们的网站构建为固定的宽度,通常在 960px 到 980px 之间。然而,在开发早期的小型设备时,制造商面临一个问题。当时大多数网站都是这样固定宽度的,比他们新设备的屏幕宽度要宽得多。如果他们以设备的原生分辨率加载站点,那么用户将需要水平和垂直滚动来查看站点。

解决这个问题的方法是将视窗宽度设置为大于设备宽度,这意味着站点将被缩放以适合屏幕。例如,iOS 默认将视窗宽度设置为 980 像素,这样,典型站点的整个宽度将适合屏幕,而无需水平滚动。因此,网站将被缩小,因此,为了阅读网站的内容,用户将放大他们感兴趣的内容。这为旧网站提供了最佳的折衷方案,以确保它们可以在较小的设备上使用。

为了让开发人员控制视口宽度,引入了一个 meta 标签,它允许设置视口宽度和初始比例;我将在本章后面介绍如何使用这个 meta 标签。这意味着您可以告诉移动浏览器以不同的视口宽度呈现站点。在使用响应式设计技术的情况下,您可以选择告诉浏览器将视窗宽度设置为等于浏览器窗口的宽度(或者在单个窗口设备的情况下,等于该设备的宽度)。

图 1-3 显示了视窗宽度和视窗高度相对于浏览器窗口的测量位置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-3。

A diagram illustrating the viewport width and viewport height

多种多样的设备意味着您需要确保在多种不同的视窗尺寸下进行测试。要轻松查找各种流行设备的视口大小,您可以查看 http://viewportsizes.com ,它允许您搜索设备列表,以及设备视口大小的信息。

了解断点

除了理解视口,您还需要很好地理解什么是断点。响应式设计中的断点是网站根据媒体查询声明更改布局的宽度。典型地,响应站点将被构建成与针对特定类型的设备的至少两个但通常是三个不同的断点一起工作。最常用的断点有:

Extra small devices, for example, Phones (<768px)   Small devices, for example, tablets (≥768px and <992px)   Medium devices, for example, desktop computers (≥992px and <1200px)   Large devices, for example, desktops computers (≥1200px)

除了断点,您需要理解的另一个重要术语是状态,即每个断点之间的站点版本。因此,移动、平板和桌面是您的状态,在它们之间有两个断点。

请务必记住,媒体查询响应视窗的宽度,而不是屏幕的宽度。这就是为什么你可以简单地调整你的浏览器来测试你的断点。

响应式网页设计的例子

在编写响应式网页之前,让我们看看一些响应式网站的最佳例子。最好在网上访问这些网站,看看它们所描述的功能。截至本文撰写之时,在此对它们进行了描述。

八月

我们的第一个例子是八月( http://www.agst.co/ ),这是一个发现世界上最有才华的艺术家的地方。该网页是一个单页网站,在页面的末尾有一个表格来记录您的兴趣。

当你调整网站大小时,你会注意到这些变化看起来非常微妙。当您查看每个断点之间发生的变化时,您会注意到下面几节中讨论的差异。

大中型设备

对于大型设备和中型设备状态,August 使用 HTML5 视频循环播放。背景被拉伸到全宽,而内容在容器中居中。当你向下滚动页面时,你会发现这个网站的图片非常多,图片小心翼翼地包裹在文本周围(见图 1-4 和 1-5 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-5。

The imagery on the “august” site wraps around the copy on large and medium devices

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-4。

The initial view of the “august” site, with the video playing in the background

小型设备

对于较小的设备(如平板电脑),August 禁止在后台播放视频,而是选择用图像来代替(见图 1-6 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-6。

On small devices, the “august” site replaces the background video with a static image

调整文字环绕图像的方式,使文字位于图像的上方,以免覆盖主要图像(见图 1-7 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-7。

The wrapping of the copy is adapted to better fit the screen of smaller devices and not cover the image

超小型设备

在针对移动设备的最小视图上,网站通过替换不适合移动设备的图像来适应更小的设备。以视窗高度为目标的媒体查询用于进一步调整字体大小,以确保文本正确地位于页面上(见图 1-8 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-8。

On our extra small devices, the text is resized and the imagery is sized to be fit the smaller display better

当您查看图像的变化时,您可以看到它现在被裁剪了视窗的宽度,并且文本再次被移动到图像的上方,以防止它与图像重叠(参见图 1-9 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-9。

In the content sections, the copy is moved up above the imagery to prevent it overlapping

楠木

Nyetimber ( http://nyetimber.com/our-story/ )网站与 August 网站有很大不同,它是一个多页面响应网站。该网站有一个题为“我们的故事”的部分,它使用视差滚动效果告诉你关于业务的故事;这一页将是下面例子的焦点。

大中型设备

该公司的故事是用桌面上的视差效果讲述的,当你滚动网站时,不同的元素在不同的时间间隔出现在视图中(见图 1-10 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-10。

The Nyetimber site starts wth an introduction to the story

如果你点击任何一个观看电影按钮,你将被带到一个充满视窗的视频(见图 1-11 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-11。

When opened, the videos fill the viewport

当你滚动页面时,你会看到一个区域,在那里你可以将鼠标悬停在面板上,以找到关于该公司的更多信息(见图 1-12 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-12。

Tiled panels allow the user to hover over them

小型设备

在平板电脑上,导航已降至徽标下方,视差功能已被移除(参见图 1-13 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-13。

Instead of

视频现在是内嵌的,而不是全屏显示(见图 1-14 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-14。

The videos are shown inline on small devices, uses the Vimeo HTML5 player for playing the videos

由于用户不能悬停在触摸设备上,面板不再具有悬停动作,而是显示为关于 Nyetimber 的信息列表(见图 1-15 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-15。

The information panels are visible by default on small devices

超小型设备

在手机上,页眉被进一步缩小,以移除导航,并在顶部的一条带上显示徽标(参见图 1-16 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-16。

The menu be default is collapsed on extra small devices, with a menu icon now available to toggle it

点击标题上的导航按钮,导航现在打开(参见图 1-17 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-17。

Taping the menu icon expands the menu

其余内容的大小被调整得更窄,字体大小也更小(参见图 1-18 )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-18。

The content is narrower, blocks are all stacked and the text size optimized for the device

其他示例

在 AWWWards 网站上有更多的例子,那里有一整节是关于响应式设计的。 7

HTML5 入门

响应式设计建立在 HTML5 和 CSS3 带来的新技术之上。让我们看看 HTML5 带来的变化,这样我们可以更好地理解我们正在编写的代码。

HTML5 是最新版本的 HTML 语言规范的规范草案,由万维网联盟(W3C)达成一致。HTML5 规范是 W3C 称之为“开放 web 平台”的更大技术集的一部分,简单地说,这意味着它允许我们构建在任何地方都可以工作的网站和 web 应用程序。当人们提到术语 HTML5 时,他们通常谈论的是“开放网络平台”

在您的项目中使用 HTML5 有很多好处,我现在将讨论这些。

易接近

HTML5 让你的网站更容易被访问。新的 HTML5 语义标签允许屏幕阅读器更容易地识别内容的类型,这允许它们为用户提供更好的体验。此外,HTML5 支持 ARIA(accessible rich Internet application)数据角色,这允许您将角色分配给内容的各个部分。这在使用 JavaScript 更新页面内容时尤其有用,因为您可以定义 ARIA 角色来监视页面的某些部分的变化并通知用户。

视频和音频支持

HTML5 对视频和音频代码都有本地支持。HTML5 视频和 HTML5 音频的主要优势之一是,它们提供强大的移动设备支持,因为它们在浏览器中工作,不需要任何像 Adobe Flash 这样的插件。目前正在讨论的一个领域是 HTML5 是否应该支持内容的数字版权管理(DRM ),并且出于防止像电影和音乐这样的数字媒体的盗版的目的,可能会将某种形式的 DRM 添加到规范中。

更智能的存储

在 HTML5 之前,客户端存储数据的主要方式是使用 cookies 这样做的缺点是,即使服务器不使用它们,它们也会随 HTTP 请求一起发送到服务器。HTML5 引入了 DOM(文档对象模型)存储,它包括 localStorage(持久的)和 sessionStorage(仅在会话期间可用)。DOM 存储的好处是数据只保留在客户端,所以它们不会影响 HTTP 请求的大小,并且它允许您存储更多的数据;目前,DOM 存储允许每个域存储 5MB 的数据。

新的互动

HTML5 的新 JavaScript APIs 使您能够添加新的和改进的交互。这方面的一个例子是新的 API,如拖放、地理定位和历史记录。这些新交互的目的是让你能够构建更丰富、更易于使用的界面。

帆布

HTML5 引入了canvas元素,这是新的 HTML5 标签,可用于绘图。它允许您构建丰富的互联网应用程序,就像过去使用 Adobe Flash 一样。

移动的

HTML5 引入了许多针对移动设备的改进,新的 API(如地理定位)允许网站确定用户的位置并提供特定位置的数据。HTML5 有一个 viewport 标签,允许你定义视窗宽度和缩放设置。还有一些设备特定的标签,使开发人员能够与浏览器特定的功能进行交互,例如,当使用 meta 标签时,开发人员可以告诉 iOS,如果在主页上添加了书签,它应该作为全屏 web 应用程序打开。

查看 HTML5 技术

既然您已经意识到了 HTML5 带来的好处,那么让我们来看看一些单独的核心变化。

文档类型

doctype 告诉浏览器应该如何解析你的文档;因此,它是文档的重要部分,应该包含在 HTML 文档的第一行。先前的 doctype 不仅将文档定义为 HTML4,还提供了规范文档的 URL,如下例所示:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd

新的 HTML5 doctype 要简单得多,您不再需要指定 HTML 的版本或规范文档的 URL,如下例所示:

<!DOCTYPE html>

变化的原因是 HTML 是一个活的规范,在标准化过程中,浏览器将继续规范的新部分。这个想法是,将来可以添加新的特性,而无需对 doctype 做进一步的更改。

新的语义 HTML 标签

当您第一次打开一个 HTML5 文档时,您首先会注意到在整个文档中使用了更多的语义标签。最值得注意的是:

<article>: Defines an article.   <aside>: Defines content alongside the main content.   <figure>: Defines related content, an example of use is photos or code listings.   <figcaption>: Defines the caption for your <figure> element.   <header>: Defines a header for the document or section.   <footer>: Defines a footer for the document or section.   <nav>: Defines a series of links used for navigation around the site.   <section>: Defines a section of content.

下面是一个 HTML5 文档布局的简单示例:

<!DOCTYPE html>

<html>

<head>

<title>Title</title>

</head>

<body>

<header>

<h1>Hello World</h1>

</header>

<div class="content">

</div>

<footer>

</footer>

</body>

</html>

新元标签

除了 HTML5 引入的新语义标签,还引入了一些新的元标签。

视口元标记

新 meta 标记中最重要的是 viewport meta 标记。这个 meta 标签最初是由 Mobile Safari 引入的,它是一种允许开发人员定义视窗宽度和缩放比例的方式。如果使用不当,viewport meta 标签会给用户带来可怕的体验。

视口元标记内容由逗号分隔的键值对列表组成,可以使用的值有:

width:– The width of the viewport.   initial-scale: The scale of the site when it initially loads.   user-scalable: By default, the user can zoom the site, setting “user-scalable” to “no” disables this. This is bad for the accessability of the site so it is discouraged.   maximum-scale: Allows you to define a maximum level that the user can zoom the site. Although not as bad as user-scalable, this can still be harmful to accessability.

如果您要将这个 meta 标记添加到一个无响应的站点,您应该将 viewport meta 标记设置为一个合理的宽度,以便舒适地显示该站点。如果您以一个 980px 的站点为例,它是居中对齐的,您可能希望在边缘周围包括一点间距,因此您可以将视区宽度设置为 1024px,如下例所示:

<meta name="viewport" content="width=1024, initial-scale=1">

对于响应式设计,您希望视口的宽度等于您正在使用的设备的宽度。这有两个主要原因:首先,您将构建以视口宽度为目标的 CSS,因此您希望视口宽度与设备宽度相匹配。第二,它告诉设备该站点是移动优化的,因此它不需要加载一个缩小的大默认视窗。

要使视窗等于您正在使用的设备的宽度,您可以将视窗宽度的值设置为device-width,而不是指定一个特定的大小。您还希望您的站点以默认的缩放级别开始,因此您将initial-scale设置为 1,如下例所示:

<meta name="viewport" content="width=device-width, initial-scale=1">

苹果触摸图标

另一个引入的新 meta 标记是 Apple touch icon meta 标记,它允许您定义当用户将网页保存到主屏幕时将在 iOS 上使用的图标,如下例所示:

<link rel="apple-apple-icon" href="apple-icon-iphone.png">

<link rel="apple-apple-icon" sizes="76x76" href="apple-icon-ipad.png">

<link rel="apple-apple-icon" sizes="120x120" href="apple-icon-iphone-retina.png">

<link rel="apple-apple-icon" sizes="152x152" href="apple-icon-ipad-retina.png">

Although not part of the HTML5 specs, these icons are necessary to allow iOS users to have a nice icon if they save the web site or web application to their home screen.

Web 表单

使用 HTML5 规范升级了输入表单字段。以前,我们仅限于单选、复选框和文本字段,但是,现在我们有了更大范围的输入类型:

search   email   url   tel   number   range   date   month   week   time   datetime   datetime-local   color

使用新输入类型的好处之一是它允许浏览器呈现相关的控件。例如,在移动设备上,如果输入类型设置为email,则会显示一个专用于插入电子邮件地址的键盘。或者,如果输入类型设置为date,则显示本地日期选择器,而不是键盘。这提供了非常好的用户体验,因为它使得表单输入更快。提供了一个为日期字段显示的自定义控件的简单示例:

<input type="date"  id="field" name="field" />

当你在手机上访问它时,在这种情况下是运行 iOS7 的苹果 iPhone,它会在浏览器中显示原生日期选取器桶(见图 1-19 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-19。

as shown on an iPhone running iOS7

当您在桌面浏览器中加载相同的控件时,您将获得桌面的本地控件(参见图 1-20 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-20。

The date input control shown on a desktop in Chrome

HTML5 允许您在输入字段中添加占位符;这意味着您可以为用户提供一个例子,告诉他们应该在输入字段中输入什么样的数据。向输入字段添加占位符属性的示例如下:

<input type="input" placeholder="Sample placeholder" id="field" name="field" />

当载入浏览器时,您会看到占位符的灰色文本框(参见图 1-21 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-21。

Input element with a placeholder

在 HTML5 中,您还可以轻松地向表单添加验证。为了演示这是如何工作的,让我们看几个简单的例子。

最简单的验证形式是使字段成为必填字段,您可以通过将属性required添加到输入字段来实现这一点,如下例所示:

<input type="text" placeholder="e.g``example@example.com

当您点击浏览器中的提交按钮时,用户会看到一条错误消息,提醒他们填写该字段(见图 1-22 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-22。

The browsers error message shown when user tries to submit the form without filling in a required value

如果您想验证一个电子邮件地址,您只需将输入类型设置为email,如下例所示:

<input type="email" placeholder="e.g``example@example.com

当您单击浏览器中的提交按钮时,用户会看到一个错误,告诉他们输入的电子邮件地址无效(参见图 1-23 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-23。

The browsers error message shown when user tries to submit the form with an invalid email address

聚合填充

尽管 HTML5 中有这么多奇妙的新特性,但令人失望的是,我们发现并非所有这些特性都能很好地与我们需要支持的传统浏览器兼容。谢天谢地,这就是 polyfills 的用武之地。术语 polyfill 是 Remy Sharp 在 2009 年写“HTML 简介”时首次提出的。

Remy 说“Shim,对我来说,意味着你可以添加一段代码来修复某些功能,但它通常有自己的 API。我想要一种你可以放进去的东西,它会无声无息地工作。” http://remysharp.com/2010/10/08/what-is-a-polyfill/

因此,根据 Remy 的定义,polyfill 是简单地为浏览器添加缺失功能的一段代码,这通常使用 JavaScript 来实现。这个术语并不意味着暗示旧的浏览器,因为新的浏览器通常也需要填充最新的特性。

HTML5 技术已经有了大量的聚合填充,其中一些流行的有:

Respond.js: https://github.com/scottjehl/Respond Respond.js adds support for min/max-width CSS3 Media Queries to older versions of Internet Explorer (IE6-8). If you are planning on making mobile first responsive sites and need to support older IE, this is required.   HTML5 Shiv: https://github.com/aFarkas/html5shiv HTML5 Shiv enables support for styling HTML5 semantic elements in older versions of Internet Explorer.   CupCake.js: http://www.rivindu.com/p/cupcakejs.html CupCake.js adds support to both localStorage and sessionStorage with a generic API.   FlashCanvas: http://flashcanvas.net/ HTML5 Canvas Polyfill based on using Adobe Flash.

验证 HTML5 页面

您可能以前使用过 W3C 验证器来验证您的 HTML 但是,您可能不知道它已经被更新为对 HTML5 规范草案的实验性支持。

要验证您的 HTML,请访问 W3C 验证器(validator.w3.org),或者通过输入您站点的直接 URL 进行验证,或者将您站点的 HTML 粘贴到提供的文本区域。

可以使用 HTML 的验证:

As a debugging tool: The simplest bug to fix in HTML are those caused by writing invalid code. A simple validation should highlight problems with your HTML, which you can promptly fix.   To maintain quality of code: By ensuring code always passes the W3C validation, it maintains a level of quality in the code.   Ensuring ease of maintenance: Although invalid code may not break your site in the short term, unexpected bugs can crop up when you later amend that code, and validating helps minimize this.

CSS3 的新特性

随着 HTML5 带来的变化,我们也有了新的 CSS3 规范。CSS3 是 CSS 的第三个化身,它扩展了 CSS,允许我们构建更深入、更丰富的用户界面。在您开始使用响应式设计之前,了解使用 CSS3 可以实现什么是非常重要的,因为它将构成您在媒体查询中所做的许多工作的基础。

浏览器供应商前缀

在你开始看 CSS3 的例子之前,你需要了解一些关于 CSS 浏览器前缀的知识。

由于 CSS3 规范仍然是一个工作草案,浏览器供应商经常在特定于供应商的前缀后面实现新功能。这意味着它们能够实现尚未被所有浏览器完全认同的特性。每个供应商都有自己的前缀,最受欢迎的供应商的前缀是:

-moz- Firefox and browsers using Mozilla’s Gecko engine   -webkit- Safari, Chrome, and WebKit   -o- Opera   -ms- Internet Explorer

正如您将在一些示例中看到的,并非所有浏览器都需要 CSS3 属性的前缀版本,因为该属性已经开发了足够长的时间,不需要浏览器前缀,并且一些浏览器供应商从未实现过前缀版本。

在实现了 CSS 属性的前缀版本的地方,实现通常是非常相似的。然而,有一些带有前缀的 CSS 属性互不相同。线性渐变属性就是一个例子,它对每个浏览器前缀都有不同的实现。

值得注意的是,随着谷歌迁移到他们从 WebKit 中分出来的新 Blink 引擎,他们不再在浏览器前缀下添加新功能。引用他们背后的原因:

历史上,浏览器依赖于供应商前缀(例如-webkit-feature)来向 web 开发者提供实验性特征。这种方法可能对兼容性有害,因为 web 内容开始依赖这些供应商前缀名称。”8–闪烁信息页面。

这对开发者来说意味着,当 CSS3 的一些新的实验性特性进入浏览器时,我们将无法立即使用它们,因为我们网站的用户无法使用它们。这并不妨碍我们在自己的浏览器中启用实验性功能,并尝试它们,因为它们可以在 Chrome 的 about: flags 中启用。

厂商前缀 CSS 属性的完整列表可以在: http://peter.sh/experiments/vendor-prefixed-css-property-overview/ 找到。

CSS3 示例

为了真正探索你可以用 CSS3 做什么,让我们看看一些常见的元素,并讨论我们以前如何对它们进行样式化,以及 CSS3 如何使样式化变得更容易。

小跟班

网站使用按钮的目的多种多样,常见的例子有动作调用、表单提交按钮和动作按钮。从历史上来看,设计按钮的样式是相当棘手的,因为你需要使用图像,比如渐变、非网页安全字体和阴影。当我们有不同大小的按钮时,我们就需要一组不同的图像。使用 CSS3,您可以通过编写代码来实现所有这些。这不仅更简单,还意味着您可以将按钮缩放到不同的大小,而无需重新定义一般的按钮样式。清单 1-1 定义了一个渐变的按钮大小。

清单 1-1。带有渐变的单个按钮

<!DOCTYPE html>

<html>

<head>

<title>Button example</title>

<style>

.button {

display: inline-block;

border: 1px solid #1f84ef;

padding: 0px 50px;

line-height: 50px;

-webkit-border-radius: 5px;

-moz-border-radius: 5px;

border-radius: 5px;

background: #6db3f2; /* Old browsers */

background: -moz-linear-gradient(top, #6db3f2 0%, #54a3ee 50%, #3690f0 51%, #1e69de 100%);                 /* FF3.6+ */

background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6db3f2),color-stop(50%,#54a3ee), color-stop(51%,#3690f0), color-stop(100%,#1e69de)); /* Chrome,Safari4+ */

background: -webkit-linear-gradient(top, #6db3f2 0%,#54a3ee 50%,#3690f0 51%,#1e69de 100%); /* Chrome10+,Safari5.1+ */

background: -o-linear-gradient(top, #6db3f2 0%,#54a3ee 50%,#3690f0 51%,#1e69de 100%); /* Opera 11.10+ */

background: -ms-linear-gradient(top, #6db3f2 0%,#54a3ee 50%,#3690f0 51%,#1e69de 100%); /* IE10+ */

background: linear-gradient(to bottom, #6db3f2 0%,#54a3ee 50%,#3690f0 51%,#1e69de 100%);                 /* W3C */

text-transform: uppercase;

font-family: Impact, "Arial Black", sans serif;

color: #fffffe !important;

font-size: 20px;

font-size: 1.42857rem;

text-decoration: none;

-webkit-font-smoothing: antialiased;

text-shadow: 1px 0px 2px #1f84ef;

filter: dropshadow(color=#1f84ef, offx=1, offy=0);

}

.button:hover, .button:active, .button:focus {

text-decoration: none;

background: #54a7f0; /* Old browsers */

background: -moz-linear-gradient(top, #54a7f0 0%, #3c97ec 50%, #1f84ef 51%, #1c5fcc 100%); /* FF3.6+ */

background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#54a7f0), color-stop(50%,#3c97ec), color-stop(51%,#1f84ef), color-stop(100%,#1c5fcc)); /* Chrome,Safari4+ */

background: -webkit-linear-gradient(top, #54a7f0 0%,#3c97ec 50%,#1f84ef 51%,#1c5fcc 100%); /* Chrome10+,Safari5.1+ */

background: -o-linear-gradient(top, #54a7f0 0%,#3c97ec 50%,#1f84ef 51%,#1c5fcc 100%); /* Opera 11.10+ */

background: -ms-linear-gradient(top, #54a7f0 0%,#3c97ec 50%,#1f84ef 51%,#1c5fcc 100%); /* IE10+ */

background: linear-gradient(to bottom, #54a7f0 0%,#3c97ec 50%,#1f84ef 51%,#1c5fcc 100%); /* W3C */

}

</style>

</head>

<body>

<a href="#" class="button">Call to action</a>

</body>

</html>

这段代码将在浏览器中创建一个按钮,如图 1-24 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-24。

The finished CSS button

RGBA 吗

在 CSS 中,颜色通常被定义为十六进制或 RGB(红、绿、蓝)。如果我们想要半透明的背景,就需要使用 1 × 1px 24 位。png 然而,有了 CSS3,我们现在可以用 RGBA 颜色做到这一点。RGBA 颜色是一种应用了 alpha 透明度的 RGB 颜色。这样做的好处是,您不再需要包含图像。为了演示 RGBA,让我们在一个随机的半透明背景的图像上放置一些文本(见清单 1-2)。

清单 1-2。展示 RGBA

<!DOCTYPE html>

<html>

<head>

<title>RGBA example</title>

<style>

.rgba-container, .rgba{

width: 220px;

height: 220px;

position: relative;

}

.rgba{

background: rgba(255,255,255,0.5);

position: absolute;

top: 0px;

left: 0px;

margin: 0px;

line-height: 220px;

text-align: center;

}

</style>

</head>

<body>

<div class="rgba-container">

<img src="http://lorempixel.com/220/220/

<p class="rgba">Hello World</p>

</div>

</body>

</html>

正如您在清单中看到的,您已经将背景设置为rgba(255,255,255,0.5),它是 50%不透明度的白色。根据 RGB 值,您定义的前三个值是红色、绿色和蓝色,第四个值是颜色的不透明度,以十进制数表示。这可以在图 1-25 所示的截图中看到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-25。

The finished text over a translucent image

多列

在以前,如果你想实现多列文本,这是非常困难的。您可以选择在后端计算每列中应该出现多少个单词,或者使用 JavaScript 来设置这些列。CSS3 允许添加多个列,这意味着您可以在样式表中定义列,而不是以编程方式定义。在清单 1-3 中,您将把段落标记中的内容分成两列,每列 10px。

清单 1-3。创建两列

<!DOCTYPE html>

<html>

<head>

<title>Multiple col example</title>

<style>

p{

-moz-column-count: 2;

-moz-column-gap: 10px;

-webkit-column-count: 2;

-webkit-column-gap: 10px;

column-count: 2;

column-gap: 10px;

}

</style>

</head>

<body>

<p>Sed posuere consectetur est at lobortis. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Donec id elit non mi porta gravida at eget metus. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</p>

</body>

</html>

在这个清单中,您将column-count设置为 2,这样内容将显示为两列。然后您将column-gap定义为 10px 来分隔列。您会注意到,对于需要前缀版本的浏览器,您还包括了这些 CSS3 属性的前缀版本。你可以在图 1-26 中看到结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-26。

The finished two columns

渐变面板

作为设计的一部分,你可能想有一个径向渐变,所以不使用图像,你可以使用 CSS3 来实现这一点。对于响应式站点来说,这样做的好处是它将随着块的宽度而缩放。参见清单 1-4 中的例子。

清单 1-4。创建径向渐变

<!DOCTYPE html>

<html>

<head>

<title>Gradient panel example</title>

<style>

.panel{

width: 220px;

height: 180px;

padding: 20px;

background: #77b7ef; /* Old browsers */

background: -moz-radial-gradient(center, ellipse cover,  #77b7ef 0%, #000000 100%); /* FF3.6+ */

background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#77b7ef), color-stop(100%,#000000)); /* Chrome,Safari4+ */

background: -webkit-radial-gradient(center, ellipse cover,  #77b7ef 0%,#000000 100%); /* Chrome10+,Safari5.1+ */

background: -o-radial-gradient(center, ellipse cover, #77b7ef 0%,#000000 100%); /* Opera 12+ */

background: -ms-radial-gradient(center, ellipse cover, #77b7ef 0%,#000000 100%); /* IE10+ */

background: radial-gradient(ellipse at center,  #77b7ef 0%,#000000 100%); /* W3C */

filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#77b7ef', endColorstr='#000000',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */

background-size: 160% 160%;

background-position: center -160px;

}

.panel h1{

margin-top: 0px;

}

.panel h1, .panel p, .panel a{

color: #fff;

}

</style>

</head>

<body>

<div class="panel">

<h1>Intro</h1>

<p>Cras mattis consectetur purus sit amet fermentum.</p>

<p><a href="#">read more</a></p>

</div>

</body>

</html>

你可以在图 1-27 中看到完成的径向梯度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-27。

Our finished gradient

摘要

这一章解释了响应式设计技术如何使你能够构建在各种不同设备上运行良好的网站。重要的是要记住,响应式设计不仅仅是让一个网站能够跨移动和桌面设备工作,还包括构建一个足够灵活的网站,能够跨多种设备良好运行。您无法预测未来访问您站点的设备将如何显示,因此,对于您的编程来说,最好按照大型、中型、小型和超小型来考虑设备,而不是桌面、平板和移动设备。

除了了解在哪里使用响应式设计之外,你现在应该能够识别出不适合使用响应式技术的时候。一个很好的例子是像 Google Docs 这样的桌面替代应用程序,它有很多小设备没有的功能,或者没有足够的空间展示给用户。

了解了响应式设计以及它能为你的网站提供什么之后,看看一些现有的响应式网站,了解一下使用这些技术能实现什么是个好主意。本章还看了几个正在使用的响应式设计的例子。然而,随着响应式设计的流行,有更多的好例子。AWWWARDS 网站有一个很好的不同响应网站的列表,可以在: http://www.awwwards.com/websites/responsive-design/ 找到。

让响应式设计成为可能的当然是 HTML5 和 CSS3 浏览器的改进。作为 HTML5 的一部分,新的语义标签使我们能够为我们的 HTML 带来更多的意义,这不仅有助于我们作为开发人员,而且也使屏幕阅读器能够理解页面的结构。CSS3 也带来了许多改进,让我们能够更好地控制我们的页面样式。

在下一章,我们将探索如何有效地测试我们的响应站点。我们将首先在我们的浏览器中测试我们的网站,看看我们的网站如何在调整到不同宽度的浏览器窗口中工作。然后,我们将开始研究如何在不同的设备上进行测试,从使用模拟器开始,然后研究如何在真实设备上进行测试。

Footnotes 1

伊森·马科特,名单分开。http://alistapart.com/article/responsive-web-design

2

娜塔莎·洛马斯,科技危机。http://techcrunch.com/2014/02/13/smartphones-outsell-dumb-phones-globally/

3

Joe McCann,纽约 Mother 创意技术总监,2013 年 8 月 11 日。

4

http://www.theguardian.com/technology/2013/apr/09/windows-8-touchscreen-laptops-pain

5

http://www.pcpro.co.uk/news/384172/tablet-sales-to-overtake-pcs-this-quarter

6

雅各布·尼尔森- http://www.nngroup.com/articles/repurposing-vs-optimized-design/

7

https://www.awwwards.com/websites/responsive-design/

8

闪烁信息页面 http://www.chromium.org/blink#vendor-prefixes

二、测试响应站点

在第一章中已经介绍了响应式设计以及 CSS3 和 HTML5 中的一些新特性,本章将介绍如何在你开发响应式网站时测试它们。

很可能你已经对你的站点做了一些浏览器测试,以确保你支持你的用户正在使用的浏览器。然而,当测试一个响应站点时,可能会更棘手,因为需要支持的设备范围要大得多。

你需要知道如何有效地测试你的响应站点,记住这一点,本章将解释:

How to test responsive site in the web browser   How to test on a device

在浏览器中测试响应式设计

在网站的开发生命周期中,您测试网站的第一个地方很可能就是您在网上冲浪时使用的浏览器。使用响应式设计,只要你的浏览器支持媒体查询(IE9+,Chrome,Firefox,Opera,Safari),你就可以继续这样做,当你到达需要跨浏览器测试的时候,就转向其他浏览器。

要开始测试响应站点,第一步是将响应站点的 URL 加载到浏览器中。对于这个例子,让我们看看我在 www.jonathanfielding.com 的博客(见图 2-1 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-1。

My blog at www.jonathanfielding.com

因为这个站点是响应性的,所以可以调整浏览器的大小来测试移动视图(见图 2-2 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-2。

My blog resized on a smaller device

这就是我的网站,在桌面和移动视图中。这种简单的调整窗口大小的过程在所有支持媒体查询的浏览器中都是一样的。

浏览器特定的测试功能

我之前提到过,你不需要改变你的浏览器来测试一个响应站点。一些浏览器提供了额外的开发工具来帮助我们测试一个响应站点。虽然您不需要为您的核心开发切换浏览器,但是了解浏览器提供的不同工具是很有用的,因此当您觉得对您的工作流有好处时,您可以切换浏览器来利用特定的工具。

谷歌 Chrome

在 Chrome 中,您可以通过以下步骤模拟一些最流行的设备:

Open the Developer tools, there are two ways in which you can do this, the first is to right-click your page and click Inspect element. The second method is to click on the menu button found to the right of the url field and select Tools ➤ Developer Tools.   Click the Show console icon to the right of the Developer Tools or press the Esc key on your keyboard. This will open the Console drawer, as shown in Figure 2-3.  With the Console drawer open, you can now select the Emulation tab. As you can see in Figure 2-4, the Device line indicates it will default to Google Nexus 4.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-3。

The Console drawer open in Chrome’s InspectorUsing the drop-down menu, you have the option to emulate a specific device. Select the Apple iPhone 4 and click Emulate (see Figure 2-5).

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-4。

The Emulation tab, preselected with a default deviceHaving selected the device to emulate, you will see the viewport has now automatically narrowed, and when you move your mouse cursor over the viewport, it will turn into a circle to signify your finger (see Figure 2-6).

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-5。

Selecting the iPhone in the Emulation tab

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-6。

With a device selected and emulation enabled, the browsers viewport changes Note

Chrome 中的模拟并不是真正的设备模拟,而是简单地模拟设备的一些关键特性。这些包括视窗大小、设备像素比率、用户代理和触摸事件。这意味着任何特定于浏览器的错误都不会显示出来,因为你仍然在 Chrome 中测试。

火狐浏览器

Firefox 对此采取了一种稍微不同的方法。您可以进入响应式设计模式,而不是模拟特定设备,该模式允许您测试常见的视口宽度。

Open the developer tools. The easiest way to do this is to right-click the web page and click Inspect element.   Enter responsive design view; this is achieved using the icon tab on the far right.   Now that you are in responsive design view, you can see the site in a smaller viewport. You have the option to switch to landscape view, enable touch events, or change the viewport size to other commonly used viewport sizes. You can also resize the viewport and then save the new viewport size as a preset. You can see the Firefox interface in Figure 2-7.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-7。

The Firefox inspector with the Responsive Design view active

在设备模拟器上测试

到目前为止,您一直在通过调整浏览器窗口大小或使用浏览器内置的工具来测试响应性站点。虽然这对于查看媒体查询是如何工作的是有效的,但是它不能提供它们将如何影响移动设备上的站点的全貌。我们现在将看看如何在设备模拟器和实际设备上测试我们的项目。

在开始在真正的移动浏览器上进行测试之前,您需要确定您将支持哪些浏览器。根据网站的目标受众,这可能因网站而异,所以如果你已经对用户使用的浏览器进行了一些分析,这是一个好的开始。此外,如果您的网站针对某个特定的国家,通过查看 StatCounter GlobalStats 网站( http://gs.statcounter.com/ ),很容易找到使用每个平台的用户百分比的统计数据。

目前有五种主要的智能手机操作系统:

iOS   Android   Windows Mobile   BlackBerry OS   Firefox OS

决定了要在哪些浏览器上进行测试之后,让我们看看如何在真正的移动浏览器上进行测试。有两种选择:第一种是使用模拟器,第二种是使用一些实际的设备开始测试。

模拟器

模拟器为测试您的响应站点提供了一个极好的开端。它们能够在您的本地机器上运行,通常能够访问您所有的本地文件和您所在网络上的文件。

iOS 模拟器

如果你使用的是 Mac,你可以从苹果应用商店下载 Mac 开发者工具包 Xcode。其中包括 iOS 模拟器,可用于测试响应站点。要开始使用 iOS 模拟器,您需要遵循以下步骤:

Download Xcode from the Apple App Store.   Open Xcode.   Use the menu bar to navigate to Xcode ➤ Open Developer Tool ➤ iOS Simulator.   Open Safari by clicking the Safari icon in the dock.

现在,您可以访问任何网站,包括存储在 Hosts 文件中的本地网站。如果你只是想测试一个 HTML 文件,你甚至可以将它拖放到 iOS 模拟器窗口中。

不幸的是,由于苹果尚未推出与操作系统兼容的 iOS 模拟器版本,因此无法在微软 Windows 上测试移动 Safari 中的网站。

机器人

Android 模拟器作为 Android SDK(软件开发工具包)的一部分在 Windows 和 Mac 上都可用。

苹果个人计算机

Download the Android SDK from http://developer.android.com/sdk .   Extract the zip file to ∼/bin/Android (∼is the Unix shorthand for your user directory, so if your username is Jonathan, the full folder path would be /Users/jonathan/bin/Android).   Open your terminal.   Navigate to the SDK, which is located at ∼/bin/Android/sdk/tools. You can navigate to this path using the change directory Unix command cd, so the full command you enter into your terminal would be ∼/bin/Android/sdk/tools.   Run the SDK Manager by running the ./android command in your terminal. This will load another application (be aware this application may take a while to load and unfortunately does not give any indication of the status of it loading).

Windows 操作系统

Download Android SDK from http://developer.android.com/sdk .   Extract the zip file to C:\Program Files\Android.   Launch the SDK Manager.exe.

共享步骤

You will now be able to select the SDK version you want to test. In this case I have selected Android 4.3. Then simply click Install, reading and accepting any licenses as required.   You then need to select Tools ➤ Manage AVDs on the menu bar. Then click the New button to create a new Android Virtual Device.   You will now need to enter the settings for your Simulator (see Figure 2-8).  You can now select your simulator and click Start (see Figure 2-9).

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-8。

The create a Simulator prompt allows you to configure your simulatorWith the Android emulator installed, you can now simply use the emulator as you would with a normal Android device (see Figure 2-10).

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-9。

Android Virtual Device Manager lists the available Simulators

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-10。

The Android Simulator, with the hardware buttons included in the window

Firefox OS 模拟器

Firefox OS Simulator 作为 Firefox 的附加软件运行,从 Firefox 26.0 开始,它的安装非常简单。

Launch Firefox and open the URL about:app-manager. You will be presented with the built-in App Manager, as shown in Figure 2-11.  You can now click Start Simulator. Because there is no simulator installed, you will be given the option to install the simulator, so click Install Simulator to continue, as shown in Figure 2-12.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-11。

The Firefox App Manager tool can be used to launch a Firefox OS SimulatorYou will now be taken to a web page to install a simulator, simply follow the instructions to install the latest version.   Once installed, go back to about:app-manager and refresh the page. Click Start Simulator and then select the version of the simulator you wish to start. If it still says Install Simulator, you should try to install a different version (see Figure 2-13).

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-12。

The App Manager allows you to install the simulator if it is not already installedAfter a short loading time, you will find yourself at the Firefox OS home screen, where you can select the web browser. The OS Simulator is shown in Figure 2-14.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-13。

The option to choose from different versions of the Simulator to installUpon loading the browser, you can enter your web site URL and start testing your site. The browser is shown in Figure 2-15.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-14。

Firefox OS Simulator home screen, with the browser found in the bottom right-hand corner

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-15。

Firefox running on the Firefox OS Simulator

黑莓操作系统模拟器

BlackBerry Limited 为 BlackBerry OS 提供了可以在 Windows 和 Mac 上运行的模拟器,它们安装起来非常简单。但是,如果您还没有安装这些应用程序,您还需要在 Windows 上安装 VMware Player 或在 Mac 上安装 VMware Fusion,这些应用程序可以在 www.vmware.com 找到。

Download the emulator at http://uk.blackberry.com/sites/developers/resources/simulators.html .   Run the Installer.   Run the Virtual Machine in VMware, as shown in Figure 2-16.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-16。

BlackBerry simulator running in VMware

Windows Phone 模拟器

Windows Phone 模拟器是 Windows Phone SDK 的一部分,目前仅适用于 Windows 8+。不幸的是,运行 Windows Phone 模拟器也有特定的硬件要求,可以在msdn.microsoft.com/en-us/library/windowsphone/develop/ff626524(v=vs.105).aspx找到。

Download the Windows Phone SDK from http://dev.windowsphone.com/en-us/downloadsdk .   Run the SDK installer (this requires 6.5GB of hard drive space).   Upon completion of the installation, you will be told you need a license for Visual Studio, so you can either cancel and use the trial or register for a free license at http://www.visualstudio.com/en-US/products/visual-studio-express-vs .   Check for available updates to the SDK.   Open the command line (cmd) by right-clicking and clicking Run as administrator.   Run the command:

"C:\Program Files (x86)\Microsoft XDE\8.0\XDE.exe" /vhd "C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Emulation\Images\Flash.vhd" /name WP8SDK

With the emulator now open, you should now be able to run Internet Explorer in the Simulator, as shown in Figure 2-17.  To make opening the simulator easier in the future, create a .bat file with the command.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-17。

Internet Explorer running on Windows Phone Simulator

物理设备

到目前为止,我一直关注如何通过在浏览器中测试站点和使用电话模拟器来测试开发机器上的站点。尽管用这些方法测试一个站点非常实用,并且可以让你快速地进行初始测试,但是它们并不能真实地反映出这个站点在真实设备上的运行情况。

其中一个原因是,在开发机器上,您只能使用键盘和鼠标模拟设备使用的不同输入方法。通过在真实设备上进行测试,您可以使用用户会使用的输入法进行测试。如果不在物理设备上测试网站,您可能不会注意到可用性方面的问题。您可能没有注意到的常见问题是按钮太小而无法点击,或者文本在小显示屏上不可读。

考虑到这一点,在尽可能多的设备上测试响应站点是非常重要的。然而,如果你刚刚开始收集设备,选择购买哪些设备可能会非常困难,尤其是在你预算有限的情况下。在这种情况下,了解一下用户正在使用的设备是很有意义的,在选择您需要的设备时,请确保您考虑周全。设备应该至少覆盖最流行的操作系统,如果可能的话,混合高端和低端。

在设备上调试网站

当在各种不同的设备上测试网站时,您需要能够调试用户可能面临的任何问题。进行调试的方式取决于设备的操作系统。

在 iOS 上调试站点

随着 iOS6 的发布,苹果为 iOS 引入了远程调试功能,使开发人员能够将 Mac Safari Web Inspector 连接到移动 Safari 中打开的网站。若要启用此功能,您需要打开 iOS 设置➤ Safari 设置➤高级设置并打开 Web 检查器。在图 2-18 中,您可以看到 Web Inspector 设置已启用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-18。

Advanced settings for iOS Safari with Web Inspector enabled

您还需要确保在 Mac Safari 上启用了“开发”菜单项。要做到这一点,只需打开 Safari 并检查“开发”项目是否出现在顶部菜单上。如果看不到,您需要打开“高级”标签下的 Safari 偏好设置。要启用开发菜单,只需勾选菜单栏中的显示开发菜单复选框,如图 2-19 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-19。

Safari preferences with Develop menu enabled

现在,Mac Safari 和 iOS 设备都已设置好,您可以开始将两者连接在一起,以便调试您的站点。为此,首先使用 USB 电缆将您的设备插入电脑。完成此操作后,您可以在 Mobile Safari 中打开您的站点。要在 Mac 上打开检查器,只需打开显示设备的开发菜单。选择您的设备后,您将看到一个页面列表,您可以选择调试,如图 2-20 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-20。

The Develop menu in Safari

选择要调试的站点后,Safari 检查器面板将会打开,您可以完全访问站点代码。从这里开始调试就像在桌面 Safari 上调试一样,突出显示源代码中的一个元素将会突出显示 iOS 设备上的相应元素。Safari 检查器面板如图 2-21 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-21。

Safari Inspector panel

在 Android 上调试网站

与 iOS 类似,你可以从你的开发机器上调试运行在 Android 上的 Chrome 中的网站。

第一步是配置您的 Android 设备,使其允许远程调试。您的操作方式取决于您的设备运行的 Android 版本。

对于 Android 4.2 或更高版本,进入设置➤关于手机,并点击建立号码七次(听起来有点像旧的 Konami 代码!),然后返回上一个屏幕。然后导航到新菜单选项 Developer options 出现的前一个屏幕。在调试下,您现在可以启用 USB 调试。该设置在图 2-22 中突出显示。

对于 Android 4.0 或 4.1,进入设置➤开发者选项。在调试下,您现在可以启用 USB 调试。该设置在图 2-22 中突出显示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-22。

The Android Developer options with USB debugging enabled

如果您使用的是 Windows,在这个阶段您需要安装 USB 设备驱动程序来连接 Android 设备。这些都可以在 http://developer.android.com/tools/extras/oem-usb.html 下载。

此时,您需要更改 Chrome 中的设置来启用远程调试支持。为此,请在您的网络浏览器中输入 URL about:inspect。这将显示 Chrome 开发工具的设置页面。然后,您可以通过选中“发现 USB 设备”复选框来启用设备发现,如图 2-23 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-23。

Enable device discovery in Chrome

您现在处于可以通过 USB 连接设备的阶段。连接时,您可能会在设备上看到请求 USB 调试权限的警告。为了避免将来出现这种情况,您可以在单击“确定”之前选中“总是允许来自这台计算机”复选框。

你现在可以在你的设备上用 Chrome 打开你的网站了。这将出现在您插入电脑的设备下方的chrome://inspect页面上。如图 2-24 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-24。

Choose a tab on your device you want to inspect

在您的设备上加载一个页面后,您现在可以单击站点名称下方的 Inspect 链接,这将打开检查器。这是你用来检查你桌面上的网站的普通 Chrome 检查器(如图 2-25 所示)。此外,您安装在浏览器上的所有开发工具插件也可以用来调试您的站点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-25。

Chrome Developer Tools inspecting the site on the Android device

开放设备实验室

如果你没有预算购买任何自己的设备,你可以看看在你工作或居住的地方附近是否有任何开放的设备实验室( http://opendevicelab.com/ )。开放设备实验室是一项社区运动,旨在建立任何人都可以去测试的设备池。他们通常有一系列不同的设备,这将使您能够很好地了解您的网站如何在这些设备上工作。

在线解决方案

您可能会遇到这样的情况:您无法接触到设备,并且不住在开放的设备实验室附近。在这种情况下,也有在线解决方案,允许您跨各种设备进行测试。

第一个在线解决方案是 Perfecto Mobile ( www.perfectomobile.com/)。Perfecto Mobile 不是一个模拟器,而是你可以远程控制真实的设备。这意味着你可以更真实地了解用户在使用你的网站时的感受。

第二个解决方案是 BrowserStack ( www.browserstack.com),它允许你在大量不同的浏览器上测试你的网站。除了允许你测试和调试你的响应站点,BrowserStack 还允许你在不同的浏览器和设备上快速生成你的手机截图。值得一提的是,使用 BrowserStack 并不需要公开您的站点,因为它会安装一个浏览器插件,将您的本地站点安全地代理到它们的服务器。

摘要

测试网站对于构建可在各种不同设备上运行的网站至关重要。因此,确保你有一个关于如何测试你的站点的策略是非常重要的。

在计划测试网站的策略时,你应该确保考虑到用户使用的浏览器和设备。

本章探讨了如何在这些不同的平台上进行测试,包括最初如何在浏览器中进行测试,然后在真实设备或模拟器上进行测试。您的策略应该将两者都考虑在内,因为如果您只在桌面浏览器上进行过测试,就不能简单地指望网站在真实设备上运行。像 Perfecto Mobile 和 BrowserStack 这样的第三方工具可能是这个策略中很有价值的部分,因为它们可以让你更好地访问额外的浏览器进行测试。

在 web 开发的大背景下,你需要确保你有足够的时间来测试你的站点。测试不是你可以在过程的最后简单地做的事情,而是应该成为你工作的一个组成部分,你应该能够在实现的时候测试一个特定的特性。

彻底的测试使你能够确保不会遗漏任何东西,并且你已经看到了用户从不同设备获得的不同体验。

在下一章,我们将探索媒体查询的力量,以及它们对响应式设计的重要性。你不仅会对什么是媒体查询有一个全面的了解,还会了解它们在构建一个能够响应用户浏览器环境的站点时所给予你的灵活性。

三、媒体查询的力量

第一章介绍了 CSS3,但有一个明显的遗漏:没有讨论媒体查询。而且理由很充分;媒体查询是响应开发的一个如此大的领域,它们应该有自己的一章。

媒体查询是响应式设计的核心,因为它们允许开发人员根据设备的功能来确定特定的 CSS 样式。最常见的目标功能是视口宽度;然而,媒体查询远不止这些,我将在本章中解释这些功能。

本章将涵盖:

  • 媒体查询简介
  • 在 CSS 中使用媒体查询
  • 移动优先与桌面优先
  • 瞄准高像素密度显示器

媒体查询简介

媒体查询是响应式设计的基础,允许您根据指定的查询来更改网站的外观。媒体查询可以分成两种类型的部分:媒体类型和媒体表达式。

为了开始对媒体查询的介绍,让我们看看媒体类型,它是作为 CSS2.1 规范的一部分引入的。

媒体类型

在新的 CSS3 草案规范之前,CSS2.1 引入了媒体类型,允许开发人员添加针对不同类型设备的媒体相关样式表。总共有十种不同的媒体类型,其中三种你可能已经遇到过:全媒体、屏幕媒体和印刷媒体。

如果您在过去遇到过媒体类型,很可能您已经看到过它们被用来根据设备类型启用或禁用样式表。这方面的一个例子是:

<link rel="stylesheet" type="text/css" href="all.css"    media="all" />

<link rel="stylesheet" type="text/css" href="screen.css" media="screen" />

<link rel="stylesheet" type="text/css" href="print.css"  media="print" />

除了屏幕和打印样式表,还有许多其他媒体类型支持各种其他设备:

all: all devices   aural: speech synthesizers   braille: braille tactile feedback devices   embossed: paged braille printers   handheld: small or handheld devices   print: printers   projection: projected presentations, like projectors and projected slides   screen: computer screens   tty: media using a fixed-pitch character grid, like teletypes and terminals   tv: television-type devices

除了能够为每种媒体类型指定不同的样式表之外,还可以使用以下语法将这些样式包含在您的样式表中:

@media print {

/* print styles go here */

}

在主样式表中包含不同的媒体类型查询有几个好处:

It reduces the number of HTTP requests. An increase in the number of HTTP requests can lead to reduced performance of loading a site.   Separate style sheets can increase the time that the page is blocked from rendering, as most browsers will wait until all the individual style sheets are downloaded before they will render the content.

Stoyan Stefanov 的一项实验发现,不仅浏览器下载打印样式表,大多数浏览器还在呈现之前等待它下载(即使并不严格要求向用户显示页面)。这包括用户不太可能打印的移动浏览器。 1 因此,这里的好处是通过减少浏览器必须加载的样式表数量来减少这种阻塞。

当应用媒体类型时,考虑浏览器在任何给定的时间将只声明一种媒体类型。这意味着,如果浏览器实现了手持媒体类型,那么您的屏幕媒体类型的样式将不会被应用,尽管假设手持设备具有屏幕。

对于媒体类型,您依赖于浏览器来实现您期望的设备媒体类型。浏览器供应商并不总是像预期的那样实现媒体类型的一个很好的例子是电视上的浏览器。尽管有些浏览器可以正确支持电视媒体类型(包括 Opera),但有些电视浏览器会错误地同时应用电视和屏幕媒体类型。这意味着,如果您使用一种屏幕媒体类型,将特定于您的桌面体验的样式作为目标,它们可能会意外地应用到电视上,这根据规范是不正确的:

A user agent can only support one media type when rendering documents. 2

媒体查询

CSS3 中添加了媒体查询作为媒体类型的扩展,目的是让开发人员能够更好地控制他们的网站在不同浏览器和设备上的显示方式。其思想是,不必为不同的设备构建和维护每个页面的多个版本,而是可以根据设备的属性、特性或特征在 CSS 中修改单个网站。

与简单地告诉您设备类型的媒体类型不同,媒体查询为 CSS 添加了一个逻辑层次,即如果满足某个条件,则应该应用样式,否则应该忽略它们。这意味着,您现在可以针对设备的单个特征,而不是简单地针对设备的类型。

媒体查询可以测试什么?

媒体查询可以测试各种不同类型的查询。这些将在接下来的章节中讨论。

宽度|最小宽度|最大宽度

width查询允许您测试浏览器视窗的宽度。这使您能够以特定的浏览器宽度为目标样式。您不仅可以根据设定的宽度进行测试,还可以将浏览器视窗的最小宽度或最大宽度作为目标。这意味着您可以使用该查询来匹配各种不同的设备宽度。width媒体表达是最常用的媒体表达之一,用于调整站点以做出响应。

高度|最小高度|最大高度

height查询允许您测试浏览器视窗的高度。类似于width查询,您可以确定精确的高度、最小高度或最大高度。虽然height查询比width查询用得少,但是height查询在您希望确保特定内容在页面首次加载时对您的用户可见(或不可见)的情况下特别有用,因为您可以使用它来调整内容的高度,使其最适合视窗的高度。

设备宽度|最小设备宽度|最大设备宽度

device-width查询允许您测试设备的宽度。您可以设定精确宽度、最小宽度或最大宽度。widthdevice-width的区别在于,宽度与浏览器的width有关,而device-width与设备屏幕的宽度有关。虽然有一些使用device-width的用例,但问题是如果用户在桌面上调整浏览器的大小,网站不会调整到合适的大小。此外,如果您正在使用 viewport meta 标签并将width设置为等于device-width,您应该只使用width查询。

设备高度|最小设备高度|最大设备高度

device-height查询允许您测试设备的高度。您可以设定精确的高度、最小高度或最大高度。device-heightheight的区别在于device-height与设备屏幕的高度有关,而height与视窗的高度有关。这种区别在能够调整浏览器窗口大小的设备上非常重要。

纵横比|最小纵横比|最大纵横比

aspect-ratio查询允许您测试设备视窗的纵横比。器件的纵横比是器件较长边的长度与器件较短边的长度之比。当您想要将资产定位为匹配设备的宽高比时,包括显示视频,这是对用户设备的最佳优化,那么aspect-ratio查询可能特别有用。

设备纵横比|最小设备纵横比|最大设备纵横比

device-aspect-ratio查询允许您测试设备的纵横比。device-aspect-ratioaspect-ratio的区别在于device-aspect-ratio与设备屏幕的纵横比有关,而aspect-ratio与视窗的纵横比有关。这种区别在能够调整浏览器窗口大小的设备上很重要,因为aspect-ratio和视窗大小一样灵活,而device-aspect-ratio的值不会改变。

颜色|最小颜色|最大颜色

color query允许您根据每个颜色组件的位数来测试设备的颜色功能。

颜色指数|最小颜色指数|最大颜色指数

color-index查询允许您测试设备支持的颜色数量,该值必须是整数,不能是负数。

单色|最小单色|最大单色

monochrome查询允许您在单色设备上测试每像素位数,使用1表示真,0表示假。

分辨率|最小分辨率|最大分辨率

resolution查询允许您测试设备的像素密度。分辨率查询接受三种不同类型的值:dpi(每 CSS 英寸点数)dpcm(每 CSS 厘米点数)和dppx(每像素点数)。首选是使用dppx,这是比dpcmdpi更新的规范。dppx 相对于其前辈的优势在于,它与屏幕的像素密度直接相关,因此开发人员更容易理解。

扫描

scan查询允许您测试设备的扫描过程。这是电视机特有的,它可以进行逐行或隔行扫描。这两者的区别在于,逐行显示一次在显示器上画出所有的线,而隔行显示画出所有的奇数线,然后画出偶数线,以欺骗眼睛认为他们一次看到了所有的线。

格子

grid查询允许您测试设备是网格设备还是位图设备,有两个可能的值。如果该值被设置为 1,那么如果设备的显示是基于网格的,查询将启用 CSS,例如只有一种固定字体的电话显示。或者,您可以通过将该值设置为 0 来检查所有其他设备。

方向

orientation查询允许您测试设备是横向的还是纵向的,并适当地应用您的 CSS。orientation查询的一个典型用例是,您可能希望在纵向的一列和横向的两列之间切换。

Note

您可以使用的查询类型取决于设备的媒体类型。并非所有媒体类型都支持所有查询的原因是,这并不总是有意义的,例如,如果用户使用听觉设备,则涉及视口或屏幕的查询(如宽度和设备宽度)将没有意义。

媒体查询的语法

既然您已经熟悉了媒体类型和媒体查询及其用途,那么让我们来探索编写它们的方法。

媒体查询至少由媒体类型组成,并且可以另外具有一个或多个媒体表达式,其返回 true 或 false。对于要应用的 CSS,媒体类型应该与加载页面的设备相匹配,并且所有媒体表达式必须返回 true。媒体查询可以根据您的需要具体或模糊,从而确保您的 CSS 完全按照您期望的方式应用。查看编写媒体查询的语法的最佳方式是深入研究一些示例。

第一个例子展示了如何将 CSS 添加到具有小视窗的设备中;通常是移动电话。如果您只想在小视窗上启用 CSS,那么您需要添加一个规则来定义 CSS 将应用到的视窗的宽度上限。在这种情况下,您可以添加一个max-width规则,并将值设置为767px。一个简单的例子是:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在本例中,媒体类型被设置为all,这意味着它适用于所有媒体类型。然后有一个 max-width 设置为767px的媒体表达式,因为您希望将目标指向额外的小设备(例如,移动电话),在这种情况下,它被定义为小于767px。这里的理由是,许多可能被归类为小型设备的设备,如 iPad,其最小宽度为768px。这个媒体查询背后的逻辑是,对于所有设备,如果视口的宽度小于或等于767px,则应用 CSS 样式。

如果您只想将 CSS 应用于屏幕设备,您可以将媒体查询中使用的媒体类型更改为 screen。这一变化反映在这个更新的例子中:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个媒体查询的逻辑类似于上一个例子,但是,关键的区别是您已经将媒体类型更改为screen。因此,逻辑是,对于类型屏幕的所有设备,如果视口的宽度小于或等于767px,则 CSS 是活动的。

“非”逻辑运算符

如果您想将 CSS 应用于除屏幕之外的所有媒体类型,您可以利用not逻辑运算符。媒体查询中的 not 逻辑运算符告诉浏览器反转表达式的结果。对于屏幕示例,您可以简单地将 not 逻辑运算符添加到表达式的开头:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以对于这个例子,逻辑是如果浏览器不是宽度小于等于767px的屏幕设备,那么样式表就会被激活。

“唯一”逻辑运算符

only逻辑运算符用于防止不支持媒体表达式的旧浏览器试图处理媒体查询。如果没有only操作符,旧的浏览器将读取媒体类型,但是,它将不能理解媒体表达式;因此,媒体表达式被忽略,样式被应用。

出现这种现象的原因是,在用于媒体查询之前,媒体属性最初用于媒体类型。尽管 CSS 规范已经扩展到包括 CSS3 中的媒体查询,但是您仍然需要支持使用旧规范的旧浏览器。使用only逻辑运算符的媒体查询只是在媒体类型运算符前加上。此示例更新了先前用于测试超小型设备的媒体查询:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本例中媒体查询的逻辑与之前完全相同,但是,您现在添加了only逻辑运算符,这将防止此媒体查询中包装的样式在较旧的浏览器中被错误地应用。

使用多个表达式

媒体查询真正强大的原因之一是能够一起使用多种媒体表达式。这意味着,如果你想针对小型设备,如平板电脑,而不影响额外的小型设备,你可以这样做,使用两种媒体表达方式,而不是一种。

要链接表达式,您需要在媒体表达式之间使用and关键字。本例使用最小宽度768px和最大宽度1023px来确定设备是否为小型设备:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个媒体查询的逻辑是,如果媒体类型是 screen,viewport 等于或大于768px,并且小于或等于1023px,那么样式表将被激活。

链接媒体查询

到目前为止,示例只是使用了单独的媒体查询;但是,通过链接媒体查询并允许在多种情况下应用 CSS,您可以在任何查询返回 true 时应用 CSS。每个媒体查询可以具有其自己的媒体类型和其自己的媒体表达,这意味着单独的媒体查询可以针对不同的媒体特征、类型和状态。要使用多个媒体查询,只需在每个查询之间添加一个逗号来分隔它们,然后将对每个查询进行单独评估,以查看它们是否为真,如下例所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在本例中,有两个媒体查询。如果浏览器的宽度等于或大于768px并且小于或等于1023px,则第一个媒体查询将为真。如果设备的方向是纵向,则第二媒体查询将为真。现在,如果这两个媒体查询中的任何一个为真,那么样式将被激活。

您可能希望使用多个媒体查询的一个常见示例是针对在不同浏览器中以不同方式实现的功能。例如,当您使用最小分辨率表达式时,如以下代码所示:

@media only screen and ( -webkit-min-device-pixel-ratio: 2 ),

only screen and ( -o-min-device-pixel-ratio: 2/1 ),

only screen and ( min--moz-device-pixel-ratio: 2 ),

only screen and ( min-device-pixel-ratio: 2 ),

only screen and ( min-resolution: 192dpi ),

only screen and ( min-resolution: 2dppx ) {

/* High resolution styles here */

}

在 CSS3 媒体查询的早期,需要实现一种针对高像素密度设备的方法,这导致 WebKit 在其供应商前缀下实现device-pixel-ratio表达式。随着规范的成熟,正确的实现是使用“resolution”表达式;然而,为了支持这些旧的浏览器,您需要使用多个媒体查询。

在 CSS 中使用媒体查询

既然您已经探索了编写媒体查询的语法,那么是时候看看如何将它们应用到页面上了。这三种方法是:

Separate style sheets for each media query   Use @import in the main CSS file to load CSS files conditionally   Use the media queries inside CSS file

单独的样式表

通常,在过去使用屏幕或打印样式表时,每种样式表都有一个样式表,其中包含适用于哪种媒体类型的规则。类似地,您可以通过媒体查询来有条件地启用和禁用样式表。为此,您可以在用于包含样式表的链接标签上使用 media 属性。这个属性与您之前在样式表中添加媒体类型规则时使用的属性相同。添加规则时,只需将其放入“媒体”属性,如下例所示:

<link rel="stylesheet" media="screen and (min-width: 768px) and (max-width: 1023px)

" href="tablet.css" />

在这个例子中,媒体查询用于检查用户是否在小型设备上,并且这被简单地添加到媒体属性中。

使用单独的样式表的好处是,它允许您更容易地划分代码。请记住,媒体查询中的所有样式表都被下载到用户的设备上,如果不需要,它们就不会被激活。这意味着,通过使用单独的样式表,可以增加向服务器发出的 HTTP 请求的数量。

使用@import

如果您想为每个媒体查询使用单独的样式表,但不想在 HTML 中定义它们,您可以使用 CSS @import 语法并应用媒体查询。@import 语法可以分为三个部分:

The @import declaration   The URL to CSS file to include   One or more media queries

将这些放在一起,您最终会得到以下结果:

@import url("tablet.css") screen and (min-width: 768px) and (max-width: 1023px);

在本例中,您使用媒体查询来检查用户是否在小型设备上,并简单地将其添加到用于加载tablet.css文件的@import 语法中。

类似于在标签中使用链接到页面的单独样式表,通过@import 加载的样式表增加了 HTTP 请求的数量。然而,除此之外,@import 可以防止样式表被同时下载。

在 CSS 中使用媒体查询

您可以在站点的样式表中定义媒体查询,而不是将 CSS 分成单独的样式表。这允许您定义新的样式,并在条件为真时对现有样式应用覆盖,从而利用 CSS 的级联特性。

要在 CSS 文档中编写媒体查询,可以使用@media 语法。如何使用该语法的分类如下:

The @media declaration   One or more media expressions

因此,@media语法的一个例子是:

@media only screen and (min-width: 768px) and (max-width: 1023px){

/* Your styles. */

}

尽管这只是一个简单的例子,但它向您展示了在 CSS 文件中包含媒体查询是多么容易。与添加到您的<head>中的@import和单独的文件不同,在主 CSS 文档中使用媒体查询与在主 CSS 文档中包含您的媒体类型具有相同的好处,这些好处是减少 HTTP 请求和减少阻塞。

移动优先与桌面优先

开发人员通常会以他们最舒服的方式编码——毕竟,人类是习惯性的动物,不管有些人怎么认为,开发人员也是人。因此,当响应式 web 设计出现时,最常见的方法是首先构建桌面站点,然后使用媒体查询使其适应移动应用程序;毕竟,他们的大部分用户仍然来自于桌面应用,开发人员已经习惯了为桌面开发。

这种方法被称为适度降级,其思想是,你应该首先创造尽可能好的体验,然后开始考虑浏览器功能下降时的降级。对于一个响应式网站来说,这意味着当视窗缩小时,网站会缩小,删除内容和功能。

然而,还有一种更适合响应式设计的方法,叫做渐进增强。渐进增强并不是一个新的想法;它是由 Steven Champeon 在 2003 年奥斯汀的西南偏南互动会议上首次提出的。在为 Webmonkey 写的后续文章中,Steven 说:

Don’t try to mix the representation into the tag that the lowest common denominator browser can’t handle anyway, but strip it out. Make sure that only competent browsers will request it first. The more we know about what browsers support, the better it will be for us to set tags and styles. 3

Steven 所说的是用最少的功能为浏览器建立你的网站,然后通过增加新的功能和内容逐步改进网站。如果您想将这种方法应用到一个响应式站点,您应该首先构建移动站点。然后,随着设备性能的提高,您可以增强这些站点。这种渐进式改进被称为移动优先响应设计。

当把优雅的退化与渐进的增强相比较时,乍一看,它们只是一枚硬币的两面。对于适度降级,我们只需从构建最好的网站开始,然后降低体验;对于渐进增强,我们从构建功能最差的浏览器的体验开始,然后渐进增强桌面的体验。

事实上,当我们首先构建桌面网站时,我们通常会在网站上添加许多功能。这些可能为桌面用户提供了很好的用户体验,但是,通常有一些功能不能很好地扩展。接下来的问题是如何让网站的这一部分在移动应用上工作。这正是卢克·乌鲁布莱夫斯基 2009 年在他的博客上提出的观点:

Mobile devices require the software development team to focus only on the most important data and actions in the application. There is no room for irrelevant and unnecessary elements on a 320×480 pixel screen. You must prioritize. Therefore, when a team first designs a mobile device, the end result is an experience of focusing on the key tasks that users want to complete, without unnecessary detours and interface fragments that can be seen everywhere in today’s desktop access websites. This is a good user experience, which is also good for enterprises. 4

他的意思是,通过首先关注移动设备,我们可以为用户提供更好的体验。我们不会让不必要的功能塞满我们的界面,因为我们必须优先考虑对用户重要的功能。通过扩展浏览器的功能,移动应用还使我们能够添加额外的功能,例如,精确的地理位置信息和触摸事件。这意味着,虽然移动浏览器在某些方面可能有局限性,但它们提供了我们可以轻松利用的额外功能。

当我们对我们的移动构建感到满意时,我们就可以继续扩展视口并逐步增强站点,使用诸如特征检测之类的技术来允许我们在支持它们的浏览器上瞄准特征。

先看看如何建立一个移动网站

既然您已经了解了构建移动优先的响应型站点的好处及其背后的方法,那么让我们来看看如何构建移动优先的站点。

首先要开始使用移动设备,你需要把一些基本的 HTML 放在一起。在这个例子中,你将输入一些可用于博客文章的 HTML,包括标题、文章和相关文章的列表,如清单 3-1 所示。

清单 3-1。我们的移动第一个例子的 HTML

<!DOCTYPE html>

<html>

<head>

<title>Mobile First</title>

<meta name="viewport" content="width=device-width">

<link rel="stylesheet" type="text/css" href="mobile-first.css">

</head>

<body>

<header>

<h1>Blog</h1>

</header>

<div class="content" role="main">

<article>

<h2>Article title</h2>

<p>02/12/2013</p>

<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Vestibulum id ligula porta felis euismod semper.</p>

</article>

<aside>

<h2>Related Articles</h2>

<nav>

<ul>

<li><a href="#">Article item 1</a></li>

<li><a href="#">Article item 2</a></li>

<li><a href="#">Article item 3</a></li>

</ul>

</nav>

</aside>

</div>

</body>

</html>

如果你把它加载到你的浏览器中,你会得到一个简单的没有任何样式的单列页面,如图 3-1 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-1。

Our mobile first example site before we have applied any styles

因为您首先构建移动设备,所以您将首先集中精力构建主 CSS 来设计页面样式。您将应用以下样式:

body: Both margin and padding set to 0px, the font size set to 14px, and the line height set to 18px   header: Add background color and padding   h1: Set the color to white   aside and article: add margin of 20px to both the left and right   article: add a border to separate the article from the related articles

将这些放在一起后,它会看起来像是我为清单 3-2 编写的代码。

清单 3-2。我们的示例 mobile first 站点的基本 CSS

body{

margin: 0;

padding: 0;

font-size: 14px;

line-height: 18px;

}

header{

background: #304480;

padding: 10px 20px;

}

h1{

color: #fff;

}

article, aside{

margin: 0 20px;

}

article{

border-bottom: 1px solid #304480;

}

如果你看一看应用了这些额外样式的网站,你会发现你的网站在我们的超小型设备上运行得很好,如图 3-2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-2。

The site, as it looks on browsers with a extra small viewport

然而,如果你只是简单地将浏览器拉伸到屏幕的宽度,网站看起来就不那么好了,如图 3-3 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-3。

Our mobile first site, shown on a larger viewport

单栏网站在移动设备上运行良好,但是在较大的视窗中,将相关文章列表显示为侧边栏并限制网站的宽度是有意义的。

当您从超小型设备视图增加站点的视口时,您会达到小型设备的宽度,例如平板电脑。在本例中,您将把 iPad 的最小宽度 768px 作为小型设备视图的基础,并将其用于媒体查询。因此,媒体查询的目标最小宽度为 768 像素,如清单 3-3 所示。

清单 3-3。我们的媒体查询针对我们的小型设备

@media screen and (min-width: 768px){

header, .content{

width: 728px;

margin: 0 auto;

padding: 10px 20px;

}

article, aside{

float: left;

margin: 0px;

}

article{

width: 80%;

border-bottom: 0px;

}

aside{

width: 20%;

}

}

因为你已经做了所有的移动来使站点在平板电脑上工作,你只需要增加页面的宽度来利用更大的视窗,代码如清单 3-4 所示。

清单 3-4。我们针对更大视窗的媒体查询

@media screen and (min-width: 1024px){

header, .content{

width: 940px;

}

}

现在,如果你在浏览器中查看这个,你会看到网站现在被设计成一个漂亮的两栏布局,相关文章显示在侧边栏中,如图 3-4 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-4。

Our completed site shown on a larger device viewport

在这个例子中,我们从移动优先的角度构建了一个简单的响应博客。我们最初构建了核心样式,然后随着浏览器视窗大小的增加,我们引入了新的媒体查询,以使我们的网站能够响应视窗的宽度,并利用增加的空间。

移动优先的警告

使用移动优先的方法建立网站有一些警告,最大的警告是浏览器对媒体查询的支持程度。总的来说,浏览器对媒体查询的支持是好的,然而,最早支持媒体查询的 Internet Explorer 版本是 Internet Explorer 9。这意味着通过移动优先的方法,Internet Explorer 8 和更早版本将接收您的移动站点。您可能很乐意保留它,或者您可以选择添加一个名为Respond.js的 polyfill,这将为 Internet Explorer 8 提供有限的媒体查询支持。

在手机的限制下建立一个网站也是一个挑战;如果你像我一样,在职业生涯中使用鼠标事件(如悬停和点击)来积累经验,你会发现它们在较小的触摸屏设备上消失了,取而代之的是手指点击和滑动。

从移动优先的角度出发,我们应该从一开始就考虑用户使用的输入类型,旨在支持用户与网站交互的各种方式。我们在正确支持多种输入类型时可能会发现的一个问题是,对于某些动作,一些浏览器试图预测我们希望我们的网站如何工作。

一个例子是鼠标悬停交互;在一些触摸屏设备上,浏览器已经实现了悬停事件,以便可以切换它,当你第一次点击元素时,悬停状态会打开,第二次点击时会关闭。这样做的目的是允许用户访问原本只能在悬停状态下访问的内容(并且您不能在移动设备上悬停)。这本身增加了额外的挑战,因为具有悬停状态的区域也可能是一个链接,这意味着当用户点击它时,它应该已经有一个动作。不幸的是,媒体查询不能确定设备是否是触摸设备,并且特征检测技术也不能准确地确定用户是否正在使用触摸设备。因此,在构建网站时,我们需要考虑处理这些交互的新方法。

瞄准高像素密度显示器

移动设备具有高像素密度变得越来越普遍。对于最终用户来说,高像素密度显示器的优势显而易见,可以提供更清晰的文本和图像。受益于这场显示技术革命的不仅仅是移动设备;笔记本电脑制造商也在他们的高端电脑上提供更高质量的显示器。

考虑到这一点,在构建网站时,您需要考虑如何利用显示技术的这一变化,谢天谢地,浏览器没有让我们束手无策,因为媒体查询支持使用分辨率媒体功能测试显示器的像素密度。

当使用媒体查询来定位具有高像素密度显示的设备时,您可以使用媒体查询分辨率功能来检查最低屏幕分辨率。此功能支持三种不同类型的设备:

dpi: dots per CSS inch   dpcm: dots per CSS centimeter   dppx: dots per pixel unit, 1dppx = 96dpi

尽管这些都是受支持的单元,但浏览器供应商建议开发人员使用 dppx。如果你正在使用dpi :

Consider using “dppx” instead of “dpi”, because “dpi” in CSS refers to dots per CSS inch, not dots per physical inch, so it does not correspond to the actual “dpi” of the screen. In the media query expression: print, not all, (-WebKit-min-device-pixel-ratio: 1.25), (min-resolution: 120 dpi) https://github.com/h5bp/html5-boilerplate/issues/1474

这个警告是在使用一个流行的开源模板 HTML5 boilerplate 时显示的。正如警告所指出的,dpi 是每 CSS 英寸的点数,这可能会给开发人员造成混淆,他们不知道媒体查询中的 dpi 不是屏幕的实际 dpi。

在我展示一些如何实现针对高像素密度显示器的媒体查询的例子之前,您需要了解浏览器支持。如前所述,CSS3 仍然是一个草案标准,这意味着每种浏览器都有自己的厂商前缀实现。此外,媒体查询分辨率的一些早期实现使用设备的物理分辨率,而不是其 CSS 分辨率。此外,尽管您应该使用 dppx 作为解析查询的单位,但它是在 dpi 之后添加到规范中的,因此为了与没有实现dppx的浏览器兼容,您还应该包括dpi。这意味着您在编写媒体查询时需要考虑所有这些因素,这增加了读取媒体查询时的复杂性。为了覆盖尽可能多的浏览器,可以使用以下媒体查询:

@media only screen and (-webkit-min-device-pixel-ratio: 2),

only screen and (-o-min-device-pixel-ratio: 2/1),

only screen and (min--moz-device-pixel-ratio: 2),

only screen and (min-device-pixel-ratio: 2),

only screen and (min-resolution: 192dpi),

only screen and (min-resolution: 2dppx) {

/* High resolution styles here */

}

为了正确地了解我们如何处理这些高像素密度设备,让我们看一个简单的例子,看看一个徽标在没有任何媒体查询的情况下会是什么样子,然后编写媒体查询以在其位置显示更高分辨率的图像。

首先,让我们编写一些简单的 HTML,使用图像替换技术在页面上的 H1 中添加一个徽标。我们的 HTML 如清单 3-5 所示。

清单 3-5。高分辨率图像示例的 HTML

<!DOCTYPE html>

<html>

<head>

<title>High Res Image Example</title>

<meta name="viewport" content="width=device-width">

<link rel="stylesheet" type="text/css" href="high-res-images.css">

</head>

<body>

<h1>logo</h1>

</body>

</html>

然后你需要创建 CSS。现在,您只需创建 CSS 来显示标准分辨率的徽标。让我们在徽标周围添加一个边框,以清楚地显示图像的大小。

清单 3-6。我们的标志的基本 CSS,使用正常的低分辨率图像

h1{

width: 100px;

height: 100px;

text-indent: 100%;

white-space: nowrap;

overflow: hidden;

background-image: url("low-res-image.png");

border: 3px solid #d3000c;

margin: 0px;

}

现在,当你在具有高像素密度显示器的设备上查看时,你可以看到图像的放大导致了一些模糊,如图 3-5 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-5。

Our lower resolution logo shown on iOS

我们现在可以看看如何添加媒体查询来处理加载更高分辨率版本的徽标。

要加载图像的更高质量版本,请使用您之前使用的查询,然后添加一些 CSS 来将背景图像更改为图像的更高分辨率版本。您还需要将背景图像缩放到原始图像的大小,以便它适合相同的尺寸(清单 3-7)。

清单 3-7。CSS 媒体查询以在高像素密度显示器上显示更高分辨率的徽标

@media only screen and (-webkit-min-device-pixel-ratio: 2),

only screen and (-o-min-device-pixel-ratio: 2/1),

only screen and (min--moz-device-pixel-ratio: 2),

only screen and (min-device-pixel-ratio: 2),

only screen and (min-resolution: 192dpi),

only screen and (min-resolution: 2dppx) {

h1{

background-image: url("high-res-image.png");

background-size: 100px 100px;

}

}

现在,如果您在高像素密度设备上进行测试,您将会看到徽标图像显示得更加清晰,如图 3-6 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-6。

Our high resolution logo shown on iOS

这只是一个简单的例子,说明如何使用媒体查询来改善网站在高像素密度设备上的显示。

摘要

有各种各样的设备可供使用,建立一个能够支持所有这些设备的网站是非常具有挑战性的。开发人员需要支持各种不同类型的设备,从电视到音频合成器,正如本章所讨论的,自 CSS2.1 规范以来,我们现在有能力使用媒体类型来支持这些设备。媒体类型限制了开发人员直接针对这些不同的类型,然而,现在各种各样的现代设备都使用屏幕媒体类型,这意味着尽管对开发人员来说它们也应该适合这些其他类别(如电视或手持设备)是合乎逻辑的,但事实并非如此。

这就是媒体提问的地方。与媒体类型相比,它们允许开发人员更好地控制目标样式。媒体查询允许开发人员针对设备的各种功能,包括屏幕宽度、屏幕高度和分辨率。这种细粒度的控制意味着我们可以更好地针对各种可用的设备。

媒体查询构成了响应式 web 设计的基础,因此开发人员很好地理解如何使用它们来优化网站以在各种设备上工作是非常重要的。展望未来,媒体查询将使我们能够支持越来越多的设备,随着新设备类别的不断出现,通过使用媒体查询,我们已经能够很好地支持它们。

在我们的下一章中,你将学习网页设计中通常使用的不同类型的布局,重点关注流体设计的工作原理,以及我们如何将流体设计作为一个响应式网站的一部分来实现。

Footnotes 1

http://www.phpied.com/5-years-later-print-css-still-sucks/

2

W3C 媒体类型规范, http://www.w3.org/TR/CSS2/media.html

3

steven champeon,Webmonkey .我是 steven champeon,webmonkey . http://www.hesketh.com/thought-leadership/our-publications/progressive-enhancement-and-future-web-design

4

卢克·乌鲁布莱夫斯基,http://www.lukew.com/ff/entry.asp?933=2009 年 11 月 3 日。

四、使用流体布局

已经研究了媒体查询的使用,本章将研究如何将这些与 CSS3 的其他方面结合起来,为您的用户构建更好的体验,这种体验既灵活又能够在更广泛的设备上工作。

本章将探讨:

The different types of layouts.   Principles when working with a fluid design.   Building a fluid design using a CSS grid.

布局类型

谈到页面的结构布局,有多种类型的布局可供选择。三种最流行的布局类型是固定宽度布局、流动布局和弹性布局,每种布局都有自己的优点和缺点。

当决定使用哪种类型的布局时,考虑用户的体验是很重要的。对于一个响应式站点,你的布局选择需要在大量设备上都能很好地工作。由于使用的用户数量庞大,因此选择一种能够为大多数用户提供最佳体验的布局类型非常重要。你还需要考虑到,从最小的智能手机到客厅里的 85 英寸电视,任何东西都有可能访问你的网站。

让我们来看看不同的布局风格,并考虑每种风格的优点和缺点,目的是学习如何从每种风格中选择最佳的部分,以便为网站用户建立良好的体验。

固定宽度布局

顾名思义,固定宽度布局主要是用具有固定宽度的包装器构建的。然后将其定位在屏幕上,通常位于浏览器视口的中心。无论用于访问网站的屏幕大小如何,固定宽度布局将保持其固定宽度。

从历史上看,当开发人员构建网站时,他们是从一个有固定宽度的设计开始构建的。通常,设计者会将站点设计成960px宽,因为这是使用网格布局的理想宽度,因为这个数字可以被 3、4、5、6、8、10、12 和 15 整除。当开发人员开始构建这些设计时,他们会在960px宽的地方构建站点,努力使构建尽可能像素完美。这里的想法是,他们可以让设计在浏览器中看起来像平面设计一样精彩。图 4-1 显示了一个典型的三列固定布局的例子,有两个侧栏和一个主要内容区。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-1。

An example of a 960px wide, three-column fixed layout

如果你看看一个典型的固定宽度布局是如何组成的,你通常会有一个固定宽度为960px的包装器,在这个包装器里面你会有你的网站内容,通常有以像素定义的宽度。在图 4-1 的例子中,有一个宽度为576px的主要内容区域,两侧有两个192px列。

固定宽度构建仍然非常受欢迎,当您考虑到创建内容(包括完全符合设计的图像)的能力时,就很容易理解为什么了。图 4-2 展示了三星固定宽度网站的当前示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-2。

The Samsung web site is a good example of a fixed layout

三星网站被构建为960px宽,使该网站能够针对各种流行的视窗。尽管没有响应,该网站仍然可以在移动设备上使用;它最初加载全屏,整个网站可见,然后,为了与网站交互,用户能够利用浏览器内置的捏、拉和双击用户交互来缩放和导航内容。虽然这是可用的,但它并没有提供我们在移动设备上期望的奇妙的用户体验。

如果你在 iPhone 上的 Mobile Safari 中查看三星网站,你会看到如图 4-3 所示的图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-3。

Samsung desktop site (left) vs. Samsung mobile site (right)

三星确实提供了特定的移动网站,如图 4-3 所示,然而,它并不与桌面网站共享相同的内容。这意味着用户最终仍然可以在他们的移动设备上使用桌面站点来访问通过其他方式无法访问的内容。

固定宽度设计的一个主要问题是,你在判断你的站点应该设计和建造到什么宽度。做出这种决定的局限性在于要支持的浏览器宽度范围很大。这样做的结果是,在小于所选固定宽度的浏览器窗口上,你会得到水平滚动,而在较大的浏览器窗口上,你的站点两侧有多余的空间可以得到更好的利用。

当苹果在 2007 年推出 iPhone 时,大多数网站都是固定宽度的,因此开发者试图通过默认缩小网站来弥补这一点(按照三星的说法),这意味着用户可以看到网站的整个宽度,尽管对他们的设备来说太大了。虽然这比仅仅看到网站的一角提供了更好的体验,但浏览一个大型网站仍然会令人沮丧。

使用固定宽度的设计不一定是一个坏的决定,重要的是要考虑你的网站的用途和目标受众。固定宽度的场地适用于希望在所有视口中保持相同布局和比例的场地。

弹性布局

弹性布局不以像素定义宽度,而是以 ems 度量。em 单位是字体大小的倍数,所以如果你设置你的字体大小为16px,那么2em的宽度将等于32px。这意味着,如果用户在查看网站时更改字体大小,网站的布局也将随着字体大小的增加或减少而成比例地改变。

弹性布局给了开发人员更多的控制,因为当用户在浏览器中调整文本大小时,设计比例保持不变。这意味着,如果用户需要增加你的网站上使用的字体大小,他们在你的网站上获得的体验与用户以原始字体大小查看网站没有什么不同。站点元素的大小与字体大小成比例。这意味着弹性布局在使开发者确保他们的站点对所有用户都是可访问的方面非常有效。

如果您采用原始的固定宽度网站设计,使用 16px 的基本字体大小,您可以通过将每个像素列宽除以字体大小(在本例中为 16)来轻松地将布局转换为使用 em 而不是像素。图 4-4 显示了图 4-1 中使用的相同布局,用于转换为弹性布局的固定布局示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-4。

An example of a 960px wide, three-column elastic layout with em conversion

该示例现在使用 ems 而不是像素来定义列宽。从像素到 ems 的计算非常容易执行:

像素宽度/基本字体大小= em 宽度

使用这个简单的公式,您可以很容易地计算出 ems 中元素的宽度。在图 4-4 中,您可以看到如何通过将像素宽度代入计算中来计算元素宽度:

576 / 16 = 36em

192 / 16 = 12em

重要的是要知道,ems 可以有一个小数值,所以如果您的计算没有得到一个整数,这不是一个问题。

使用弹性布局的一个例子是北爱尔兰社区档案馆关于阿尔斯特种植园的微型网站,如图 4-5 所示。 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-5。

The Plantation site is a good example of an elastic layout

这个网站使用 ems 来定义外部包装的宽度和布局的列。如果增加了基本字体大小,整个网站就会调整大小以适应更大的文本,如图 4-6 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-6。

The Plantation site after increasing the base font size

弹性布局最初的问题之一是,因为站点的宽度是基于基本字体大小的,如果用户将字体大小增加到某一点以上,站点在视口中会变得非常大,可能会导致浏览器出现水平滚动条。

弹性布局的另一个问题是,它们本质上仍然是一种固定宽度的布局,我的意思是弹性是基于基本字体大小的,所以除非用户改变字体大小,否则网站将保持开发者想要的基本宽度。这意味着,虽然弹性布局提供了比基于像素的固定布局更易访问的方法,但是布局仍然看起来在每个断点处都咬合到位,因为应用了每个媒体查询内的 CSS 因此,它们之间没有流动性,因为网站适应不同的大小。

弹性布局不太流行的原因之一是因为在 ems 中必须计算宽度所带来的困难。在查看基本字体大小之前,不清楚36em的宽度是多少像素。基本字体大小为16px,宽度为576px;然而,通过简单地改变基本字体大小为14px,宽度将减少到504px。不得不执行这个(虽然简单)计算给开发人员增加了一个额外的步骤。

你可能面临的另一个问题是ems是相对于父节点计算的;因此,如果父元素定义了不同于正文的字体大小,您可能会发现元素的宽度不是您所期望的。这是因为您可能已经根据正文的字体大小计算了宽度;要解决这个问题,只需根据父元素的字体大小重新计算即可。为了完全避免这个问题,一个选择是对字体大小使用 rem 而不是 em,这意味着所有的字体大小都相对于基本字体大小,而不管父元素的字体大小,警告是 rem 在诸如 Internet Explorer 8 和更早版本的传统浏览器中不工作。

流畅的布局

流体布局也称为液体布局或相对布局,其宽度根据用户的视口而变化。与固定布局不同,在固定布局中,宽度以像素为单位定义,相反,您可以将宽度定义为百分比,其中百分比引用其在视口中的部分,如图 4-7 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-7。

An example of a fluid web site, with browser currently open at 960px wide

如果你以固定宽度布局的图 4-1 中的例子为例,将尺寸转换成百分比,你将有两列宽度为 20 %,一列宽度为 60%。浏览器视口在960px时,等效像素值与固定示例中的像素值相同(括号中显示的像素),如图 4-8 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-8。

An example of a fluid web site, with the browser open at 1,600px wide

如果您随后要调整浏览器的大小,使视窗宽度为1,600px,网站会自然地放大到浏览器的全宽。较小的列现在的宽度为320px,较大的列的宽度为960px。这样做的好处是内容会自然地填充页面,潜在地放大任何图像并使文本流动以填充可用空间。

雅虎!最近重新设计了 Flickr 网站,使用了一种流体布局方法(如图 4-9 所示),利用额外的可用空间来增加图像的大小,并根据屏幕大小,增加每行的图像数量。这样做的好处是网站的用户可以更快地浏览更多的图片,并且更加关注网站。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-9。

The Flickr web site is a good example of a fluid web site

如果您要调整浏览器窗口的大小,Flickr 站点会随着浏览器一起缩放,从而更好地利用可用空间。图像要么增加尺寸,要么允许在一行中显示更多,利用用户的观看空间,并最大限度地增加他们在任何给定时间能够观看的内容。你可以在图 4-10 中看到 Flickr 网站的全景图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-10。

The Flickr web site when viewed on a wider screen

使用流体布局对 Flickr 的好处是显而易见的;图像可以填满所有可用的空间,允许用户适当地欣赏照片。用户体验的改善也可以通过网站参与度的增加来衡量。虽然雅虎!没有公布任何确切的数字,一个名叫托马斯·霍克斯 2 的 Flickr 用户自己做了一些研究。在重新设计启动后的六天内,有 8000 万张新照片上传到网站,而在重新设计前的六天,用户仅上传了 4700 万张照片。

流畅的布局不仅有利于像 Flickr 这样只有图片的网站,也有利于平铺内容的网站。Pinterest 就是一个例子,虽然它也非常注重图片,但也显示其他内容。对于 Pinterest,用户经常会浏览他们感兴趣的版块,寻找吸引他们注意力的东西,通过使用流畅的布局,Pinterest 能够显示用户当时能够查看的最大数量的内容,让他们更快地找到他们想要的东西。Pinterest 的流体宽度、平铺界面如图 4-11 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-11。

The tiled interface of Pinterest benefits from fluid design to show more content

使用流体布局的一个好处是,它可以更加用户友好,因为它可以根据用户的设备进行调整。流体布局可以利用可用空间,让内容填满所有可用空间,而不是有多余的空白空间,在较大的设备上,它允许内容间隔更大,有额外的呼吸空间。

尽管流动布局非常强大,但它们也有一些缺点,其中最重要的是它们会导致内容呈现方式的问题。由于流畅的布局可以在任何浏览器宽度下查看,您可能会发现图像的外观存在问题。虽然可以随着浏览器的大小调整来缩放图片,但重要的是要知道有些图片的缩放效果不好。包含焦点的图像会受到影响,因为缩小它们不仅会失去效果,还会使焦点太小。同样,低分辨率的图片在放大时,质量会显著下降。

除了内容呈现方面的问题之外,fluid width 网站可能还会面临一些交互功能方面的问题。网站通常使用 JavaScript 来增强用户体验,例如,显示等高的列。当用户调整浏览器大小时,问题就来了;文本重排,然后列变得太高或太短。因此,JavaScript 需要在调整大小时重新计算高度。

为什么要在响应式设计中使用流体布局

探讨了固定布局、流动布局和弹性布局之后,很重要的一点是要很好地理解每种方法的优缺点。然而,我还没有真正讨论这一切与响应式设计的关系。

在第三章中,我解释了如何使用媒体查询使你的网站适应不同的视窗。这样做的问题是,无论是固定布局还是弹性布局,它们都会在适应不同屏幕尺寸的两种或更多种不同布局之间切换。它们不是对各种不同的设备做出反应,而是适应于在几种不同的普通屏幕尺寸上工作。

但是设备不再符合几种不同的普通屏幕尺寸;相反,开发人员现在面对的浏览器具有任何尺寸的视窗,可以在从 85 英寸电视到 3.5 英寸手机屏幕的设备上观看。开发人员必须有这样的心态,无论如何都希望他们的网站看起来很棒,而不仅仅是在几个选择的屏幕尺寸上。如果用户要调整浏览器的大小,你会希望调整平滑流畅,布局在任何给定的分辨率下都能工作。

当考虑选择布局样式时,您应该确保您熟悉可用的替代选项,这就是为什么我在前面的部分中介绍了优点和缺点。在构建网站时,你应该对你选择的布局风格感到满意,并根据你的需要进行调整,而不是受它们的限制。也就是说,响应式设计确实需要一个流畅的布局,以便在最大范围的设备上提供最佳的用户体验,同时在不同的视窗大小之间保持最小的中断。这并不意味着你不能有断点,这导致布局捕捉改变它,以更好地利用可用的屏幕空间。事实上,这是受到鼓励的;你会希望能够以最好的方式利用你现有的空间。

处理流体设计时的原则

构建流体设计可以为响应式设计带来多种益处;然而,有一些重要的原则要记住,以确保您的网站保持可用,无论视窗的大小。

您应该努力遵循的主要原则是:

Do not use fixed heights.   Do not necessitate horizontal scroll bars.   Think about how your images look at different sizes.   Think about wrapping content.   Think about spacing.   Think about the length of your lines of text.

让我们更详细地探讨这些问题,看看解决您可能遇到的问题的潜在方法。

不要使用固定高度

如果您习惯于构建固定的布局,您很可能会遇到这样的问题:您已经为元素定义了固定的高度,但是当内容发生变化时,该高度或者有多余的间距,或者内容溢出到定义的高度之外。

随着流体设计带来的可变宽度,这个问题变得更加普遍,因为内容换行的方式会根据视口的大小而改变,所以在 CSS 中设置固定的高度变得不切实际。

不幸的是,有时在相同的栏中显示内容是设计的一部分,每个栏都有自己的背景颜色。如果不在 CSS 中定义高度,这可能很难实现;因此,要么在 CSS 中创建假列,要么使用 JavaScript 动态设置列的高度。

使用 CSS 创建假列

简单地使用一些 CSS 就可以创建列的效果。

对于两列布局,您知道一列总是比另一列高,只需将父元素的背景色设置为较短列的背景色。然后,通过设置 longer column 元素的背景色,您已经创建了具有两列的效果。让我们快速看一下处理这个问题的代码,从一些简单的 HTML 开始:

<div class="col-container">

<aside class="col">

Sidebar

</aside>

<div class="col main">

Main Content Area

</div>

</div>

如上所述,您将把列的背景应用到列容器和主内容列。为了实现列的效果,您还可以将列的宽度定义为 50 %,向左浮动,使它们彼此相邻:

.col-container{

background: #000;

color: #fff;

}

.col-container:after{

content: ' ';

clear: both;

display: block;

}

.col{

float: left;

width: 50%;

}

.col.main{

background: #999;

}

值得注意的是,您已经向列容器添加了一个伪元素来清除浮动的列。这是必要的,以便浏览器计算列容器本身的高度。如果您的站点已经为此使用了 clearfix 类,那么您可以选择将它添加到您的列容器中,而不是添加一个特定于该元素的伪元素。

如果你在你的浏览器中签出这个,布局有两列和预期的一样高,如图 4-12 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-12。

Two columns with equal height using CSS

虽然这很简单,但是这种两列的方法适用于所有的浏览器,并且非常有效,需要注意的是这种方法只适用于两列,并且需要知道哪一列更高。

如果有两列以上,可以选择在父级上使用 CSS3 渐变来达到相同的效果。但是,请记住,这种方法只能在 Internet Explorer 10 或更高版本中使用。扩展上面的示例,您可以在 HTML 中添加一个额外的列:

<div class="col-container">

<aside class="col">

Sidebar

</aside>

<div class="col main">

Main content area with our main body content

</div>

<div class="col">

Related content

</aside>

</div>

然后,您可以简单地修改现有的 CSS,因为您不再需要向主列添加背景。因此,您可以删除 CSS 的这一部分。然后将 CSS3 背景渐变添加到列容器中。在下面的示例中,您只包括 W3C CSS3 属性,对于实时代码来说,添加带前缀的版本以确保浏览器支持是很重要的:

.col-container{

background: linear-gradient(to right, #000000 0%,#000000 33%,#a0a0a0 33%,#a0a0a0 66%,#a0a0a0 66%,#707070 66%);

color: #fff;

}

.col-container:after{

content: ' ';

clear: both;

display: block;

}

.col{

float: left;

width: 33.3%;

}

当在浏览器中查看运行结果时,新列以正确的背景颜色出现,如图 4-13 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-13。

Three columns with equal height using CSS

如果您需要支持旧版本的 Internet Explorer,或者您想要支持动态数量的列,您可能应该考虑使用 JavaScript。

使用 JavaScript

已经了解了如何使用 CSS 创建仿列效果,让我们看看如何使用 JavaScript 创建等高的列。JavaScript 方法并不试图伪造列的外观,而是让所有的列都具有相同的高度。

使用 JavaScript 创建等高列的方法是遍历每个列,找到最高的列,然后将所有列设置为最高列的高度。

为了演示这一点,让我们看一个简单的例子,从一些 HTML 开始:

<div class="col-container">

<aside class="col nav">

Sidebar

</aside>

<div class="col main">

Main content area with our main body content

</div>

<div class="col related">

Related content

</aside>

</div>

然后,您需要设置列的样式,使它们具有不同的背景颜色:

.col-container{

color: #fff;

}

.col-container:after{

content: ' ';

clear: both;

display: block;

}

.col{

float: left;

width: 33.3%;

}

.col.nav{

background: #aaa;

}

.col.main{

background: #000;

}

.col.related{

background: #999;

}

有了这个地方,现在所有的列都很好,每个都有独特的背景颜色;然而,柱子的高度仍然不相等。你可以在图 4-14 中看到它的样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-14。

Three columns with unequal height before adding the JavaScript

为了使列相等,您需要添加一些 JavaScript。在下面的例子中,我使用了document.getElementsByClassName,它只受 Internet Explorer 9 或更高版本的支持。但是,您可以使用聚合填充来支持此方法,此要点code : https://gist.github.com/eikes/2299607 中提供了一个这样的聚合填充。

<script>

var columns = document.getElementsByClassName('col'),

height = 0;

//Loop through columns and find the tallest columns

for (var i = 0; i < columns.length; i++) {

if(height < columns[i].clientHeight){

height = columns[i].clientHeight;

}

}

//Apply the max height to all columns

for (var i = 0; i < columns.length; i++) {

columns[i].style.height = height + "px";

}

</script>

equal column JavaScript 简单地遍历所有列,找到最高的元素。然后,它再次遍历元素来定义高度。你可以看到 JavaScript 在图 4-15 中工作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-15。

Three columns with equal height after adding the JavaScript

对于固定的、非响应性的设计,在页面加载后简单地运行这个 JavaScript 就足够了。然而,对于一个流畅的、响应性的设计,用户可以调整浏览器的大小,因此 JavaScript 需要能够在调整大小时更新列的高度:

<script>

var equalColumns = function(){

var columns = document.getElementsByClassName('col'), height = 0;

//Reset the height of all the columns so that we can recalculate max height

for (var i = 0; i < columns.length; i++) {

columns[i].style.height = "auto";

}

//Loop through columns and find max height

for (var i = 0; i < columns.length; i++) {

if(height < columns[i].clientHeight){

height = columns[i].clientHeight;

}

}

//Apply the max height to all columns

for (var i = 0; i < columns.length; i++) {

columns[i].style.height = height + "px";

}

}

//Initially set the column heights

equalColumns();

//Update column heights on browser resize

window.addEventListener("resize", equalColumns, true);

</script>

有了这个修改后的 JavaScript,您已经将我们的equalColumns JavaScript 包装成一个函数,并对其进行了更新,以便它在重新计算高度之前重置所有列的高度。然后,当页面加载并将其作为事件侦听器附加到 resize 事件时,运行该方法。现在,如果用户调整浏览器的大小,列的高度也会随之调整。

不需要水平滚动条

当使用一个网站时,内容通常会沿着页面向下流动,因此能够双向滚动会损害用户的体验。

有一个创建水平布局的用例;然而,在这种情况下,你应该避免使用垂直滚动条,专注于提供水平体验。你可能想要建立一个水平布局的例子是一个艺术家或摄影师的在线作品集,比如 C. L. Holloway 的作品集网站,他通过允许用户水平滚动创建了一个类似画廊的体验。 3 需要注意的是,尽管这个网站的开发者选择了使用水平滚动条,但该网站选择了避免垂直滚动条,除非视口太浅而无法显示所有内容(大约在610px,这非常适合最流行的垂直屏幕分辨率)。

想想你的图片在不同尺寸下看起来是什么样的

当使用流体设计在网站上实现图像时,仔细观察图像在不同尺寸下的外观是很重要的。你需要考虑如何缩放你的图片,这取决于你是想把图片作为标签放在你的页面上,还是想把图片作为背景图片。

缩放内嵌图像

要缩放内嵌图像,只需对图像应用宽度。如果您的站点是响应式的,您实际上并不知道将哪个宽度大小应用于图像,因此您可以将max-width属性设置为 100 %,而不是定义绝对宽度,如以下代码所示:

img {

max-width:100%

}

有了这个,如果一个图像比它的容器大,它将缩小;但是,如果图像比容器小,它将保持原来的大小。

缩放背景图像

如果要缩放背景图像,可以使用 CSS3 background-size属性。这可以采用三个不同的值:覆盖、包含和宽度/高度值。

.image{

background-size:80px 60px;

}

background-size的问题在于,虽然你可以使用相对宽度来设置元素的宽度,但是对于元素的高度来说,这并不容易。

第一步是定义将包含背景图像的div:

<div class="image"></div>

接下来你需要定义 CSS。首先,您将定义图像容器。因为您希望宽度是相对的,所以您将使用一个百分比值,在本例中为width: 100%。图像的高度需要与图像的宽度成比例;使用 height 属性无法实现这一点,因为高度不能是相对的。相反,你可以使用填充。因为百分比填充是基于元素的宽度,所以您可以使用它来定义高度。不幸的是,这是有点复杂的地方,因为你需要设置填充底部,以便它保持图像的正确纵横比。

有了正确的宽度和高度,您现在只需添加图像作为背景图像,并设置background-size使其缩放到元素的全宽和全高:

.image{

width: 100%;

position: relative;

padding-bottom: 125%;

background: url(scalableimage.jpg) 0 0 no-repeat;

background-size: 100% 100%;

}

有了这个,你可以在浏览器中查看图像,看到它现在与页面的宽度成比例。图 4-16 显示了它在浏览器中的样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-16。

Scaling a background image with CSS

考虑包装内容

当构建一个流动的站点时,元素不断变小并不总是有意义的,因为最终内容会变得不稳定和不可读。相反,随着视口变大,将内容块堆叠在一起是没有意义的。这两种情况下的选项都是考虑内容如何在不同的视口换行。

这种情况的一个例子是,在网站的一侧有一个包含相关内容的侧边栏。如果侧边栏占页面宽度的 25 %,而视窗只有 320 像素宽,那么该列只有 80 像素宽。侧边栏可以移动到页面主要内容的下方,为主要内容释放额外的空间,并允许侧边栏也变成全宽,而不是保持栏的结构。

想想间距

使用流体设计时,使用元素宽度的百分比,好处是浏览器能够根据视口的宽度缩放宽度。除了用百分比计算元素的宽度,您还需要考虑如何处理每个元素之间的间距。

增加间距的一种方法是使用填充的百分比值。这里的问题是,在较大的视窗上,间距会太大,而在较小的视窗上,间距会太小。

理想情况下,您希望用百分比定义元素宽度,用像素或 ems 定义元素填充。不幸的是,默认情况下,浏览器呈现盒子模型的方式将填充放在宽度的外部,这意味着当定义填充的像素时,设计的流畅度会随着水平滚动条的出现而破坏,如图 4-17 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-17。

Using pixel values for paddings, the Fluidness of the design breaks and horizontal scrollbars appear

如果你从事 web 开发已经有一段时间了,你可能知道 quirks 模式。从本质上讲,在旧的浏览器中,这些标准没有得到正确的实现,而到了 Internet Explorer 6,人们决定要实现 HTML 和 CSS 标准,就需要为没有更新以支持这些标准的旧站点留一条退路。这种后退被称为 quirks 模式,它是通过在 HTML 文档的第一行不包含doctype来触发的。

特别是,在这些旧的浏览器中,与标准相比,盒子模型的实现是不正确的。W3C 标准要求,当定义元素的宽度或高度时,它不包括填充、边框和边距,这些应用于宽度或高度的外部。在这些较旧的浏览器中,实现包括内容、填充和边框,都在指定的宽度或高度内。

quirks 模式的实现对于允许你增加你的流体设计站点的间距是理想的,但是,你不想强迫你的站点进入 quirks 模式,因为你希望你的站点是标准兼容的。随着 CSS3 的到来,对盒子模型如何工作的控制权交给了开发人员,我们现在能够使用新的盒子大小 CSS 属性来确定盒子如何呈现。

box-sizing 属性提供了三个值供我们选择,每个值将呈现一个具有不同版本的盒子模型的盒子。可用于调整框大小的值有内容框、填充框和边框框。

内容盒

默认样式由 CSS 标准指定。宽度和高度属性被测量为仅包括内容区域。边框、边距和填充被添加到外部。示例如图 4-18 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-18。

The box model as applied by setting the CSS property box-sizing to content-box

填充盒

对于 padding-box,width 和 height 属性包括填充大小,但不包括边框或边距。示例如图 4-19 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-19。

The box mode asl applied by setting the CSS property box-sizing to padding-box

边框

width 和 height 属性都包括填充和边框,但不包括边距。如果您已经开发了一段时间,您可能会熟悉 border-box 的工作方式,因为它是 Internet Explorer 在文档处于 quirks 模式时使用的。示例如图 4-20 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-20。

The box model as applied by setting the CSS property box-sizing to border-box

边框是响应式开发的圣杯,因为它允许我们向元素添加一致的填充,同时仍然使用基于百分比的宽度。

对于一个响应式站点来说,对所有元素使用边框是完全有意义的。它不仅保持了一致性,还意味着您可以对从div到输入字段的所有内容使用百分比宽度。将边框应用于所有元素的方法是使用通用选择器(*):

* {

-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */

-moz-box-sizing: border-box;    /* Firefox, other Gecko */

box-sizing: border-box;         /* Opera/IE 8+ */

}

想想你的文本行的长度

当构建一个流畅的站点时,不管浏览器大小如何,简单地允许一个站点是全幅的是非常容易的。然而,这通常会导致很长的文本行。

Chris Coyier 在 2013 年 11 月就这个问题写了一篇关于 CSS 窍门的文章:

The traditional idea is that the text (long text, multiple paragraphs, need to look at it again when reading …) should be between 45 and 75 characters per line. It’s awkward when it’s short, and it’s easy to find the position and the next line when it’s long.

这完全有道理;一眼看去,不算过长的台词读起来更舒服;报纸使用专栏也是出于同样的原因。在流畅的布局中,很容易让文本行变得过长。为了避免这种情况,您可以使用一个名为max-width的 CSS 属性,它是作为 CSS2.1 规范的一部分引入的。

CSS max-width属性允许你定义一个元素可以跨越的最大宽度,使你能够通过直接定义包含元素或者段落标签的最大宽度来控制文本行的长度。在定义这个最大宽度时,实际上可以通过在 ems 中定义您的max-width来考虑每行的最大字符数。这意味着元素的最大宽度将保持相对于定义的字体大小,因此如果用户增加默认字体大小,元素将适当缩放。需要注意的是,使用像素宽度来包含 em 定义的宽度是很棘手的,所以与您定义宽度的方式保持一致是很重要的。

同样,您也希望确保您的文本行不会显得太短。为此,您可以使用 CSS 属性min-width,它也是作为 CSS2.1 规范的一部分引入的。min-width属性允许你指定一个元素可以拥有的最小宽度,如果元素的宽度低于min-width值,它会覆盖widthmax-width属性的值。对于单行文本来说,副本太短的情况,min-width属性没有帮助;但是,它确实有助于防止出现这样的情况:由于元素不够宽,多行文本每行只有几个单词。需要注意的是,如果容器的宽度小于元素的宽度,那么元素将溢出容器。此外,如果容器的 CSS 属性 overflow 设置为 hidden,元素的内容将被裁剪,这当然是不希望的。

浏览器对max-widthmin-width的支持在 Internet Explorer 7 和更高版本、Firefox、Chrome 和 Safari 中都很好,包括移动版本,它们都支持该属性。

使用 CSS 网格构建流畅的设计

至此,您已经很好地理解了构建流体设计时应遵循的原则。让我们来看看如何将这些付诸实践,以构建一个流畅的设计。在第三章中已经构建了一个响应式站点,当你学习了媒体查询时,让我们看看如何使用流体设计原理构建一个响应式 CSS 布局网格。

布局网格起源于出版业,在出版业中,公司会使用预定义的网格来布局杂志和书籍等印刷材质。这样做的目的是让他们在整个印刷作品中实现视觉对称。这些不可见网格的目的是为读者提供一个更简单、一致的阅读体验。早在响应式设计成为趋势之前,印刷品中的网格所带来的好处就促使它们以 CSS 网格的形式向网络过渡。

CSS 网格通常使用列来构建;这些是网格的最小度量单位,块可以跨越一列或多列。通常,一个网格有 12 到 16 列,每列之间会有间距。间距是每列之间的间距,通常定义为填充或边距。

为了让我更容易说明网格是如何工作的,我把一个固定布局网格的例子放在一起,如图 4-21 所示。在本例中,我们有一个四列网格,每列宽 215 像素,每列的两边都应用了 20 像素的装订线。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-21。

An example of a fixed width grid

固定宽度的布局允许我们描绘网格是如何分布的,但是我们希望网格是流动的。为了实现这一点,我们将把我们的每一列定义为 25%的宽度,然后为我们的站点启用槽,我们将使用 box-sizing 属性来移动我们的列内部的填充。总宽为 960 像素,每列宽为 240 像素;但是,如果您要将其缩小到 320 像素,则浏览器中的列会随着每列而缩放,而不是每列 80 像素宽。该流体网格如图 4-22 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-22。

Grid adapted to fluid layout

构建网格

虽然您可以简单地使用 CSS 网格框架,但首先重要的是要很好地理解网格框架是如何工作的,这样您就可以充分利用它们。让我们先看看如何编写一个简单的移动响应 CSS 网格。

最简单的形式是,CSS 网格由以下内容组成:

Columns   Gutters   Rows   Wrappers

让我们更详细地看看网格的这些元素:

在开发 CSS 网格时,您需要决定网格系统将使用的列数,正如前面提到的,网格系统通常有 12 或 16 列。

CSS 网格中的列通常宽度相等,位置相邻。通常,这是通过将列向左浮动来实现的:

.col{

float: left;

width: 25%;

}

对于您将要编写的示例 CSS 网格,您将使用四列。您可能还记得我之前提到过,您可能希望您的内容跨越多列,因此为了支持这一点,您需要做一些调整。通过简单地定义每个支持的宽度,很容易使网格支持跨越多个列。之前我将一个列命名为.col,但是,为了使您能够使用一个选择器将共享样式应用到我们的附加列,您将把它重命名为".col-span-x",其中 x 是该列应该跨越的列数…列名应该反映它们将跨越多少列:

[class*="col-span"]{

float: left;

}

.col-span-1{

width: 25%;

}

.col-span-2{

width: 50%;

}

.col-span-3{

width: 75%;

}

.col-span-4{

width: 100%;

}

你可能已经注意到,在这里我使用了一种我在本书中没有涉及的 CSS 语法,一种你以前可能没有使用过的语法,叫做属性通配符选择器。使用的属性通配符选择器[class*="col-span"]允许您定位所有列,而不必添加额外的类。在这个例子中,我用它来代替书写:

.col-span-1, .col-span-2, .col-span-3, .col-span-4{

float: left;

}

到目前为止,您已经创建了四列,但是,在这里您将希望能够根据视窗的大小来调整您的站点。当我讨论构建响应式流体设计的原则时,我提到过将某些内容调整得过小会带来糟糕的用户体验。因此,您应该能够控制内容在较小设备和较大设备上分别占据多少列。您可以通过改进具有媒体查询的类来做到这一点:

[class*="col-span"]{

float: left;

}

.sm-col-span-1{

width: 25%;

}

.sm-col-span-2{

width: 50%;

}

.sm-col-span-3{

width: 75%;

}

.sm-col-span-4{

width: 100%;

}

@media screen and (min-width: 768px){

.lg-col-span-1{

width: 25%;

}

.lg-col-span-2{

width: 50%;

}

.lg-col-span-3{

width: 75%;

}

.lg-col-span-4{

width: 100%;

}

}

由于您首先构建的是可移动的 CSS 网格,因此您首先定义了默认的列宽,然后为更大的设备定义了类,如果设备的最小宽度为 768px,这些类将被激活。您已经将原来的类改为前缀为sm-lg-sm-前缀类针对小型及以上设备,lg-前缀类针对较大设备。其思想是将带有sm-前缀的列类应用于 HTML 元素,为较小的设备定义布局,然后使用带有lg-前缀的列在适当的地方覆盖列跨度。

沟壑

CSS 网格的间距是每列之间的间距;从历史上看,这是通过保证金实现的。但是,在处理流体设计时,您希望间距成为列的一部分,因此可以选择对列宽使用百分比。因此,您应该对列之间的间距使用填充。

使用空白填充的缺点是,它会阻止您为列添加背景色。这样做的原因是,如果你给列添加一种背景色,背景也会出现在槽中。解决这个问题的唯一方法是向列内的元素添加任何背景色,而不是向列本身添加背景色。

之前我解释了 CSS3 box-sizing属性,它允许你改变盒子模型的工作方式,允许你控制填充是在宽度的内部还是外部。对于此网格,您将希望列包括填充,这将用于装订线。为了实现这一点,这些列将把box-sizing设置为border-box。如果您已经像我之前建议的那样将它应用到通用选择器,您不需要在这里再次添加box-sizing:

[class*="col-span"] {

box-sizing: border-box;

padding-left: 15px;

padding-right: 15px;

}

如您所见,您还向列添加了填充。您已经使用完整的padding-leftpadding-right属性名称添加了填充,因为这可以防止您覆盖添加到元素顶部或底部的任何填充,而这些填充可能已经在 CSS 的其他地方指定了。

行用于包含列。因为列是向左浮动的,所以它们被从页面流中取出;因此,浮动元素前后的非定位块元素就像不存在一样。因此,为了防止这个问题,行还负责清除列使用的浮点数。

通常的方法是添加一个伪元素作为清除浮动的行的一部分:

.row:after{

content: ' ';

clear: both;

display: block;

}

如上所述,伪元素是一个应用了clear: both的空块级元素。

包装材质

最后,您将在所有行周围添加一个包装器。它用于向站点的左侧和右侧添加额外的填充:

.wrapper{

padding-left: 15px;

padding-right: 15px;

}

将网格放在一起

前面的例子着重于如何构建一个响应式博客,这样就有可能看到这些例子之间的差异,因此这个新代码将为一个博客构建一个响应式网格。

我已经解释了组成这个网格的 CSS,所以让我们把它们放在一起(清单 4-1)。

清单 4-1。用于网格的示例 HTML

<!DOCTYPE html>

<html>

<head>

<title>Responsive Grid</title>

<meta name="viewport" content="width=device-width">

<link rel="stylesheet" type="text/css" href="responsive-grid.css">

</head>

<body>

<header>

<div class="wrapper">

<div class="row">

<div class="sm-col-span-2 lg-col-span-4">

<h1>Blog</h1>

</div>

<nav class="sm-col-span-2 lg-col-span-4">

<ul>

<li><a href="#">Latest posts</a></li>

<li><a href="#">Popular posts</a></li>

</ul>

</nav>

</div>

</div>

</header>

<div class="content" role="main">

<div class="wrapper">

<div class="row">

<article class="sm-col-span-4 lg-col-span-3">

<h2>Article title</h2>

<p>02/12/2013</p>

<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Vestibulum id ligula porta felis euismod semper.</p>

</article>

<aside class="sm-col-span-4 lg-col-span-1">

<h2>Related Articles</h2>

<nav>

<ul>

<li><a href="#">Article item 1</a></li>

<li><a href="#">Article item 2</a></li>

<li><a href="#">Article item 3</a></li>

</ul>

</nav>

</aside>

</div>

</div>

</div>

</body>

</html>

现在让我们把 CSS 放在一起;所以 CSS 很容易理解,让我们把 CSS 网格从站点特定的样式中分离出来,使它看起来像一个博客。完整的 CSS 代码如清单 4-2 所示。

清单 4-2。网格的完整 CSS

/*Grid styles*/

.wrapper{

padding-left: 15px;

padding-right: 15px;

}

.row:after{

content: ' ';

clear: both;

display: block;

}

[class*="col-span"] {

float: left;

box-sizing: border-box;

padding-left: 15px;

padding-right: 15px;

}

.sm-col-span-1{

width: 25%;

}

.sm-col-span-2{

width: 50%;

}

.sm-col-span-3{

width: 75%;

}

.sm-col-span-4{

width: 100%;

}

@media screen and (min-width: 768px){

.lg-col-span-1{

width: 25%;

}

.lg-col-span-2{

width: 50%;

}

.lg-col-span-3{

width: 75%;

}

.lg-col-span-4{

width: 100%;

}

}

/*Site specific*/

body{

margin: 0;

padding: 0;

font-size: 14px;

line-height: 18px;

}

header{

background: #304480;

padding-top: 10px;

padding-bottom: 10px;

color: #fff;

}

ul{

padding: 0px;

margin: 0px;

}

ul li{

list-style: none;

}

header nav{

text-align: right;

}

header nav a{

color: #fff;

}

@media screen and (min-width: 768px){

header nav{

text-align: center;

padding-top: 10px;

border-top: 1px dashed #ccc;

margin-top: 10px;

}

header nav li{

display: inline-block;

}

}

我们现在可以看看这在一个额外的小设备上看起来如何(如图 4-23 所示)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-23。

Our site shown on an extra small device (in this example an iOS device)

已经看到我们的网站在一个额外的小设备上的样子,我们还应该看看它在更大的设备上的样子,我们可以通过启动桌面浏览器并加载我们的网站来做到这一点。图 4-24 显示了我们期望看到的情况。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-24。

Our site shown on a larger device (in this example a desktop browser)

但是,如果您将视窗宽度进一步增加到 1,440px,您将开始注意到文章中的文本行开始变得相当长。如前所述,每行的最佳字符数在 45 到 75 之间,查看图 4-25 中的截图,您会注意到文本远远超出了这个范围。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-25。

Text beyond the optimum number of characters per line

防止这一点并不太难;您只需调整包装器,使其具有最大宽度,之后它将简单地使站点居中:

.wrapper{

padding-left: 15px;

padding-right: 15px;

max-width: 1200px;

margin: 0 auto;

}

现在,如果你在大视窗上检查站点,当视窗超过 1200 像素时,它会居中,如图 4-26 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-26。

Text now centering with larger viewport

改善电网

现在已经完成了第一个响应式网格,您已经了解了构建 CSS 网格的基本原则。如果你想更进一步,有很多方法可以改进网格,让你建立更好、更有用的站点。

第一种方法是增加列数。典型的网格使用 12 到 16 列,然而,为了简单起见,我只选择了 4 列。增加列数相对来说比较简单,只需使用以下公式计算每一列:

列宽= (100 /总列数)*列跨度

您可以选择使用 Nicolaj Kirkgaard Nielsen 的网格计算器,而不是手动计算。 4

改进网格的第二种方法是更好地控制不同视口大小的列数。您已经添加了媒体查询,以允许独立确定小型和大型设备的列数;但是,您可以通过添加针对中型设备的功能来添加更细粒度的控制。

摘要

流畅的布局是任何响应式网站的显著特征,因为它们允许网站利用任何可用的空间。正如本章所强调的,流体布局的这一特性对于响应式设计尤为重要,因为我们正在开发各种形状和大小的设备。

然而,流动的布局确实给我们作为开发者带来了一些额外的挑战,所以我们研究了一些可以遵循的原则,以确保我们能够优化我们的响应网站的可用性。此外,这些原则应该指导你能够快速有效地建立你的网站。

了解了流体设计之后,我解释了如何应用这些技术;特别是,我专注于构建一个流体响应 CSS 网格。这解释了如何将您已经学到的关于媒体查询的知识应用到流畅的布局中。

看了流畅的布局,学习了如何自己构建一个基本的网格,在下一章,你将学习更多关于现有的 CSS 网格和框架,我们可以用它们来构建我们的响应站点。

Footnotes 1

http://niarchive.org/trails/plantation-rewriting-the-story/

2

http://thomashawk.com/2013/05/flickr-users-uploading-71-more-photos-to-flickr-since-new-design-rolled-out.html

3

http://www.clholloway.co.za

4

http://gridcalculator.dk/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值