这是在 CSS Globe 上看到的一篇文章,个人感觉对理解 Web 标准和 Web 开发(尤其是前端开发)很有启发意义,特翻译分享,并加入了一些我的想法。原文地址:5 Most Common Web Standards Misconceptions。
当开始学习 Web 标准的时候,我们会听到很多关于 Web 标准的理论,这些理论不一定都是正确的,有些反而可能会误导我们。下面是一些最常见的误解。
1、Web 标准 = Validation(验证)
W3C 提供的 HTML 标记验证和 CSS 验证对学习 Web 标准和 Web 开发是很重要的,它不但能够指出代码中的错误,还能让我们学会怎样去改正错误。但是,仅仅通过验证并不意味着你的页面符合 Web 标准。我曾经把 W3C 的验证服务和英语拼写检查工具做过比较。如果你在拼写检查工具中输入这样一个句子:
Dog fox brown lazy over jump.
拼写检查工具并不会发现任何错误,因为单词拼写全是正确的。但是,这句话有意义吗?当你没有为你的页面逻辑结构使用合适的 HTML 元素时,不正和上面的那个例子一样吗?机器就是机器,它可以检测出你的语法、属性、嵌套等的正误,但是它无法了解你要表达的内容的本质。这就是 Web 语义化(semantic)的重要性。
2、Web 标准 = CSS
CSS 是一种样式单,它是一个让页面看起来更加美观的(强大的)工具,而且,CSS 也是 Web 标准的一个重要部分。但是,看看那些基于表格布局,tr、td 等标记层层嵌套如同噩梦一般的页面,你会发现它们也在通过各种方法使用着 CSS,那么,这些页面符合 Web 标准吗?
Web 标准并不只是技术,当然更不只是 CSS,而是你怎样去使用它。一个相对标准的页面,即使剥离了 CSS,它仍然应该是可读的,层次结构清晰的。
3、Web 标准 = No Tables
当从表格布局转变到 CSS 布局之后,很多开发者开始拒绝在任何情况下使用表格,他们认为“Tables are evil”。
对我来说,没有任何一个 HTML 元素是 evil 的。它们是被一群非常聪明的人发明的,每一个元素都有它的目的和存在的意义。什么时候应该使用表格,这又涉及到了 Web 语义化的问题,如果你要在页面中显示表格数据(比如日历表、统计表等),那么,表格就是你的最佳选择。
4、Web 标准 = Divs
过度使用 div,是在刚从表格布局转变到 CSS 布局的开发者中很常见的问题,我曾经也经历过。我们经常可以看到这种说法:“div+css布局”,似乎使用了 div 就是好的,就是符合 Web 标准的。实际上有些时候,你只是简单地使用 div 代替了表格,仅此而已。你最终得到的还是复杂的、难以读懂的、层层叠叠的标记,就像以前一样,只是 div 代替了以前的 table、tr、td,并且把 CSS 文件增大了几倍而已。
你需要改变的不仅仅是在页面中充当容器的元素,而是整体的结构和理念。符合 Web 标准需要走一条很长的路,好在这条路是充满阳光的,我愿意走下去。
5、Web 标准 = No IE
我知道你很可能和我一样痛恨 IE,但是,Web 标准的观点是实现跨平台、跨浏览器的页面访问,更重要的是,大多数用户都在使用 IE。因此,我们不能抛弃 IE,尽管它不是一个符合标准的浏览器。
所以,不要在开发中忽视 IE 下的调试,因为毫无疑问会有用户在使用 IE,你迟早都必须面对它。骂完 IE 以后,还是好好想想怎么对付它吧。
从总统博客得知,今天(2008年4月9日)是第三届 CSS 裸奔节,这里是中文版介绍。
CSS 裸奔,顾名思义,就是把网页中的 CSS 移除,把页面最原始的表现呈现在访问者面前。这个活动意在推动 Web 标准,倡导使用结构良好、语义明确的 XHTML 构建网页。这样的网页,即便没有 CSS 的支持,层次结构依然清晰明了,只是欠缺美观。
从现在开始,我也开始参与 CSS 裸奔了,除了少数插件的 CSS 不方便移除之外,主体的 CSS 都移除了。网站原形毕露,看起来另有一番滋味吧。活动持续一天,明天即将恢复原状。
去年我曾经写过一篇 CSS 下拉菜单,其中完全只使用 CSS 实现了导航条鼠标悬停下拉菜单的效果(演示地址)。但是只用 CSS 实现起来比较麻烦,代码较多,而且为了浏览器的兼容性不得不使用了两个 CSS 文件,所以我把它叫做“探究”,实用性并不强。
最近我从 blog 的流量统计中发现,很多网友通过搜索“JS 下拉菜单”关键字访问到了我的那篇文章。不过很遗憾,那篇文章和 JavaScript 一点关系都没有,有误导网友之嫌。所以,昨天我花了一点时间把原来的代码做了一点修改,搞了一个 JS 版下拉菜单。其实用 JS 实现下拉菜单比 CSS 简单多了,因为各个浏览器之间对 JS 支持的差异相比 CSS 来说要小一些,不需要花那么多心思用在对付浏览器上。如果 HTML 的结构良好,只需要很少的 JS 代码即可实现,而且可以实现多级下拉菜单的效果(我的示例中给出了二级下拉菜单,可以根据需要按照原来的 HTML 结构逐级添加)。
演示地址
页面源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JavaScript下拉菜单</title>
<style type="text/css">
* {
padding:0;
margin:0;
}
body {
font-family:verdana, sans-serif;
font-size:small;
}
#navigation, #navigation li ul {
list-style-type:none;
}
#navigation {
margin:20px;
}
#navigation li {
float:left;
text-align:center;
position:relative;
}
#navigation li a:link, #navigation li a:visited {
display:block;
text-decoration:none;
color:#000;
width:120px;
height:40px;
line-height:40px;
border:1px solid #fff;
border-width:1px 1px 0 0;
background:#c5dbf2;
padding-left:10px;
}
#navigation li a:hover {
color:#fff;
background:#2687eb;
}
#navigation li ul li a:hover {
color:#fff;
background:#6b839c;
}
#navigation li ul {
display:none;
position:absolute;
top:40px;
left:0;
margin-top:1px;
width:120px;
}
#navigation li ul li ul {
display:none;
position:absolute;
top:0px;
left:130px;
margin-top:0;
margin-left:1px;
width:120px;
}
</style>
<script type="text/javascript">
function displaySubMenu(li) {
var subMenu = li.getElementsByTagName("ul")[0];
subMenu.style.display = "block";
}
function hideSubMenu(li) {
var subMenu = li.getElementsByTagName("ul")[0];
subMenu.style.display = "none";
}
</script>
</head>
<body>
<ul id="navigation">
<li onmouseover="displaySubMenu(this)" onmouseout="hideSubMenu(this)">
<a href="#">栏目1</a>
<ul>
<li><a href="#">栏目1->菜单1</a></li>
<li><a href="#">栏目1->菜单2</a></li>
<li><a href="#">栏目1->菜单3</a></li>
<li><a href="#">栏目1->菜单4</a></li>
</ul>
</li>
<li onmouseover="displaySubMenu(this)" onmouseout="hideSubMenu(this)">
<a href="#">栏目2</a>
<ul>
<li><a href="#">栏目2->菜单1</a></li>
<li><a href="#">栏目2->菜单2</a></li>
<li><a href="#">栏目2->菜单3</a></li>
<li><a href="#">栏目2->菜单4</a></li>
<li><a href="#">栏目2->菜单5</a></li>
</ul>
</li>
<li onmouseover="displaySubMenu(this)" onmouseout="hideSubMenu(this)">
<a href="#">栏目3</a>
<ul>
<li onmouseover="displaySubMenu(this)" onmouseout="hideSubMenu(this)">
<a href="#">栏目3->菜单1</a>
<ul>
<li><a href="#">菜单1->子菜单1</a></li>
<li><a href="#">菜单1->子菜单2</a></li>
<li><a href="#">菜单1->子菜单3</a></li>
<li><a href="#">菜单1->子菜单4</a></li>
</ul>
</li>
<li><a href="#">栏目3->菜单2</a></li>
<li onmouseover="displaySubMenu(this)" onmouseout="hideSubMenu(this)">
<a href="#">栏目3->菜单3</a>
<ul>
<li><a href="#">菜单3->子菜单1</a></li>
<li><a href="#">菜单3->子菜单2</a></li>
<li><a href="#">菜单3->子菜单3</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
这些天又捣鼓了一下 blog,为了使我的首页(www.helloxudan.net)通过 W3C 的 XHTML 验证。我个人还是很注重 Web 标准的,以前验证 blog 首页的时候没有通过,虽然我不能算是一个完美主义者,但是 blog 上一直运行着有错误的代码,我觉得心里很不舒服,于是这两天抽了点时间做了一些修改,基本解决了问题。
其实绝大多数 Wordpress 主题在原始状态都是通过了 XHTML 验证的,但是我们在使用的时候会在 blog 中添加很多新的东西,比如日志、图片、各种插件以及各种 widget 等,或者喜欢 DIY 的朋友会对主题做一些小小的修改来实现自己理想中的效果。这些因素都有可能使原来通过验证的主题出现一些 XHTML 错误,我主要就是解决了这个问题。
一个符合标准的 XHTML 文档有几点需要注意,这也是从 HTML 到 XHTML 主要的改变:
- 所有的 XHTML 标签都必须有一个相应的结束标记,标签必须闭合最容易被忽略的就是那些不成对出现的标签,例如 <img />,<input /> 等,最后一定要加一个“/”来闭合标签。
- 所有标签的元素和属性的名字都必须使用小写
- 所有的XML标记都必须合理嵌套
- 所有的属性必须都用引号”"括起来
- 把所有<和&特殊符号用编码表示
XHTML 验证中的常见错误:
- required attribute X not specified:标签中缺少必须的属性。最常见的就是缺少 <img> 标签中的 alt=”…” 属性和 <script> 标签中的 type=”…” 属性。顺便发个牢骚, 阿里妈妈提供的广告代码中竟然有一行 text/javascript 没有加引号……
- end tag for X omitted, but OMITTAG NO was specified:标签没有关闭,也就是前面的第一条中提到的。
- XML Parsing Error,常见的主要有这两种错误:Opening and ending tag mismatch,标签的不合理嵌套;EntityRef: expecting ‘;’,一般都是由于在链接地址中出现了“&”字符,解决办法是把“&”替换为“&”,前面最后一条提到的。
对于中含有 flash 的页面,由于一般都是用 <embed> 或者 <object> 标签,而这两个标签并不是标准的 XHTML 标签,所以就会无法通过验证,解决的办法就是使用 SWFobject 通过 javascript 操作 flash。不过这个办法比较麻烦,我认为不适合对出现在 blog 日志中的 flash 使用,所以如果我的日志中包含有 flash 的话(主要就是视频了),是通过不了验证的,呵呵。
哦,对了,XHTML 验证的地址是:http://validator.w3.org/ ,感兴趣的朋友也可以去验证一下。如果没有通过,千万不要被那几十个甚至几百个错误给吓住了,因为很多错误都是级联产生的,当你解决了一个前面的一个错误之后,也许后面的错误也会消失很多。
一位同学今天找我帮他做一个页面,静态的 html 页面,要求在页面中放入多个 Flash 小游戏的链接和一个游戏区域,通过 Javascript 操作 flash,点击小游戏的链接之后在游戏区域中显示所选的 flash,无需刷新页面实现 flash 的更换。
熟悉 javascript 的朋友都知道,用这种方法操作图片是非常简单的,只需要通过 DOM 修改 img 标签的 src 属性即可实现图片的更换。而我们常见的页面中的 flash 都是使用 object、embed 等标签,这些标签并不是标准的 xhtml 标签,所以不能通过 DOM 来操作。
这个问题把我难住了,于是马上到 google 寻找答案,结果一不小心来到了 aw 的这篇文章:SWFObject:基于Javascript的Flash媒体版本检测与嵌入模块。文章中详细的介绍了 SWFObject,使用它可以方便地在 html 中使用 javascript 插入 flash(.swf文件),方法如下:
1、在 html 中包含 swfobject.js 文件,并为 swf 文件预留一个 html 结点(这个 html 结点内的所有内容都会在客户端被 flash 资源替换,当客户端没有安装 flash播放器的时候,这些内容会显示出来。这一特色在 SEO 以及对用户体验方面非常有必要)。
<script type="text/javascript" src="swfobject.js"></script>
<div id="flashcontent">
This text is replaced by the Flash movie.
</div>
2、在 js 中创建一个新的 SWFObject 实例,设置参数,写入 html 中预留的节点中。
<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100", "7", "#336699");
so.write("flashcontent");
</script>
这6个参数的意义:
- swf - SWF文件路径
- id - 您为这个SWF文件分配的id值,它将用于给embed与object标签设定name属性,以便于可以支持swliveconnect的功能,如动态传入变量
- width - 宽度
- height - 高度
- version - FlashPlayer需要的版本号,它可以详细到 ‘主版本号.小版本号.细节’,例如:”6.0.65″。一般地,我们只需传入主版本即可,例如:”6″。
- background-color - Flash资源的背景色,16进制格式
(以上代码和说明均摘自 aw 的原文,swfobject.js 的下载地址也请参看原文。原文中还有很多细节的东西,由于我基本不懂 flash,而且前面的这些对我已经够用了,所以就不再引用。感兴趣的朋友可以查看原文,感谢 aw 的文章。)
这样就好了,我只需要在链接中把 flash 的文件路径传递给 javascript 即可,这样就可以在一个页面中切换多个 flash 的显示,具体的代码很简单,就不再写了。