4 响应式设计中的HTML5
HTML5是从Web Applications 1.0项目发展而来的,由网页超文本技术工作小组(WHATWG)发起,后被W3C采纳。HTML5规范的大部分内容都偏重于处理Web应用程序。就算你不创建Web应用程序,也并不意味着HTML5对你制作响应式设计就没有太大价值。所以,HTML5的一部分特性与制作更好的响应式网页直接相关(如简洁的代码),而另一些则和响应式设计没太大关系。
HTML5还提供了针对表单处理和用户输入的特定工具。这些特性大大节省了为表单验证这类工作而在复杂技术如JavaScript上耗费的精力。不过我们将在第8章再单独研究HTML5表单。
本章内容
HTML5的那些部分我们现在就能用?
如何编写HTML5网页
HTML5的精简之道
HTML中的废弃零件
HTML5中的全新语义化元素
使用无障碍网页应用技术(WAI-ARIA)来增强语义,支持辅助技术
嵌入媒体
可响应的HTML5和iFrame视频
让网站支持离线使用
4.1 HTML5的哪些部分现在就能用
虽然完整的HTML5规范尚待批准,但是现代浏览器都不同程度地支持HTML5的大多数新特性,这些浏览器包括Safari、Google Chrome、Opera、Mozilla Firefox,而且还有IE9!当前HTML标准草案的内容最终未必全都会出现在W3C推荐标准中,但其中有很大一部分新特性现在已经可以用了。
4.1.1 大多数网站可以用HTML5编写
现在,当我接到制作网站的任务,选择的默认标签会是HTML5而不是HTML 4.01。和几年前的情况完全相反,现在,你得给网站不使用HTML5标签一个说得过去的理由。所有现代浏览器都能够正确理解常见的HTML5新特性(新的结构元素、视频和音频标签),而对老版本的IE则可以使用腻子脚本来弥补我所遇到过的所有缺陷。
什么是腻子脚本?
腻子脚本(polyfill)这个词由Remy Sharp提出,意指使用腻子来补平老版本浏览器的缺陷。因此,腻子脚本具体指的是一段能给老版本浏览器带来新特性的JavaScript代码。值得注意的是,腻子脚本会给你的代码里追加多余的代码。因此,就算你添加3个腻子脚本可以让Internet Explorer 6中网站的渲染效果与其他浏览器一模一样,也并不意味着你一定要这么做! 4.1.2 腻子脚本和Modernizr 通常,老版本的Internet Explorer(IE9以前的版本)并不识别HTML5的任何新语义元素。但是不久前,Sjoerd Visscher发现如果先使用JavaScript创建这些元素,那Internet Explorer就能识别这些元素并可为其设置样式。基于这一发现,JavaScript专家Remy Sharp开发了一个轻量级的增强脚本(http://remysharp.com/2009/01/07/html5-enabling-script/),在HTML5网页中引入该文件后,就能神奇地让老版本IE支持新HTML元素。长期以来,HTML5的先驱们都会在页面中嵌入该脚本,以便让使用IE 6、7的用户享受和现代浏览器一样的体验。
不过此事现在有了更重大的进展。这个领域上出现了一个新丁,它能做到比刚才说的更多的事情。它的名字叫Modernizr(http://www.modernizr.com),如果你正在编写HTML5页面,它很值得你去关注。除了能让IE支持HTML5新元素之外,它还能够基于一系列特性测试来有条件地加载更高级的腻子脚本(polyfill)、CSS文件以及额外的JavaScript文件。几乎没有什么理由不使用HTML5,所以我们将开始写一点HTML5风格的页面。
想找一种编写优秀HTML5代码的捷径?可以考虑HTML5样板文件
如果你时间紧迫,但却需要一个好的项目起点,可以考虑使用HTML5样板文件(http://html5boilerplate.com/)。样板文件是一个预先做好的融合了“最佳实践”HTML5文件,包含一些基本样式(如之前提到过的normalize.css)、polyfill和一些必要的工具如Modernizr。它还包含一个自动合并CSS和JS文件、自动删除注释以生成生产环境代码的构建工具。强烈推荐! 4.2 如何编写HTML5网页 打开一个已有的网页。你可能会看到文件开头有这样几行代码:
删除上面的代码片段并将其替换成如下代码片段:
保存刚才的文档,现在你就有了自己的第一个W3C验证器(http://validator.w3.org/)认可的HTML5网页。
不要担心,本章尚未结束!刚才这个简单的练习只是为了展示HTML5的适应性。这只是已有代码的一次演进,而不是彻底革命。我们可以用它来增强我们已经掌握的标签代码。
到底该怎么做呢?首先,从新的HTML5文档类型声明开始:
如果你喜欢用小写字母,<!doctype html>也没问题。大小写没有区别。
HTML5 文档类型为什么这么简短?
HTML5的<!DOCTYPE html>文档类型如此简短,目的是以简洁的方式告诉浏览器用“标准模式”渲染页面。这种简洁高效的思想渗透在HTML5的方方面面。
在文档类型声明之后,开写HTML标签,设置language属性,然后开写部分:
你会说汉语吗?
最后,设置一下字符编码。meta是一个单闭合元素所以不需要关闭标签:
字符编码通常都是UTF-8,除非你有特殊理由才可能使用其他编码。 4.2.1 HTML5的精简之道 我记得在学校的时候,对我们超级严厉(其实是对我们负责)的数学老师最后都会因教不下去而走人。整个班级里充斥着被解放的愉悦,没有人因此对“严厉先生”(用这个名字来保护那些无辜的老师)感到惋惜。新来的老师一般都很和蔼可亲,他静静地坐在讲台上,任由我们胡闹也不会训斥或者给我们找麻烦。他没有强制要求我们在学习时要保持安静,也不关心我们的作业题解得如何精巧——他只关心答案。如果HTML5是一位数学老师,那它一定是那个好好先生。接下来我将证明这个奇怪的比喻……
如果你很注意代码风格,一般都会使用小写字母,将属性值用引号括起来,而且会为脚本或样式文件链接声明type属性。例如,你会使用如下的代码来引入一个样式表:
HTML5中不需要这么仔细,这样写它一样乐于接受:
你看了一定感到怪异,我懂我也明白。代码没有闭合标签的斜线(/),属性值没有用引号括起来,没有type声明。但是,好说话的HTML5不在意这些。第二行示例代码和第一行一样有效。
这种宽松的语法可应用于整个文档,而不仅仅是链接CSS和JavaScript文件的元素。例如定义一个如下所示的div:
这是完全有效合法的HTML5代码。插入一个图片:
这样同样有效。没有结束标签的斜线,没有引号,大小写混杂。甚至,省略<head>元素,页面依然有效。XHTML 1.0对这种情况会怎么说呢? 4.2.2 HTML5标签的合理写法 虽然我们的目标是采纳移动优先的响应式设计和开发思想,但我承认无法完全按照我所认为的最佳方式来编写页面(注意,我所举的例子都遵循基于XML语法的XHTML 1.0规范)。使用这种精简的编码方式确实可以节省极其微量的数据,但老实说,如果有这个需要,我宁愿通过从网页中删去一张图片来达到同样的目的。
对我而言,那些看似多余的字符(用于闭合的斜线和属性值两边的引号)可以提高代码的可读性。因此在编写HTML5文档时我倾向于在老式编写风格(这样风格的代码在HTML5中依然有效,不过可能在验证器或类似检查工具中会产生一些警告)和HTML5的极简主义之间找到一个平衡。举例说明,以上节的CSS链接为例,我会这样写:
我闭合了标签,使用了引号,但删除了type属性。关键是找到一种你自己满意的风格。HTML5不会训斥你,也不会在课堂上批评你糟糕的标签代码,更不会因为你的代码没通过验证而罚你站墙角。 4.2.3 伟大的<a>标签万岁 HTML5中一个真正便利的精简之处,是我们可以在标签中嵌入多个元素。(哇哈哈!终于来了。)以前,如果你想让代码通过验证,必须将每个元素单独使用标签来包裹。例如以下代码片段:
现在,我们可以摆脱这个限制,像下面代码那样将一组元素包裹其中:
唯一需要记住的是——很明显:不能在一个标签中嵌套另一个标签,也不能在标签中嵌套表单。 4.2.4 HTML的废弃零件 除了script链接中的language属性,还有很多你可能已经习以为常的HTML标签或属性,在HTML5中都被认为是“废弃的”。HTML5中的废弃零件分为两类——暂保留和非保留的。暂保留零件仍可正常运行但验证工具会报警告。在实际开发中尽量避免使用,但用了也不会让天塌下来。非保留的零件在某些浏览器中仍可以渲染,但如果你使用了它们,别人会认为你是顽冥不化的,周末恐怕谁都不愿意跟你玩。
举个使用暂保留的废弃零件的例子,即给图片设置border属性。这种方法以前用来去掉超链接中图片的蓝色边框。示例代码如下:
现在则建议你使用CSS来完成同样的效果。
至于非保留的废弃零件都有哪些,多了去了。坦白地说,很多我从来都没用过(有些甚至见都没见过!)。你的情况可能和我差不多。如果你好奇,可以在后面这个网址找到完整的非保留废弃零件列表:http://dev.w3.org/html5/spec/Overview.html#non-conforming-features。比较常见的非保留废弃零件有strike、enter、font、acronym、frame和 frameset。 4.3 HTML5的全新语义化元素 字典中对语义学的定义是“关注语言本质含义的语言学和逻辑学分支学科”。对我们来说,语义化是给我们的标签赋予意义的过程。为什么语义化很重要?很高兴你问这个问题。看看And the winner isn’t…网站目前的标签结构:
大多数网页开发者能看懂这些div上使用的通用的ID命名约定——header、content、sidebar等等。但是对于代码本身,任何用户代理(网页浏览器、屏幕阅读器、搜索引擎爬虫等)看到这段代码都无法确定每个div的意义。HTML5旨在使用全新的语义化元素来解决这个问题。接下来将从页面结构的角度来讲解这些元素。 4.3.1 <section> <section>元素用来定义文档或应用程序中的区域(或节)。例如,可以用它组织你的个人信息,一个<section>用于联系信息,另一个用于新闻动态。需要重点理解的是用它的目的不是为了美化样式。如果你只想将某个元素包裹起来以便设置样式,那应该和以前一样继续使用<div>。
想知道W3C的HTML5标准对<section>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-section-element。 4.3.2 <nav> <nav>元素用来定义文档的主导航区域,其中的链接指向其他页面或当前页面的某些区域。因为<nav>用于主导航区域,所以严格来讲它不是为页脚或其他经常会包含一组链接的区块而设计的(虽然将它用在这些区块里包含链接也没问题)。
想知道W3C的HTML5标准对<nav>的说明,请访问如下网址:http://dev.w3. org/html5/spec/Overview.html#the-nav-element。 4.3.3 <article> <article>元素与<section>元素很容易混淆。在完全理解之前我只得一遍又一遍地阅读它们的标准定义。<article>元素用来包裹独立的内容片段。当搭建一个页面时,想想你准备放入<article>标签的内容能否作为一个整块而被复制粘贴到另外一个完全不同的网站且能保持完整的意义?另一种办法是,想想包裹在<article>中的内容能否在RSS订阅源中独立成为一篇文章?应该使用<article>标签包裹的内容,最明显的例子就是博客正文。注意,如果出现嵌套的<article>元素,那内层的<article>元素内容应该和外层文章内容直接有关。
想知道W3C的HTML5标准对<article>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-article-element。 4.3.4 <aside> <aside>元素用来表示与页面主内容松散相关的内容。在实践中,我经常将其用作侧边栏(当它包含合适的内容时)。另外,引文、广告以及导航元素(如友情链接等)也可以使用它。
想知道W3C的HTML5标准对<aside>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-aside-element。 4.3.5 <hgroup> 如果页面中有一组使用<h1>、<h2>、<h3>等标签的标题、标语和副标题,则可以考虑使用<hgroup>将它们包裹起来。这样在HTML5的大纲结构算法中就会隐藏次级标题元素,从而只让<hgroup>中的第一个标题元素进入文档大纲。
HTML5的大纲结构算法
HTML5允许每个<section>容器有自己独立的大纲结构。这样你就不必总想着现在是几级标题了。例如在一个博客中,博文的标题可以使用<h1>标签,同时博客内容的标题也可以包含<h1>标签。请见如下代码:
尽管代码中有多个<h1>和<h2>元素,但大纲结构还是这样:
·Ben’s blog
ºA post about something
因此,你就不必吃力地去记住标题级别了,而是可以在每个容器中随意使用任何级别的标题元素,HTML5的大纲结构算法令自动组织好大纲。可以使用下面的HTML5大纲生成器来测试生成网页的大纲结构:
http://gsneders.html5.org/outliner/
http://hoyois.github.com/html5outlier/
下图展示了HTML5大纲生成器的界面:
想知道W3C的HTML5标准对<hgroup>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-hgroup-element。 4.3.6 <header> 由于<header>元素不计入大纲结构,所以不能用它来划分内容结构,而是应该用它来包含对区域内容的介绍说明。实际使用中,<header>可用作网站头部的“刊头”区域,也可用作对其他内容如<article>元素的简要介绍。
想知道W3C的HTML5标准对<header>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-header-element。 4.3.7 <footer> 和<header>一样,<footer>元素也不计入大纲结构,所以也不能用于划分内容结构。应该用它来包含其所在区域的辅助信息。例如可以用它包含一组指向其他页面的超链接,或者用它包含版权信息。和<header>一样,它也可以视情况在同一个页面上多次出现。例如博客网站的页脚可以用它,同时博客正文<article>元素内的文脚也可以用它。不过规范指出,博文作者的联系信息应该使用<address>元素来包裹。
想知道W3C的HTML5标准对<footer>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-footer-element。 4.3.8 <address> <address>元素用于明确地标注离其最近的<article>或<body>祖先元素的联系信息。为避免产生混淆,请记住<address>中一般不放具体的邮政地址,除非相应内容确实需要联系地址。而邮政地址和其他可能会改变的联系信息应该使用<p>标签来包裹。
想知道W3C的HTML5标准对<address>的说明,请访问如下网址:http://dev.w3.org/html5/spec/Overview.html#the-address-element。 4.4 HTML5结构元素的实际用法 我们来看几个使用刚才所讲的这些新元素的实际例子。我想<header>、<nav>和<footer>元素的用途是显而易见的,所以先从它们开始。从And the winner isn’t…网站的首页开始,修改其头部、导航和页脚(注意看下面代码片段中加粗的部分):
不过,当页面中有<article>或<section>元素时,则刚才所说的这三个元素在每个页面中的使用次数不受限制。每个<article>或<section>元素都可以有自己的头部、脚注和导航。例如,我们在刚才的页面中添加一个<article>元素,代码如下:
如上代码所示,我们在页面及其所包含的<article>中都使用了<header>、<nav>和<footer>元素。
接下来继续修改侧边栏区域,其当前的HTML 4.01标签结构如下:
侧边栏内容当然是和页面主要内容“略微”相关的,所以首先移除<div id="sidebar">并将其替换为<aside>:
代码看上去很优雅!但是如果在浏览器中看到效果之后你张口骂娘也是情有可原的……
这真是进一步退两步!造成这种糟糕效果的原因是我们没有针对新元素修改CSS代码。在我们继续前进之前得先把这件事搞定。我们得将所有#header引用改为header,所有#navigation引用改为nav,所有#footer引用改为footer。例如,第一个引用#header的CSS规则如下:
要将其改为:
这些修改非常简单,因为header、navigation和 footer作为ID与其对应要修改的元素名称一致——我们只需要去掉“#”即可。sidebar则有些许不同:我们得将带#sidebar的引用改为aside。不过,在编辑器中执行“查找与替换”可帮助我们快速完成任务。简要说一下,类似这样的CSS规则:
要变成这样:
即使你写了一个超长的CSS样式文件,将其中的HTML 4.01 ID名称替换成HTML5元素也不是什么难事。
注意HTML5中的元素复用
请注意,HTML5页面中可能会有多个<header>、<footer>和<aside>元素,你可能需要为每一个都编写特定的样式。
And the winner isn’t…的样式修改完成后,我们就又回到了正轨:
现在,我们虽然告知了用户代理(如浏览器)页面那部分是侧边栏,但其中又含有两个独立的区域,UNSUNG HEROES和OVERHYPED NONSENSE。为了让这两个区域具有语义,还要对代码做进一步修改:
需要谨记的是,使用<section>的目的不是为了美化样式,而是为了标识一个鲜明独立的内容块。一个内容块(section)一般都应该带有标题,这恰好符合我们的需求(用于独立标识)。考虑到HTML5的大纲结构,我们可以将上面代码中的<h4>标签改为<h1>,这样HTML5就会为文档生成一个精确的大纲:
网站的主体内容怎么办
你可能会觉得有点奇怪:没有一个专门的元素用来标记页面主体内容。其实逻辑是这样的,既然可以界定除主体内容之外的其他元素,那么剩下的元素自然就是页面的主体了。 4.5 HTML5的文本级语义元素 除了前面讲过的结构元素,HTML5还修订了一些被称之为行内元素的标签。HTML5标准中称这些标签为文本级语义元素(http://dev.w3.org/html5/spec/Overview.html#text-levelsemantics)。我们来看几个常用的例子。 4.5.1 <b> 过去,人们通常利用<b>元素为文本添加样式,但它的实际用途其实是“给文本加粗”。不过现在你可以正式地将其仅用作样式钩子了,因为现在HTML5标准对<b>的定义是:
……一小段文本,纯粹为了吸引人的注意,除此之外不传达任何重要性,也不暗示其他语态或语气,如文档摘要中的关键词、评论中的产品名称、交互式文本软件中的可操作单词,或者文章的导语。 4.5.2 <em> OK,我举手坦白,我也常利用<em>为文本添加样式。不过现在我需要改进使用方法,因为在HTML5中它的语义是:
……强调内容中的重点。
因此,除非你确实想强调标签中的内容,否则的话可以考虑使用<b>标签或者可以的话使用<i>标签。 4.5.3 <i> HTML5标准中对<i>的描述如下:
……一小段有不同语态或语气的文字,或者是样子上与普通文章有所差异以便标明不同特点的文字。
简单地说,它不仅仅是用来给某些文字加斜体效果的。 4.5.4 在页面中应用文本层语义元素 来看看网站首页主要内容部分的标签,看它能不能给用户代理提供更好地语义。当前的标签结构如下:
确实可以对这些代码做些改善。首先,<h1>标签中的<span>标签在上下文中毫无语义,而我们想要在样式中为其设置强调效果,所以在HTML代码中也应该如此:
回顾一下网站之前的效果:
还需要给电影名称设置不同的样式,但它们不需要带有不同的语气或语态。看来在此处使用<b>标签很合适:
文本层语义元素的默认样式
根据过去对<b>标签的用法,很多浏览器仍会将其渲染为粗体。所以你可以根据实际情况在相关的CSS代码中重定义其默认样式。
最后,当我说“‘we’re here to put things right”时,我的意思是我不是瞎胡闹的,而且我想让用户代理(浏览器)知道这点。所以最后,我们将这句话使用<i>标签包裹。你可能会争论说此处应该使用<em>标签,<em>其实也可以,但我准备使用<i>。修改后的代码如下:
和<b>元素一样,浏览器默认会将<i>中的文本渲染为斜体,如果需要,就重定义其默认样式吧。
现在我们给网页主要内容中添加了一些文本级语义元素。HTML5还有大量文本级语义标签,想要全面了解,请查看HTML5标准中的相关章节,地址如下:
其实,再付出一点点努力,使用辅助技术为用户提供额外的语义,可以使我们的语义化工作更上一层楼。 4.6 遵循WAI-ARIA实现无障碍站点 WAI-ARIA是Web Accessibility Initiative - Accessible Rich Internet Applications的缩写,指无障碍网页应用技术,它主要解决一个问题:让残障人士能无障碍地访问网页上的动态内容。这种技术提供了一种描述自定义组件(网页应用中的动态片段)的角色、状态和属性的方法,这样这些组件就可以被依赖辅助技术的用户找到并加以利用。
例如,屏幕上的一个组件正在显示不断变化的股票价格,如何让访问网页的盲人用户也知道这一点呢?无障碍网页应用技术就在尝试解决这类问题。本书着眼点不在于全面讲解无障碍网页应用技术(想要全面了解,请查看http://www.w3.org/WAI/intro/aria),但我们可以采纳其中一部分容易实施的技术,将其应用到HTML5网站中,以方便残障用户。
如果你接了一个为客户制作网站的任务,除了基本要求之外通常不会给你专门的时间/经费来增加无障碍支持(悲剧的是,无障碍性经常被完全抛诸脑后)。但我们还是可以使用无障碍网页应用技术中的地标角色(landmark role)来修正HTML语义元素的一些明显的不足,从而使支持无障碍网页应用技术的屏幕阅读器可以在不同的页面区块之间轻松跳转。
ARIA的地标角色
在响应式网页设计中实现ARIA的地标角色,跟响应式设计没有什么关系。可是,在某种程度上支持它一下又非常简单(而且不必作任何修改就保证通过HTML5验证),假如为了省那么点事儿,就对从今往后编写的所有HTML5页面持放任态度,似乎也真不值得。好了,不贫了,来看看怎么做吧。
新的HTML5导航区域结构如下:
我们可以让导航区域在支持无障碍网页应用技术的屏幕阅读器上轻松地定位,只需为其追加一个地标角色属性role即可,如下面的代码片段所示:
够简单吧?针对文档结构的各部分分别有如下的地标角色。
application:用来定义用作网页应用的区域。
banner:用来定义一个站点级别(而不是某个特定文档的)的区域。如网站的头部和logo。
complementary:用来定义一个对页面主要区域进行补充说明的区域。在And the winner isn’t…这个网站中,UNSUNG HEROES和OVERHYPED NONSENSE区域就可以定义为complementary。
contentinfo:用来定义与页面主要内容相关的信息区域。例如页脚的网站版权信息区域。
form:你猜都能猜到,定义表单!但注意,如果表单用于搜索,则请使用search来替代。
main:定义页面的主体内容。
navigation:用来定义链向当前文档或相关文档的导航链接。
search:用来定义一个用于搜索的区域。
无障碍网页应用技术进阶
无障碍网页应用技术并非只有地标角色。想要做进阶应用,请参阅完整的角色列表及其简要使用说明:http://www.w3.org/TR/wai-aria/roles#role_definitions。
让我们从头开始,将现在HTML5版的And the winner isn’t…网站标签使用地标角色加以扩展:
使用非可视桌面阅读器(NVDA)免费测试网站可访问性
如果你是在Windows平台上开发且想使用屏幕阅读器测试网站的可访问性,可以免费使用NVDA。软件的官方地址如下:http://www.nvdaproject.org/。
希望本节对无障碍网页应用技术的简要介绍,让你看到了为使用辅助技术的用户提供一定可访问性支持还是很简单的,希望你能在下一个HTML5项目中考虑一下。
为使用了无障碍技术的元素设置样式
和其他属性一样,可以直接使用属性选择器来为其设置样式。如,使用nav[role="navigation"] {}可以为导航区域设置样式。 4.7 在HTML5中嵌入媒体 对很多人来说,HTML5首次进入他们的视线是在苹果公司拒绝在iOS设备上支持Flash的时候。Flash作为浏览器视频服务插件已经获得了市场主导(有人说是市场垄断)地位。但是,苹果公司没有使用Adobe的专有技术,而是决定依靠HTML5来处理富媒体渲染。HTML5本身在这一领域已经有了长足进步,苹果公司对HTML5的公开支持又极大促进了它的发展,并使其媒体工具在公众中赢得了更广泛的青睐。
正如你所预想,IE8及更低版本都不支持HTML5视频和音频。不过给微软的“先天不足”的浏览器提供备用解决方案也很简单,稍后我们会讨论这个问题。其他现代浏览器(Firefox 3.5+、Chrome 4+、 Safari 4、 Opera 10.5+、Internet Explorer 9+、 iOS 3.2+、Opera Mobile 11+、Android 2.3+)都没问题。 4.8 用HTML5的方法为页面添加视频或音频 说实话,我发现在HTML 4.01网页中添加视频或音频媒体完全是一种折磨。不是因为它很难,而是很麻烦。HTML5使这件事情变简单了。添加多媒体的语法和添加图片类似:
对很多网页设计师来说简直如沐春风!不再需要向网页中引入一大堆代码,在HTML5中只需要一个<video></video>标签(音频使用<audio></audio>标签)就能搞定这种吃力活。还可以在开始标签和结束标签之间插入文字用以告知那些使用不兼容HTML5浏览器的用户,此外还支持你一般都会追加的附加属性如height和width。我们把这些都加上:
现在将上面这段代码插入我们的网页然后在Safari中查看,视频就会出现但没有播放控制栏。想要显示默认的播放控制栏则需要追加controls属性。我们还可以追加autoplay属性(不建议——因为大家都讨厌自动播放的视频,这是常识)。修改后的代码如下:
上面的代码所产生的效果如下图所示:
其余的属性还包括用来控制媒体预加载的preload(HTML5的早期尝鲜者应该注意preload替代了原先的autobuffer),用来重复播放视频的loop,以及用来定义视频缩略图的poster(这个属性在视频播放延迟时非常有用)。要使用某个属性,将其追加到标签中即可。下面的例子包含了刚才提到的所有属性:
4.8.1 提供备用的媒体源文件
最初的HTML5规范呼吁所有浏览器内置支持使用Ogg格式(1)直接播放视频或音频(无需插件)。但是由于HTML5工作组的内部争议,曾经作为基线标准的支持Ogg(包括Theora video 和Vorbis audio)的主张在最近更新的HTML5规范中被放弃。因此目前的情况是,一些浏览器支持某一套视频和音频文件格式,而另一些浏览器则支持其他格式。例如Safari只允许在<video>和<audio>元素中使用MP4/H.264/AAC媒体文件,而Firefox和Opera则只支持Ogg和WebM。
为什么我们不能和睦相处!(《火星人玩转地球》,http://movie.douban.com/subject/1297715/。)
谢天谢地,有一种方法能在一个标签内支持多种媒体格式。但是这种方法并不能免除我们为一个媒体文件创建多种版本。我们都期望这个问题在将来某个适当的时刻会自行解决,此时我们手握多种格式的媒体文件,则可以这样编写视频标签:
如果浏览器支持Ogg格式,则使用第一个文件;否则它会继续往下解析下一个<source>标签。 4.8.2 针对老版本浏览器的备用方案 照这种方式使用<source>标签,我们就能根据需要提供一系列备用方案。例如在提供了MP4和Ogg格式之后,如果我们还想给IE8及更低版本提供一个优雅的备用方案,则可以追加一个Flash。更进一步,如果用户的浏览器没有任何合适的媒体播放技术,我们还可以为其提供媒体文件的下载链接:
4.8.3 和标签的用法基本一致
<audio>标签的用法与<video>基本一致,除了width、height和poster之外其他属性基本相同。你甚至可以将<video>和<audio>标签互换使用。两者之间的最大差别就是<audio>没有可视内容的播放区域。
4.9 响应式视频
以上我们可以看出,支持老版本浏览器会一如既往地导致代码变得臃肿。<video>标签从刚开始的一两行变成到最后的十多行(增加了一个Flash文件),仅仅是为了让老版本浏览器舒坦工作!对我而言,我更乐意忘掉Flash备用方案以追求更精简的代码,不过每种用法都各有优劣。
现在,我们可爱的HTML5视频的唯一问题是它不是响应式的。没错,我们辛辛苦苦搞的响应式网页却不怎么响应。看看下面的截图,你最好忍着不要飙泪:
幸运的是,对于HTML5式嵌入视频,修正方法很简单。只需删除视频标签中的height和width属性(如删除width="640" height="480"),然后在CSS中追加如下代码:
这种方法对本页面中的视频文件很有用,但它不能解决使用iframe嵌入的视频的响应问题(拜YouTube、Vimeo等等视频网站所赐)。下面的代码可以在网页中插入来自YouTube的电影《午夜狂奔》(2)的预告片:
暂且不管之前的CSS规则,现在的效果如下:
我敢肯定德尼罗(3)对这个效果很不爽!很有多方法可以解决这个问题,但截至目前我见过的最简单的办法是使用一个名为FitVids的jQuery小插件。我们来看看将这个插件应用到And the winner isn’t…网站中到底有多简单。
首先引入jQuery库文件。在页面的<head>元素中加载该文件。此处我使用来自Google的内容分发网络(CDN)的文件。
将FitVids文件存入一个合理的文件夹(假设文件夹名为“js”),然后在<head>中引入该文件:
最后,只需使用jQuery指定包含YouTube视频的特定元素。本例中我将《午夜狂奔》视频放入了id为#content的div中:
只需这三步。多亏有了FitVid插件,现在我们有了一个完全可响应的YouTube视频。(注意:小子,不要向视频中的德尼罗学习,吸烟有害健康!)
哈哈,全部搞定。这下我就又可以收到鲍比的圣诞贺卡了! 4.10 离线Web应用 虽然HTML5中的大量新特性对我们的响应式设计没有明显帮助(如地理定位API),但离线Web应用应该还有点用处。我们知道肯定会有越来越多的移动设备用户访问我们的网站,为他们提供一种不需要网络连接仍可访问网站内容的途径如何?HTML5的离线Web应用特性将其变成了可能。
这个功能很明显是用于Web应用的(真够搞笑的,不知道他们对这个名字是怎么想的)。假设有一个在线笔记应用,当用户的手机网络断开时,他可能正在编辑一则笔记。使用HTML5的离线Web应用,他就可以继续离线编辑笔记,然后等到网络再次连接时将本地数据发送到服务器。
HTML5离线Web应用的最美妙之处在于它的设置和使用都超级简单。接下来,我们将使用这项技术——为我们的网站创建一个离线版本。这意味着如果用户想在没有网络的情况下访问我们的网站,他也能做到! 4.10.1 离线Web应用概述 离线Web应用的运行机制是每个需要离线使用的网页都指定一个后缀名为.manifest的文本文件。这个文本文件罗列了该网页离线使用时所需的所有资源文件(HTML、图片JavaScript等等)。支持离线Web应用的浏览器会自动读取.manifest文件,下载文件中所罗列的资源文件,并将其缓存在本地以备网络断开时使用。简单吧?那我们来动手试一试…… 4.10.2 让网页可离线使用 在HTML的开始标签中,我们指定一个.manifest文件:
该文件的文件名随意,但后缀名建议使用.manifest。
你必须在每一个准备离线使用的页面的HTML标签中都追加manifest="/offline.manifest"属性。
如果使用的是Apache服务器,你可能还需要修改一下.htaccess文件,追加一行代码:
这样就保证了.manifest文件拥有正确的MIME类型,即text/cache-manifest。在.htaccess文件中还可以加入以下代码:
添加上面这几行代码,可以阻止浏览器缓存缓存文件。你没看错。因为offline.manifest是一个静态文件,浏览器默认就会缓存offline.manifest文件。所以上面这几行代码就是让服务器告诉浏览器不要这么干!
现在我们需要给offline.manifest填充内容。即通知浏览器那些文件是用作离线存储的。And the winner isn’t…网站的offline.manifest文件内容如下:
4.10.3 理解manifest文件
manifest文件必须以CACHE MANIFEST开头。第二行就是一句注释,注明了manifest文件的版本号。这句注释的用途稍后详细介绍。
CACHE:部分罗列了所有离线使用所需的文件。这些文件的路径都是相对offline.manifest而言的,所以文件路径可能需要根据情况稍作修改。使用绝对路径也是可以的。
NETWORK:部分罗列了所有不需要被缓存的文件。你可以将其看成是一个“在线白名单”。此处罗列的文件在网络畅通的情况下都会直接跳过缓存。如果你想网站内容在网络畅通的情况下及时更新(而不是仅在离线缓存中查找),可以在此处使用*。星号被称为在线白名单通配符。
FALLBACK:部分使用/字符定义了一个URL模板。它的作用是访问每个页面时都会问“缓存中有这个页面吗?”,如果有则显示缓存页面,如果没有则显示指定的offline.html文件。 4.10.4 页面被自动加载到离线缓存 根据实际情况,还有一种更简单的办法来设置offline.manifest文件。任何指定了离线manifest文件的页面(就是在标签中追加了manifest="/offline.manifest"的页面)在被用户访问时都会被自动加入到本地缓存。浏览器会缓存用户访问过的每一个网页以确保这些网页在离线状态下仍可访问。简化的manifest文件如下:
选择使用这个方法时有一点需要注意,这种方法只会下载和缓存用户访问的HTML页面,不会缓存页面内引入的图片、JavaScript或者其他资源文件。如果这些资源文件是必需的,那么请按照上节中的方法在CACHE:部分专门声明这类文件。 4.10.5 版本注释的用途 对网站内容或任何资源文件做了修改之后,你必须得对offline.manifest文件也做点修改并将其重新上传服务器。这样就能让服务器为浏览器提供新版本文件,而浏览器则会下载该新版本文件并再次触发离线存储进程。我效仿了Mark Pilgrim的例子(来自著名的《畅游HTML5》 一书),在offline.manifest文件的头部加了一句注释,每次修改网站都会对应地修改该版本号:(4)
4.10.6 离线访问网站
现在来测试一下我们的作品。在支持离线Web应用的浏览器中访问网页。一些浏览器会提示该网页使用了离线模式并在本地保存数据(例如Firefox,注意看下面截图中顶部的通知栏),Chrome则不会提示:
接着,拔掉网线(或者关闭WiFi——这个没有“拔掉网线”听着霸气)然后刷新浏览器。网页应该会和联网状态下一样刷新显示——其实我们没联网。 4.10.7 离线Web应用的故障诊断 当网站在离线状态下出现问题导致无法正常运行时,我一般都使用Chrome来做故障诊断。Chrome内置的开发人员工具有一个非常好用的Console控制台(点击地址栏右侧的扳手图标,然后找到工具 | 开发者工具,之后切换到Console面板;或者直接按F12),从中可以看出哪些文件缓存成功,那些缓存失败,以及你做错了什么。以我的经验,通常是文件路径出现问题,例如缓存页面相对于manifest文件的路径不正确。
离线Web应用的完整规范,请见如下网址:
4.11 小结
这一章讲了很多内容。从最基本的使用HTML5制作页面,到确保用户断网时仍可访问网页的离线应用技术。我们还学习了在标签中嵌入富媒体(视频)以及如何确保它在不同视口中可响应,学习了如何编写更富语义的代码,以及如何帮助那些依赖辅助技术的用户——尽管这些技术并不只适用于响应式设计。不过我们的网站仍然有一些明显的缺陷。毫不客气地说,网站非常简陋:文字没有样式,页面元素缺少细节,对照一下设计图中的按钮效果就知道了。我们不会用传统的加载图片方式来解决这些问题,理由是我们不需要图片!在下一章,我们将会使用强大而灵活的CSS3来制作更加快速和更易维护的响应式设计。
【注释】
(1)详见http://baike.baidu.com/view/99249.htm。——译者注
(2)《午夜狂奔》:http://movie.douban.com/subject/1294699/。——译者注
(3)德尼罗:《午夜狂奔》的主演,截图中右边那位先生。——译者注
(4)作者此处说得不是很清楚。补充一下:如果开发者对网站内容或资源做了修改,那么也得通知浏览器更新缓存文件,否则浏览器仍然会使用之前已有的缓存文件。而通知浏览器更新缓存文件的方式通常是更新manifest文件,浏览器如果发现manifest文件发生了变化,就会更新缓存文件。大多数情况下manifest中的缓存文件清单不会发生变化,那我们就通过修改注释的方式来改变manifest文件,注释中的版本号,既能触发文件变化,又能指明当前版本,一举两得。其实注释中还可以加入更新时间等更详细信息,有助于维护。文中提到的《畅游HTML5》,参见http://diveintohtml5.com/。——译者注