All posts in Web 标准

《重构 HTML: 改善 Web 应用的设计》上市

为给 HTML 5 让路,W3C 解散了 XHTML 2.0 工作组。这造成了对 XTHML 和 HTML 之间的很多误解,所以就有人画了漫画来解释(英文中文)。为了避免更大的混乱,我就不多作评论了。

关于本书,可以参考一下我去年的书评。对于前端工程师来说,很多情况下都需要重新捡起以前的代码,不管是不是自己写的,都会面临抉择:重新来过还是基于现状?大部分情况下,后者是唯一选择。勿怨天尤人,重构是你的好朋友。即便是在全新的工作进程中,当你闻到坏坏味道时,也需要很多小型的重构。那么,到底什么是重构?这可不是前几年流行的《网站重构(Designing with Web Stardards)》那本书里说的“重构”,而是”Refactor”,编程术语上的“重构”……说到底,还是得买一本才能了解透彻的,哈哈。

随着网页的程序化(就是 Web Application 越来越多了),眼观六路,耳听八方,前端工程师跟浏览器打交道,除了在掌握浏览器在展示页面上的知识,还需要有浏览器跟后台交互的基本知识,本书涉猎 HTTP 的基本要点,虽不深入但亦可管中窥豹了。

作为第一本在 HTML 领域探讨重构的《重构 HTML: 改善 Web 应用的设计》终于上市了,各大网上书店均已铺货。

工程师与科学家

入行已久,做的领域也从浏览器扩展到桌面端甚至是手机端,对 Web 标准多少有些自己的看法,今日斗胆一说。

两种家

我们困惑不解、迷惑不安,很大程度上源于没有指导思想。要摆正自己的位置,我们究竟是想做科学家,还是想做工程师。简明扼要,科学家经常要问“为什么”,他们关心了解人类不懂的知识;工程师则利用科学家发现的知识,制造对人类有用的物体或工具。前者研究,后者实战。很明显,我们大多数人属于工程师,W3C 那一群才是科学家。端正自己的态度,很多疑问就会迎刃而解。

两种用法

HTML 生为标记语言,是组织文档的一种格式。随着技术和社会的不断进步,HTML 的用途也逐渐升级。今天它不仅出现在浏览器上(普通网页),它还出现在桌面程序上(Adobe AIR),出现在手机程序上(PalmPre WebOS);它不仅用来展示网页,也用来构建程序的用户界面。Web 标准要求我们,HTML 必须有良好的语义化,对于展示内容的文档来说,这是毋庸置疑的,但对于只是作为构建用户界面的程序来说,强调语义是没有多大意义的。要注重语义的时候一定不能松懈,只是用户界面而已的话,怎么方便怎么来,利用最方便的手段做最适合的布局。

实用主义的前提

工程师信奉的是实用主义,但不等于可以放弃原则和规范。工程师关键任务是在遵守规范的前提下,发现、理解并结合实际的局限来达到满意的结果。作为一个流量巨大的网站,Google 对待 HTML 的态度是一个非常好的例子,省略</body></html> 的做法我们何曾想过呢?但这却是符合 HTML 4 规范的。详见: http://code.google.com/speed/articles/optimizing-html.html(需自行翻墙)。

Web Forms 2.0

Web Forms 2.0 是一个很有意思的东东,是 HTML 5 的组成部分。它的目标是提升表单的使用性 (usability),基本上就是为 input 元素的 type 属性增加一些值,如 type="email";还有一些新属性,如 required。根据 type 由浏览器实现各种功能。比如,<input type="email" required="required" />,从字面上即可看出,这是一个必须填写,且格式是电子邮件的输入框。如果你用的是 Opera 9+, 猛击这个例子看看效果。

注意,这不需要任何 JavaScript,是浏览器内部实现的功能。很遗憾的是到目前为止只有 Opera 9+ 有部分实现,作为前端开发者,每天都在为表单验证、自动完成等提升表单用户体验的事情上拼了老命,重复发明轮子。好消息是,基本上这些都可以通过 JavaScript 来模拟实现,项目当然有人在做了:webforms2,不妨下载一试。

使用标准的表单字段名

是不是很烦每次注册网站或填写相关资料时都要重来一遍?其实会有很多自动填写工具能代劳。比如使用 Mac, 在 Safari 的表单中,它可以足够聪明帮你从帐户资料中查找并填写一些相应的字段。Opera 也有相关功能,不过资料设置是在浏览器内。

当然,它们是根据表单的字段名称进行猜测与匹配的。如何给表单字段起个好名字,以方便自动填写工具的匹配,就变得有必要起来。

既然说“标准”,那名字肯定不是乱取的。RFC3106 据此而生。比方说,用户 ID 使用 Ecom_User_ID, 密码使用 Ecom_User_Password 等等,你可以访问该页面查看更多的对应实例。虽然商业气息比较浓重,但不妨碍我们的使用,以及给用户带来的便利。

Refactoring HTML 书评

很多年以前,面对上古时代遗留的 HTML 发出的腐臭,我捂住鼻子唉声叹气。刚练熟 web 标准的我,恨不得寝其尸食其肉,把一切推翻重来。但经理说,没有时间浪费在清理这些垃圾上,快给我把新的页面切了!可想而知,我是郁闷的。你也是,别装了,我知道。我常常处于崩溃边缘,作为一个有深度爱心和追求完美(这应该是所有程序员追求的品质)的 web 前端开发者来说,为何不许我为残障者着想,改善一些无障碍性?为何不许我把这些鸟b(读者最好不要连起来念),鸟i, 还有鸟u送上刑场?看着 W3C 校验器显示出的一串又一串的 erorr, 我灰心丧气,横眉冷对经理指,好像丫欠了我几十万块冥币,哦不,人民币……

皆因我不知道“重构”(refactoring)。

或许你第一次看到这个词,会欢呼雀跃,耶,“重构”,网站重构,一切重新再来?很明显,不是。相反,它的过程是逐步的,有时甚至是很微小的。作为一门在编程中的高级技术,重构是指“在不改变代码外在行为的前提下,对代码作出修改,以改进程序的内部结构”(《重构:改善既有代码的设计》,2003,中国电力出版社)。对于 HTML 来说,就是不改变 HTML 所表达意义的基础上,对 HTML 作出修改,以改进 HTML 的内部结构。是不是很简单?

读者都知道 web 标准的意义所在,很明显,重构的目的是改善既有的 HTML,向 web 标准进军。重点在于改善,而不是取代。在很多情况下,取代的代价远比改善大得多。如果才能做到最大化的投入产出比,很明显,答案是重构。

啰嗦这么多,到底怎么重构?特别是 HTML, 怎么重构啊,看着堆垃圾我就头痛,是不?很多公司的网站,我们可以看到,比如腾讯,雅虎的新推出的页面,都是基于 web 标准的了,但还是存在大量的旧页面,就算访问量巨大,也是纹丝不动。我相信,这很大程度上不是由于不想改,而是除了全盘推翻重头再来之外,实在找不到好的解决办法。重构是你的解药,宝贝。

由世界知名的 XML 专家 Elliotte Rusty Harold 所著的 Refactoring HTML: Improving the Design of Existing Web Applications 是你解药的配方。书中大谈特谈的章节不多,就第一章说说who, what, why, when, where,其他章节都是说 how. how, yeah, 就是到底怎么重构的锦囊妙计。书中从编程世界中“窃取”被证明是可行的、成熟的技术,很多可能是 web 标准实践者闻所未闻的技术,结合到 HTML 来,创造行之有效的新技术,解决 HTML 特有的难题。比方说,你关心过 GET 和 POST 是什么吗?知道为何 Google 爬虫爬一爬,很多页面消失殆尽吗?(嗯嗯,老油条们,我知道你知道(绕吧?),我在这里问的是“页面仔”)。关心过自动化测试吗?什么,你还刀耕火种,写一行就在浏览器刷一下看效果?知道怎么样批量校验你的页面吗?不要告诉我你一页又一页的把上千个页面轮番轰炸 W3C Validator…

不知道?那怎么还浪费时间看什么书评,赶紧的打开书来看啊!噢哦,没有书?google 一下,有得下。英文看不懂?很吃力?噢哦,明年中文版就会上市,嗯嗯,译者就是我……(终于露出狰狞面目)……

本书是探讨 HTML 领域的重构,是对重构这门技术的又一创造性运行。它从工具入手(我们知道,工具是重构的重要辅助),然后逐一分析良构(well-formness)、合法性、布局、无障碍、web 应用程序和内容等等需要重构的方面,提出问题,讨论理据(motivation)并提供行之有效的解决方案(mechanics)。对于接触 web 标准较少的人来说,提供了一个百科全书式的的参考,而对于我的同行们,sure, 亲爱的页面仔们,不仅可以查漏补缺,亦可学习程序工业中的先进经验,提升自己的“工业”素养。总之,这不是一本束之高阁的书。

编写 HTML 不仅是一门技术,更是一门艺术。你会了解的,在读了本书之后。在此我很严肃地说。仅以此献给中国所有的页面仔,共勉。

CSS Sprites

CSS Sprites技术不新鲜,早在2005年 CSS Zengarden 的园主 Dave Shea就在ALA发表对该技术的详细阐述。原先只在CSS玩家之间作为一种制作方法流传,后来出来个14 Rules for Faster-Loading Web Sites, 技术人员之间竞相传阅,其中第一条规则Make Fewer HTTP Requests就提到CSS Sprites。于是这个小妖精就火了起来,甚至出现了在线生成工具,势不可挡也。近来国内很多blog都提到CSS Sprites,最著名的例子莫过于 http://www.google.co.kr/ 下方的那几个动画。最新发布的YUI中,也是使用到CSS Sprites,几乎都有的CSS装饰图都被一个40×2000的图包办。社交大站Facebook最近也使用了一个22×1150的图片承担了所有icon. 一时间,CSS Sprites无处不在。

原理

我们知道,自CSS革命以降,HTML倾向于语义化,在一般情况下不再在标记里写装饰性的内容而是把呈现的任务交给了CSS。GUI是缤纷多彩的,少不了各种漂亮的图来装点。新时代的生产方式是,在HTML布满各种各样的钩子(hook),然后交由CSS来处理。在需要用到图片的时候,现阶段是通过CSS属性background-image组合background-repeat, background-position等来实现(题外话:为何我提现阶段,因为未来浏览器若支持content则又新增另外的实现方法)。我们的主角是,你一定猜到了,就是background-position。通过调整background-position的数值,背景图片就能以不同的面貌出现在你眼前。其实图片整体面貌没有变,由于图片位置的改变,你看到只该看到的而已。就好比手表上的日期,你今天看到是21,明天看到是22,是因为它的position往上跳了一格。所以你也大概了解到,CSS Sprites一般只能使用到固定大小的盒子(box)里,这样才能够遮挡住不应该看到的部分。

我们使用YUI的sprite.png举个例子,假如我们有这么一段代码,max代表最大化,min代表最小化,我们需要给它们配上相应的漂亮图片(这样我们的网站才能够吸引人,才可以卖钱,才可以到佛罗里达晒太阳:D):

<div class="max">最大化</div>
<div class="min">最小化</div>

这两个class都使用同一个图片:

.min, .max {
  width:16px;
  height:16px;
  background-image:url(http://developer.yahoo.com/yui/build/assets/skins/sam/sprite.png);
  background-repeat: no-repeat; /*我们并不想让它平铺*/
  text-indent:-999em; /*隐藏文本的一种方法*/
}

效果如下:

最大化
最小化

我们看到一团灰,没错,因为我们还没有指定background-position,默认为 0 0,可以看下sprite.png, 处于这个位置正是灰块。好了,我们要找到代表最大化的加号和代表最小化的减号的位置找出来。经过测量,最大化按钮位于Y轴的350px处,最小化按钮位于Y轴400px处。想一想我们如何才能让它们能够显示出来呢,明显,要向上提升sprite.png,得到代码如下:

.max {
  background-position: 0 -350px;
}
.min {
  background-position: 0 -400px;
}

耶,我们成功了:

最大化
最小化

(注意:为了举例的方便,本例子直接在HTML内置样式,切勿在实践中的非特殊情况使用这种方式)。

优点

我们从前面了解到,CSS Sprites为什么突然跑火,跟能够提升网站性能有关。显而易见,这是它的巨大优点之一。普通制作方式下的大量图片,现在合并成一个图片,大大减少了HTTP的连接数。HTTP连接数对网站的加载性能有重要影响。

缺点

至于可维护性,这是一般双刃剑。可能有人喜欢,有人不喜欢,因为每次的图片改动都得往这个图片删除或添加内容,显得稍微繁琐。而且算图片的位置(尤其是这种上千px的图)也是一件颇为不爽的事情。当然,在性能的口号下,这些都是可以克服的。

由于图片的位置需要固定为某个绝对数值,这就失去了诸如center之类的灵活性。

前面我们也提到了,必须限制盒子的大小才能使用CSS Sprites,否则可能会出现出现干扰图片的情况。这就是说,在一些需要非单向的平铺背景和需要网页缩放的情况下,CSS Sprites并不合适。YUI的解决方式是,加大图片之间的距离,这样可以保持有限度的缩放。

总结

性能压倒一切。CSS Sprites是值得推广的一种技术。尤其适宜用于FIR,比如固定大小的icon替换。为保持兼容性,图片中的各个部分保持一定的距离是一种不错的做法。

推荐阅读:

更新:有网友问到IE6不支持png的问题。其实真相是,IE6不支持的是半透明(alpha transparency)的png,对于全透明的png, IE6并不存在问题。因此,在实践中,不涉及到半透明而需要透明背景的图片,其实都可以使用png, 这是很安全的。

HTML 5新增的元素

在本人看来,HTML 5是一个妥协方案,虽不激进,但更能推动技术的继续进步。没有命名空间,元素也不要求闭合(当然这并不是优点),浏览器也可以宽大处理一些错误。一切沿袭上个世纪HTML 4的做法。对于HTML的渲染,浏览器一直停留在1999年的水平。为此,HTML 5是一个实用主义方案,这样不仅可以继续处理这么多年来散落在世界各个角落的HTML,也可以让浏览器厂商更容易添加新特性。这就叫degrade gracefully(优雅降级)。让我们来看看HTML 5增加的一些新元素。

结构元素

这真是大快人心。目前,我们定义结构只能通过一个“万能”的div, 试图通过设置它的特性id的值如header, footer, sidebar等来分别表达头部,底部或者侧栏等。有了它们,代码编写者不再需要为id的命名费尽心思,对于手机、阅读器等设备更有语义的好处。HTML 5增加了新的结构元素来表达这些最常用的结构:

  • section: 这可以表达书本的一部分或一章,或者一章内的一节
  • header: 页面主体上的头部。并非head元素
  • footer: 页面的底部(页脚),可以是一封邮件签名的所在
  • nav: 到其他页面的链接集合
  • article: 诸如blog, 杂志,纲要等之中的一条独立记录。

举个例子,一个blog的首页,用HTML 5写的话,可以是这样(有省略):

<<!DOCTYPE HTML>
<HTML>
  <head>
    <title>realazy</title>
  </head>
  <body>
    <header>
    <h1>realazy</h1>
    </header>
    <section>
    <article>
    <h2><a href="http://realazy.org/blog">标题</a></h2>
    <p>内容在此...(省略n字)</p>
    </article>
    <article>
    <h2><a href="http://realazy.org/blog">标题2</a></h2>
    <p>内容2在此...(省略n字)</p>
    </article>
    ...
    </section>
    <footer>
    <nav>
    <ul>
      <li><a href="http://realazy/blog">导航1</a></li>
      <li><a href="http://realazy/blog">导航2</a></li>
      ...
    </ul>
    </nav>
    <p>© 2007 realazy</p>
    </footer>
  </body>
</HTML>

块级block的语义元素

HTML还增加以下三个块级元素:

  • aside
  • figure/code>
  • dialog

aside可以用以表达注记、贴士、侧栏、摘要、插入的引用等诸如作为补充主体的内容。比如这样表达blog的侧栏:

<aside>
  <h3>最新文章</h3>
  <ul>
    <li><a href="http://realazy.org/blog/">文章标题</a></li>
    ...
  </ul>
</aside>

figure元素表示一个有说明的块级图片。比如:

<figure>
  <legend>这是图片的说明</legend>
  <img alt="图片可替换文本" src="/path/to/img.png" />
</figure>

dialog元素用于表达人们之间的对话。在HTML 5中,dt用于表示说话者,而dd则用来表示说话者的内容。如:

<dialog>
  <dt>佛</dt>
  <dd>色即是空</dd>
  <dt>悟空</dt>
  <dd>我现在需要点空……

行内(inline)的语义元素

m元素用来标记一些不是那么需要着重强调的文本。现在尚有争议,可能最终会改为mark.

time元素如其名,用来表达时间。它需要一个datetime的特性来标明机器能够认识的时间,如:

<time datetime="2008-08-08T20:08:08">2008年8月8日晚上8时8分8秒</tiem>

meter元素表达特定范围内的数值。可用于薪水、百分比、分数等。比如:

很遗憾地告诉你,我只有<meter>150cm</meter>

它还有6个特性来表达各方面的含义,比如:

<p>您的分数是:<meter value="88.7" min="0" max="100" low="65" high="96" optimum="100">B+</meter>.</p>

还有一个progress,也是义如其名,用以表达进度:

目标完成度:<progress value="40" max="100">40%</progress>

嵌入多媒体

新增videoaudio元素。顾名思义,分别是用来插入视频和声音的。至于格式,交由浏览器实现,HTML再也不需要特别的代码去播放特定的格式。就像img一样,不管是png, jpg还是gif都可以显示。值得注意的是,它们可以包含内容。比如,可以把歌词放到某段歌曲中去:

<audio src="谁人伴你睡.mp3">
  <p>泪枯干</p>
  <p>难忍怎么委屈自已</p>
  <p>曾经有一刻悲与喜</p>
  ...
</audio>

交互性

HTML 5同时也叫Web Applications 1.0, 因此也进一步发展交互能力。这些标签就是为提高页面的交互体验而生:

  • details
  • datagrid
  • menu
  • command

details用来表示一段具体的内容,但是内容默认可能不显示,通过某种手段(如点击)与legend交互才显示出来。这跟现在各种通过JavaScript隐藏一段内容,在点击后才显示出来的做法有些类似。比如:

一句话记录生活中的点点滴滴,
<details>
  <legend>更多</legend>
  <p>交流与分享,拉近你和朋友,支持 MSN/GTalk/QQ、短信、手机 WAP</p>
</details>

它可以有一个open的特性,用来显示细节与否。

datagrid用来控制数据,可以由用户或者脚本来更新。

menuHTML 2就存在了,不过HTML 4把它废弃了。HTML 5废物利用,并在期内加上command元素。

参考:New elements in HTML 5

小巧三条

这两条是关于IE环境中的CSS的。

  1. 不要使用import引入CSS,可以避免内容的无样式瞬间(FOUC)问题。
  2. 不要把样式的link放到页面后(</body>之前),以防止页面6-10秒的空白。

这条是关于Firefox的。

在Firefox里,嵌入flash影片的HTML代码存在wmode特性时,在某些position:relative的元素内,会产生不可点击的现象(很遗憾,我总结不出具体条件,只知道必备条件是这个)。解决方法,只能依赖于JavaScript。思路是,暂时改变的了的元素的positionstatic, 然后恢复。JavaScript代码大致如下:

function fixSWFUnclickable(wrapper){
		wrapper.style.position = 'static';
		setTimeout(function(){wrapper.style.position = 'relative';}, 1);
}

以上。

Safari 3 Windows版

莫非这是WWDC 2007的礼物之一?请访问 http://www.apple.com/safari/

经测试,这个beta版对中文支持严重不足。只有满足以下条件才可以正确显示:

  1. 你的系统装有微软正黑体(microsoft jhenghei)
  2. 正在浏览的网站字体优先指定为微软正黑体

很凑巧,我的blog符合第二个条件。请穿墙看截图:http://www.flickr.com/photos/realazy/541766405/.

尝鲜Safari 3 on Windows,那么装上微软正黑体后,可以访问我的网站来测试(可能是世界上唯一能够在当前版本的Safari 3 on Windows正确显示的中文网站?)。

以上。

更新:Safari 3.0.2 已经支持中文的显示。

HTML新变数

XHTML已死,请准备迎接新的HTML 5.

在未来,所有的伺服为text/html的标记都将被视为HTML 5处理

XHTML,尽管Firefox和Opera有所支持,但是已名存实亡。它并未见得不先进,但是历史的现实(试想想如果转换到真正的XHTML,有多少网页会由于不良够而无法显示)无情地把它丢进了历史的垃圾桶中。尽管如此,Web标准观念已经深入人心,尽管核心概念跟XHTML并未有根本的联系,但是XHTML曾作为一个推广标准的急先锋并成为某些人忽悠、炫耀的名词功不可没。

尽管如此,当今运行在世界各个角落的web网站或者web应用,除了一些热心的个人追随者,基本上所有的都是HTML, CSS和JavaScript纠缠不清,分离的理念有所推进但也不是灵丹妙药。

除了可维护性那么一点点可怜的理由,为见得分离就有什么强大的好处。accessibility? 开发另外一个版本的成本未见得维护一个“万能”的版本要高。

web标准的价值有限。HTML和CSS充其量是构建简单界面的标记语言,把界面表示出来就是他们的最大用处。同样,JavaScript能把动态效果运行起来,给用户最佳体验,只要以一种可维护性较高的方式编写即可。当然,就目前来说,可维护性较好的方式,还是web标准的分离方式。

xhtml已死,web标准的含义亦函待改进。否则说不定明天就会有web标准的可替代方案(XAML? XUL?)。

当然,我在这里并没有号召大家不要管web标准了,在当前来说,它是最先进的,你还是需要学习并理解运用它。当然,不要受到条条框框的束缚,我其实想表达的是:在web中,实用主义是最高指导思想。你不仅需要理解,还需要变通。

期望HTML更好的未来。