每个应用程序都是独一无二的——但构成应用程序的组件却不尽如此。工具箱和程序库能够捆绑高层 GUI 元素和概念,但它们也因此造成了对程序库的依赖。
一本名叫《精通HTML5 和CSS3 设计模式》的新书研究记录了web 应用程序的常用设计模式,并使用HTML5、CSS 和JavaScript(需要的话)提供了这些设计模式的实现方案。该书的出版机构Apress 向InfoQ 独家提供了该书第二章“HTML 设计模式”的摘录。
InfoQ 邀约到了该书的作者之一Dionysios Synodinos,和他谈论了该书背后的思想,以及 HTML、CSS3 和 JavaScript 开发技艺目前的状况。
InfoQ: GoF 设计模式一书的贡献之一就是提供了共用的术语,简化了沟通方式。你们的书也是这样吗?你们根据什么给设计模式起名字?它们用于解决不同领域下的问题吗?(排版、GUI 工具箱…)?
设计模式已经在软件编程中成功运用。它们提高了 web 应用程序设计和开发的生产率、创造性以及有效性,同时减少了代码量和复杂度。在 CSS(3) 和 HTML(5) 的情况下,设计模式是一组常用功能特性的集合,工作于各种各样的浏览器和屏幕阅读器中。它们不需要依赖于 hacks 和 filters 技术,同时不降低设计价值和可访问性。但到目前为止,这些设计模式还没被系统地运用于 web 设计和开发。 一旦一个设计模式浮出水面,就将极大地提高创造力和生产力。它能够单独使用以快速得到结果,它还能和别的设计模式联合使用以创建更加复杂的结果。设计模式简化并增强创造过程,它们使得创造本身就像搭积木或者乐高组合玩具一样容易。你只要选择预先设计好的模式,然后做适当的调整,就可以对它们进行组合以创造你想要的结果。设计模式不会限制创造性——事实上它们解除了对创造性的约束。
你提及的 GoF 设计模式一书写到:设计模式由 4 个元素组成:模式名称、问题、解决方案和折衷。我们的书也遵循了这种方式。
InfoQ: 这本书涉及到跨浏览器编程和设计吗?
本书会涉及跨浏览器开发。这是一本与实战相关的书,它直接关注于被设计成具体模式、所有浏览器都支持的 CSS 和 HTML。每个模式都在所有主流浏览器中测试通过,同时本书在很多情况下都特别提及了对过时浏览器的兼容问题。
让我们以“Center Aligned(居中对齐)”模式为例,该模式用于以下情形:你想要让一个元素及其内容水平居中于它的父元素或最近的定位祖先元素。现在想想,这应该是很容易实现的任务,但可惜的是,事实上会有一些陷阱。就像我们在书中提到的,IE6 不能让绝对定位元素居中,版本 7 能够让伸展的绝对定位元素居中,但不能让设置了宽高的绝对定位元素居中,版本 8 及以上能够让设置了宽高的绝对定位元素居中。而我们提供的模式能够兼容所有浏览器!
需要说明的是,有些模式只能应用于支持 HTML5 的浏览器,比如“HTML5 Form Validation(HTML5 表单验证)”等等。
InfoQ: 你们是怎样选择框架的?你建议选择覆盖所有方面的大框架,还是根据特定任务精挑细选合适的小框架?
我个人喜欢组合小框架和程序库,而不是使用试图应付一切的大框架。无论前端编程还是后端编程都是如此。从小程序库中精挑细选,能够让我更加自由而准确地以我想要的方式达到想要的结果。这同时能帮助我为项目选择合适的工具,以及在抽象有瑕疵时把握分寸。
HTML5 平台的优势就是它比我能想到的其它平台更加适合于整合程序库,这可能是其最大的优势!
有几个 JavaScript 和 CSS 程序库能让程序员的工作更加轻松,比如 jQuery、jQueryUI、Underscore.js、Yahoo UI、HTML5 Boilerplate、Modernizr、960 Grid System、Twitter 的 Bootstrap 等等。
InfoQ: 最令你头疼的三个 HTML 问题是什么?或者说哪些 HTML 概念最让你抓狂?
我认为 HTML 平台主要存在 3 个“问题”: 1. 浏览器支持:构建任何一款需要在几种不同环境(浏览器 + 操作系统)中运行的应用程序都是很大的挑战。像 jQuery 等程序库能如此成功,正是因为它们抽象出了这些不同点。同时我还喜欢像 browserstack.com 和 Abobe BrowserLab 这样的工具,可以用于测试多重配置。
2. 可避免的冗余和有限的功能特性:人们普遍认为 HTML 语法是冗余的,这也是为什么人们正在为特定的实现做其他探索(提示:markdown)。CSS 语法也同样有一些限制,人们正在研究如何解决这些限制(提示 2:LESS)。
3. HTML 特定问题:存在这样的情况:有些 HTML5 API 特性能按照文档规范运作,但它们是违背直观的,经常会导致误会。这些特性很诱人,但同时会输出让人意想不到的结果。一个很好的例子就是 Application Cache(应用程序缓存),以及它到底如何更新。
InfoQ: 你们书中讨论了 CSS,而我们看到 CSS 的超集,比如 LESS、SASS、Closure Stylesheets 正在引起人们的关注。对这些你有什么想法么?在什么时候使用这些技术比较合适呢?
它们绝对是可以用的。像变量(variables)、混入(mixins)和嵌套规则(nested rules)等技术能使设计者的工作变得更加容易!
每个曾经试图在 CSS 文件中处理颜色的程序员都愿意使用下面的例子:
复制代码
// This is less (note the single line comment format) @color: #4D926F; #header { color: @color; } h2 { color: @color; }话虽这么说,但必须强调的是,你可别指望在没有搞懂 CSS 的情况下能会使用像 LESS 这样的技术。LESS/SASS 用于帮助你写好 CSS,而不是取代 CSS。同时想要指出的是,尽管人们认为 CSS 有不合理的地方,但说应该用其他方式来渲染 GUI 样式是骇人听闻的。在任何时候我都倾向于选择并不完美的 CSS,而不是使用 XML 或者面向对象的类来添加样式!
InfoQ: 至于文档格式,说来也怪,浏览器中 HTML 对富文本编辑的支持很糟糕。HTML 已经新增了 contentEditable 属性,但目前很多项目都已停止使用该属性。比如 Google Docs,以及源代码编辑器 CodeMirror 2和 Cloud9 ACE从不使用 contentEditable 属性。如果你现在需要构建一个富文本编辑器,那么会使用什么技术来完成呢?
这要取决于你想要编辑器做什么,以及你能等待多久。例如,如果你想要格式化文档,你也许会对 Kylix 这类技术感兴趣。事实上 Google 已经放弃使用 contentEditable,转而使用 Kylix。 至于代码,Mozilla 的成员正在开发一款基于 Firefox 开发人员工具的代码编辑器。听说他们计划使用 Eclipse 的 Orion,因为这能满足他们的 i18n 和 a10y 需求。同时他们还会从 Ace 和 Skywalker 中借用许多好的做法。两种途径都需要付出相当大的努力,即便只是实现最基本的编辑功能。Ace 和 Skywalker 本身也同样如此。
所以,浏览器中的富文本编辑体验不如桌面程序中的,我知道已经有许多聪明人正在做出努力,也相信差距会迅速缩小,特别是考虑到 web 平台的其他方面具有很多优势。
InfoQ: ACE 编辑器的格式化文本编辑模式令人印象深刻,它为每次屏幕更新重新创建 HTML——这确实可行,因为现今 HTML 组件的速度快得令人难以置信。你知道其他类似的例子吗?
Google Docs 编辑器 Kylix 的样式引擎就是个很好的例子:当你在键盘上敲字母‘a’时,编辑器知道你按了‘a’键并作出响应,以离屏的方式画了一个‘a’。接着它测量‘a’的宽和高,将宽高和鼠标位置的 x、y 坐标组合,然后将‘a’放置在屏幕的正确位置上。如果你处于单词的中间,它会将字母推到光标的后面。如果你处于一行的最后,编辑器会将单词移到下一行,并将任何溢出内容顺推到更后的行。
类似的,Google Docs 中的光标事实上是一个“手动”放置在屏幕上的只有 2 个像素宽的 div 元素。当你单击屏幕上的某个点时,编辑器计算出该点的 x 和 y 坐标,然后在该坐标点画出光标。
InfoQ: 该书提供了许多实现 GUI 工具箱基本特性(alert、layout 等)的解决方案。应用程序应该努力模拟内建 GUI 工具箱及其行为(比如在移动平台),还是只将这些特性托付给 web 形式的跨平台样式?
人们普遍认为对于桌面系统,应用程序应该遵循你所说的“web 形式的跨平台样式”。这也是我们的书所关注的。
另一方面,在移动领域,人们在模拟内建外观和体验时碰到很大问题。一个很好的例子就是 jQTouch,它不仅提供了苹果式的主题,同时还提供了具有内建应用感官的动画,等等。
InfoQ: 你对 Markdown、HAML 或者其它可用来编写 HTML 的技术是怎么看的?
在降低 HTML 的冗余度以及让内容更加容易为人所阅读和编辑方面,Markdown 做得非常成功。因此对于网页编辑,比如 CMS,使用 Markdown 要比使用纯 HTML 好!另一方面,很多时候当我碰到需要使用 Markdown 的地方时,我总在想,要是有一个所见即所得的编辑器就好了。类似的,HAML 试图降低冗余,不过是从开发人员的角度出发。它有助于你更快地编写 HTML 模板,同时使得这些模板更加容易维护。
例如:
复制代码
#profile .left.column #date= print_date #address= current_user.address .right.column #email= current_user.email #bio= current_user.bio比下面的好多了:
复制代码
<div id="profile"> <div class="left column"> <div id="date"><%= print_date %></div> <div id="address"><%= current_user.address %></div> </div> <div class="right column"> <div id="email"><%= current_user.email %></div> <div id="bio"><%= current_user.bio %></div> </div> </div>假设有体面的平台支持的话,这里“体面”是指模板引擎中的直接支持,我倾向于在每个可能的项目中使用 HAML。作为丈夫和父亲,我可没有多少空闲时间在每次发生变化时将 HAML 文件手动转换成内建模板:)
关于书的作者
Dionysios Synodinos 是 C4Media 研发平台团队的领队,同时也是一名自由顾问,专注于富英特网应用、web 应用、安全、移动互联网和 web 服务。Dionysios Synodinos 还是 InfoQ 的 HTML5 和 JavaScript 主编,同时,他还为 InfoQ 撰写 JVM 平台的文章。Dionysios Synodinos 在服务端编程和客户端 GUI 设计两个方向上有超过十年的经验,参与过多种软件项目,为多个技术出版机构做过贡献。
查看英文原文: Interview and Book Review: Pro HTML5 and CSS3 Design Patterns
感谢侯伯薇 对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。
评论