<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>小麦的自习教室 &#187; 网页标准</title>
	<atom:link href="http://www.mikkolee.com/c/webstandard/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mikkolee.com</link>
	<description>关于界面的价值观与方法论</description>
	<lastBuildDate>Fri, 02 Jul 2010 10:27:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>选择符的命名原则</title>
		<link>http://www.mikkolee.com/276</link>
		<comments>http://www.mikkolee.com/276#comments</comments>
		<pubDate>Fri, 01 Jan 2010 16:50:39 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=276</guid>
		<description><![CDATA[其实这个主题还蛮无聊的。因为我想来想去，选择符的命名，其实并不是那么重要。况且，对于不同的人，有不同的习惯，我在这里也没法定出什么完美的标准来号召大家都使用。
不过，规划好选择符的命名，还是有几点好处的：
1. 节约时间。不得不承认，我本人经常把10%-20%左右的时间花在斟酌选择符命名上。当然，或许这只是我个人的强迫症问题。
2. 防止冲突。虽然概率很小，但还是会遇得到这种情况：某个选择符的名字，已然被用过了，导致样式冲突。这种情况通常发生在不同尺度的样式：比如登录框和登录页，某个模块里的下拉菜单和导航栏，等等。
3. 防止冗余。其实这点就比较关键啦。如果命名冲突，换个名字就是了。但如果是前后由不同的人来写样式，很可能为了避免冲突而另起炉灶。一方面浪费人力，另一方面久而久之会产生大量被废弃或覆盖的样式：打开firebug，某个样式被不同的人在不同的样式表里覆盖了N次。这就比较糟糕了。
所以，好的命名规划，一定程度上还是比较的。一些关键的命名原则有：
1. 通用的样式，一定要规范好命名。所谓通用的样式，主要有：
&#160;&#160;&#160;&#160;a) 页面布局：比如头部顶部啦，左侧栏右侧栏啦，负责整个页面“骨架”的一些样式。
&#160;&#160;&#160;&#160;b) 常用布局：比如列表，田字格布局（1排5个，一共5排），标签切换（tab），翻页这种经常被网页设计所用的模块布局样式。
&#160;&#160;上面两种，在各处的样式定义可能完全不同，但由于经常用到这些布局结构，所以可以统一命名。
&#160;&#160;&#160;&#160;c) 通用模块：这里指的是一些“固定样式”的模块，会在全站各处出现。比如登录框、搜索框、浮动工具箱等等。
&#160;&#160;&#160;&#160;d) 小尺度的通用样式：比如菜单激活状态，文字高亮之类的。还例如某些同学喜欢用的清除浮动的样式。
   把这几种类型的样式的命名规范好，就能避免很多问题。原因是因为它们通常会在很多页面里被反复使用到，所以是最容易出现冲突和冗余的地方。
2. 页面布局、常用布局以及通用模块的样式，命名要特别。
   比如对于全站导航菜单，我比较喜欢用nav（navigation，即导航）来命名，而不是menu，或是main_menu之类的。原因是，可预见的是，在某些特定的页面内，会出现“菜单”这种元素，比如分类索引页，侧栏可能会出现分类的菜单列表。那如果menu被全站导航占用，到时候就容易出问题。
   同样的问题也出在“登陆框”或是“搜索框”，如果简单的用login或是search，那你到“登录页”或“搜索页”的时候，就又头疼了。我比较习惯的是用login_box和search_box。
   总之呢，一些“自然而然就能想到”的名词，尽量不要用在大尺度或全站通用的样式上，一开始把它们挤占了，就会导致后来的样式命名不得不另想花样，命名的混乱就由此开始。
3. 相反，小尺度的通用样式，命名要通俗简短。
   其实小尺度的通用样式命名，就纯粹是一个“惯例”了。比如激活的菜单，有的人用on，有的人用now，有的人用active。你管不着别人的，只能作为一个惯例推广给团队里其他同事。但不要认为“惯例”就没约束性，如果坚持用同一个名字，到处都用，其实其他同学会潜移默化的也跟着用的。比如土豆网的视频截图模块，几年来一直被称作pack。这就是aether同学最初的发明。
下面稍微列了一下，可能用到的通用样式，后面附的英文是我个人的习惯，可以参考，也可以忽略。
页面布局：
&#160;&#160;-页面头部：header
&#160;&#160;&#160;&#160;-图标：logo
&#160;&#160;&#160;&#160;-右上快捷区域：quicklinks
&#160;&#160;-页面中部：page
&#160;&#160;&#160;&#160;-侧栏：side column
&#160;&#160;&#160;&#160;-主栏：main column
&#160;&#160;&#160;&#160;-第三栏：extra column
&#160;&#160;&#160;&#160;-区块：section
&#160;&#160;&#160;&#160;&#160;&#160;-区块顶部：heading
&#160;&#160;&#160;&#160;&#160;&#160;-区块中部：container
&#160;&#160;&#160;&#160;&#160;&#160;-区块底部：footing
&#160;&#160;-页面底部：footer
&#160;&#160;&#160;&#160;-版权说明：copyright
常用布局：
&#160;&#160;-田字格布局：show case
&#160;&#160;-列表布局：list
&#160;&#160;-标签切换：tab
&#160;&#160;-排行榜：billboard
&#160;&#160;-表单：post form
&#160;&#160;-纯文字区域：text area
&#160;&#160;-翻页：page navigation
通用模块：
&#160;&#160;-导航栏：navigation
&#160;&#160;-登陆框：login box
&#160;&#160;-搜索框：search box
通用样式：
&#160;&#160;-高亮：highlight
&#160;&#160;-激活：active，或者on
&#160;&#160;-清除浮动：fix，或者clear
&#160;&#160;-图：pic
&#160;&#160;-文：txt
自己可以根据具体情况来编写这个命名规范表。比如有些网站可能全站底部有个通用的工具栏（比如facebook），那就可以把tool box放到“通用模块”里。又比如，对于“田字格”布局，有些同学可能习惯每一行用一个框套起来，每一项再用一个框套起来，那就会衍生出“row”和“item”这样的样式，另外的做法是每一行末尾用一个空div隔开，可能需要用的是“line”或者直接就用“clear”。whatever，自己决定。
4. 选择符命名的常用方法有：
&#160;&#160;a) 基于结构的命名：比如头部/底部，主栏/侧栏，菜单列表/菜单项，区块，按钮
&#160;&#160;b) 基于功能的命名：登录框、搜索框、排行榜、翻页、提示（tip)，等等
&#160;&#160;c) 基于内容的命名：今日焦点(focus)、用户排行榜（top users)、评论（comments）、搜索结果（search results），等等
&#160;&#160;d) 基于样式的命名：列表、田字格、tab、高亮、标红或加粗，等等
&#160;&#160;e) 基于状态或行为的命名：激活、拖拽、展开，等等
   我没那么教条，不去从什么“样式和结构分离”的形而上原则来规定该用什么。只是谈谈，如果在未来发生需求变动，怎样的命名会让你尽量少做改动。
   基本上呢，前两种——结构和功能——是最安全的。因为如果结构或功能发生巨大变化，你要做的工作就多着去了，也不在乎这个命名会改动多大了。
   基于内容和样式命名，就比较危险。很可能只是将“今日焦点”改名为“最新话题”，而样式完全不变。或是新增的“分类索引”模块，设计上直接照搬“搜索结果”的排列样式。遇到这种情况，你的命名就尴尬啦。基于样式命名的危险，就更不用说了。
   [...]]]></description>
			<content:encoded><![CDATA[<p>其实这个主题还蛮无聊的。因为我想来想去，选择符的命名，其实并不是那么重要。况且，对于不同的人，有不同的习惯，我在这里也没法定出什么完美的标准来号召大家都使用。</p>
<p>不过，规划好选择符的命名，还是有几点好处的：<br />
1. 节约时间。不得不承认，我本人经常把10%-20%左右的时间花在斟酌选择符命名上。当然，或许这只是我个人的强迫症问题。</p>
<p>2. 防止冲突。虽然概率很小，但还是会遇得到这种情况：某个选择符的名字，已然被用过了，导致样式冲突。这种情况通常发生在不同尺度的样式：比如登录框和登录页，某个模块里的下拉菜单和导航栏，等等。</p>
<p>3. 防止冗余。其实这点就比较关键啦。如果命名冲突，换个名字就是了。但如果是前后由不同的人来写样式，很可能为了避免冲突而另起炉灶。一方面浪费人力，另一方面久而久之会产生大量被废弃或覆盖的样式：打开firebug，某个样式被不同的人在不同的样式表里覆盖了N次。这就比较糟糕了。</p>
<p>所以，好的命名规划，一定程度上还是比较的。一些关键的命名原则有：</p>
<p>1. <strong>通用的样式，一定要规范好命名</strong>。所谓通用的样式，主要有：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;a) 页面布局：比如头部顶部啦，左侧栏右侧栏啦，负责整个页面“骨架”的一些样式。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;b) 常用布局：比如列表，田字格布局（1排5个，一共5排），标签切换（tab），翻页这种经常被网页设计所用的模块布局样式。</p>
<p>&nbsp;&nbsp;上面两种，在各处的样式定义可能完全不同，但由于经常用到这些布局结构，所以可以统一命名。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;c) 通用模块：这里指的是一些“固定样式”的模块，会在全站各处出现。比如登录框、搜索框、浮动工具箱等等。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;d) 小尺度的通用样式：比如菜单激活状态，文字高亮之类的。还例如某些同学喜欢用的清除浮动的样式。<br />
   把这几种类型的样式的命名规范好，就能避免很多问题。原因是因为它们通常会在很多页面里被反复使用到，所以是最容易出现冲突和冗余的地方。</p>
<p>2. <strong>页面布局、常用布局以及通用模块的样式，命名要特别。</strong></p>
<p>   比如对于全站导航菜单，我比较喜欢用nav（navigation，即导航）来命名，而不是menu，或是main_menu之类的。原因是，可预见的是，在某些特定的页面内，会出现“菜单”这种元素，比如分类索引页，侧栏可能会出现分类的菜单列表。那如果menu被全站导航占用，到时候就容易出问题。</p>
<p>   同样的问题也出在“登陆框”或是“搜索框”，如果简单的用login或是search，那你到“登录页”或“搜索页”的时候，就又头疼了。我比较习惯的是用login_box和search_box。</p>
<p>   总之呢，一些“自然而然就能想到”的名词，尽量不要用在大尺度或全站通用的样式上，一开始把它们挤占了，就会导致后来的样式命名不得不另想花样，命名的混乱就由此开始。</p>
<p>3. <strong>相反，小尺度的通用样式，命名要通俗简短</strong>。</p>
<p>   其实小尺度的通用样式命名，就纯粹是一个“惯例”了。比如激活的菜单，有的人用on，有的人用now，有的人用active。你管不着别人的，只能作为一个惯例推广给团队里其他同事。但不要认为“惯例”就没约束性，如果坚持用同一个名字，到处都用，其实其他同学会潜移默化的也跟着用的。比如土豆网的视频截图模块，几年来一直被称作pack。这就是<a href="http://woooh.com/" target="_blank">aether</a>同学最初的发明。</p>
<p>下面稍微列了一下，可能用到的通用样式，后面附的英文是我个人的习惯，可以参考，也可以忽略。</p>
<blockquote><p><strong>页面布局：</strong></p>
<p>&nbsp;&nbsp;-页面头部：header<br />
&nbsp;&nbsp;&nbsp;&nbsp;-图标：logo<br />
&nbsp;&nbsp;&nbsp;&nbsp;-右上快捷区域：quicklinks<br />
&nbsp;&nbsp;-页面中部：page<br />
&nbsp;&nbsp;&nbsp;&nbsp;-侧栏：side column<br />
&nbsp;&nbsp;&nbsp;&nbsp;-主栏：main column<br />
&nbsp;&nbsp;&nbsp;&nbsp;-第三栏：extra column<br />
&nbsp;&nbsp;&nbsp;&nbsp;-区块：section<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-区块顶部：heading<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-区块中部：container<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-区块底部：footing<br />
&nbsp;&nbsp;-页面底部：footer<br />
&nbsp;&nbsp;&nbsp;&nbsp;-版权说明：copyright</p>
<p><strong>常用布局：</strong></p>
<p>&nbsp;&nbsp;-田字格布局：show case<br />
&nbsp;&nbsp;-列表布局：list<br />
&nbsp;&nbsp;-标签切换：tab<br />
&nbsp;&nbsp;-排行榜：billboard<br />
&nbsp;&nbsp;-表单：post form<br />
&nbsp;&nbsp;-纯文字区域：text area<br />
&nbsp;&nbsp;-翻页：page navigation</p>
<p><strong>通用模块：</strong></p>
<p>&nbsp;&nbsp;-导航栏：navigation<br />
&nbsp;&nbsp;-登陆框：login box<br />
&nbsp;&nbsp;-搜索框：search box</p>
<p><strong>通用样式：</strong></p>
<p>&nbsp;&nbsp;-高亮：highlight<br />
&nbsp;&nbsp;-激活：active，或者on<br />
&nbsp;&nbsp;-清除浮动：fix，或者clear<br />
&nbsp;&nbsp;-图：pic<br />
&nbsp;&nbsp;-文：txt</p></blockquote>
<p>自己可以根据具体情况来编写这个命名规范表。比如有些网站可能全站底部有个通用的工具栏（比如facebook），那就可以把tool box放到“通用模块”里。又比如，对于“田字格”布局，有些同学可能习惯每一行用一个框套起来，每一项再用一个框套起来，那就会衍生出“row”和“item”这样的样式，另外的做法是每一行末尾用一个空div隔开，可能需要用的是“line”或者直接就用“clear”。whatever，自己决定。</p>
<p>4. 选择符命名的常用方法有：</p>
<p>&nbsp;&nbsp;a) <strong>基于结构的命名</strong>：比如头部/底部，主栏/侧栏，菜单列表/菜单项，区块，按钮</p>
<p>&nbsp;&nbsp;b) <strong>基于功能的命名</strong>：登录框、搜索框、排行榜、翻页、提示（tip)，等等</p>
<p>&nbsp;&nbsp;c) <strong>基于内容的命名</strong>：今日焦点(focus)、用户排行榜（top users)、评论（comments）、搜索结果（search results），等等</p>
<p>&nbsp;&nbsp;d) <strong>基于样式的命名</strong>：列表、田字格、tab、高亮、标红或加粗，等等</p>
<p>&nbsp;&nbsp;e) <strong>基于状态或行为的命名</strong>：激活、拖拽、展开，等等</p>
<p>   我没那么教条，不去从什么“样式和结构分离”的形而上原则来规定该用什么。只是谈谈，<strong>如果在未来发生需求变动，怎样的命名会让你尽量少做改动</strong>。</p>
<p>   基本上呢，前两种——结构和功能——是最安全的。因为如果结构或功能发生巨大变化，你要做的工作就多着去了，也不在乎这个命名会改动多大了。</p>
<p>   基于内容和样式命名，就比较危险。很可能只是将“今日焦点”改名为“最新话题”，而样式完全不变。或是新增的“分类索引”模块，设计上直接照搬“搜索结果”的排列样式。遇到这种情况，你的命名就尴尬啦。基于样式命名的危险，就更不用说了。</p>
<p>   基于状态或行为来命名，通常发生在两种情况：1. 用作JS的钩子；2. 用作某种状态变化的样式。以我的经验，它们的问题往往不是“改动”，而是“不能改动”。一旦用了，就会一直用下去，除非相应的行为方式发生变化。对此我还没深思熟虑过，但值得提醒的就是，对它们的命名要慎重，而且，最关键的是，要将它们和其他的样式剥离开来。当然，这就不是“命名”的范畴，而是“架构”的范畴，这里就不多讲，以后再说。</p>
<p>   最后还要特别强调的是：不管采用哪种方式命名，最忌讳的是同时基于两种方式。最常见的就是“左侧栏（left column)”，它同时基于样式和结构。还比如“顶部介绍（top intro）”，同时基于样式和内容；“频道下拉框（channel dropbox），同时基于内容和功能。这些命名，在遇到样式变动，或是新增同样式的模块时候，就会陷入尴尬。</p>
<p>5 最后讲一个比较棘手的问题：层叠（Cascading）。写CSS，经常会遇到层叠的情况：</p>
<blockquote><p>&nbsp;&nbsp;&nbsp;&nbsp;搜索<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;搜索关键字<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;搜索提示<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;搜索结果<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 搜索过滤选项</p></blockquote>
<p>  这个例子，其实还好解决：就按照各元素的内容或功能直接命名即可。之所以好解决，是因为这些元素大多是本模块（搜索）所特有的，不大可能重复。但另一种情况就比较麻烦了：表单。我举个例子：</p>
<blockquote><p>&nbsp;&nbsp;&nbsp;&nbsp;登录<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用户名<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;密码</p></blockquote>
<blockquote><p>&nbsp;&nbsp;&nbsp;&nbsp;注册<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用户名<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;密码</p></blockquote>
<p>  类似的例子还有：blog的文章（标题、内容）和留言（标题、内容）。问题的关键在于，它们是不同的模块，包含同样内容或功能的元素。更要命的是，有时候，这些元素的样式是一致的，有时候，又有点小不同，有时候，又是迥然不同。</p>
<p>  对于层叠的情况，有三种命名方式：</p>
<p>&nbsp;&nbsp;a) 模块名和元素名绑成一个名字。比如.comment_title。</p>
<p>&nbsp;&nbsp;b) 只用元素名，只对元素名定义样式。比如.keywords。</p>
<p>&nbsp;&nbsp;c) 也是只用元素名，但是将选择符层叠定义，比如.login .username。</p>
<p>  至于什么情况采用什么方式，完全在于经验。但关键要考虑的因素是：一，在其他模块中是否会出现同样的元素？二，它们在样式上有一致性吗？像“搜索关键字”这种元素，如果断定在其他模块不会有同样的元素，就大胆只用元素名吧。而“登录 用户名”和“注册 用户名”，可推断的是它们的样式有一致性，或许只是一些小不同（比如输入框宽度），那就用选择符层叠定义。而“文章标题”和“留言标题”，很明显它们在样式（甚至结构）上会有很大不同，那最好各取各的名字。</p>
<p>  我个人呢，比较倾向于用a)，即模块名和元素名绑在一起。这样可能会造成一些冗余的样式定义，但即便冗余，也有一个好处：解耦。样式各管各的，不用互相牵扯。只有对于那些特别通用的模块，我才会用c)方式，比如.list .item这样。</p>
<p>呼，这个无聊的主题，居然也洋洋洒洒写了这么多。其中肯定有很多漏洞，毕竟我也不能预见到所有的情况。就当是一个自我总结，供参考吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/276/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>一些想法和一个计划</title>
		<link>http://www.mikkolee.com/270</link>
		<comments>http://www.mikkolee.com/270#comments</comments>
		<pubDate>Mon, 21 Dec 2009 13:54:38 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=270</guid>
		<description><![CDATA[事由Hax写的一篇blog，关于“样式类”的。难得看到他写这种浅显的主题，就认真看了一下。文末他讲了这一句：
“总之，样式类虽然不至于罪大恶极，但还是应该，也可以尽量避免的。”
这句话我同意。但我仍然要对我已经同意——同时也被那芸芸的web标准的信众同意——的话抛出个疑问：为什么要避免样式类？
标准答案自然是“结构样式分离”。所……以，为什么要分离？
话说我们当年被“感召”时，都笃信了这条“结构与样式分离”。很诡异的是，这么多信众中我始终没发现有人能站出来讲一个真正对柴米油盐有意义的理由。我试图回溯了那些曾经“感召”我的词句：
“样式表能够再恰当的地方集中一批命令，以实现某种可视效果，而不是将它们到处分散在整个文档中。比如，假设要让文档中所有的标题都显示为紫色。……然而可能又决定（或许是老板决定）将标题变为暗绿色……那么又得回到前面，修改每一个FONT标签。……”
——Eric A. Meyer《CSS权威指南（第一版）》2000年，第一章
“以前重新设计网站需要几天或者几星期，现在只需要几小时，从而减少成本和避免工作烦恼”
“支持非传统的设备，从无线设备到孩子们想象到的、可以上网的智能手机以及盲人阅读器、屏幕阅读器等残疾人士使用的设备，都不需要再争论开发特殊版本的费用”
——Jeffrey Zeldman 《网站重构》 2004年，第1章
这几句话勾勒出几点很梦幻的好处：
一，原先每处都要一一修改，现在只用改一处就好；
二，一个版本，就可以支持所有的设备；
三，构建模块，重用代码。
OK，题外话，过去的15个月里，我把咱公司的网站的样式表翻了个底朝天：重写了所有页面的CSS。鉴于此，我想我还是有权抛出这样一个观点：这些梦幻般的“好处”，都是非常，非常，非常的微不足道。我们实际工作中面临的问题要比这些复杂得多：
一，原先每处都要一一修改，现在只用改一处就好——如果老板仅仅要求把紫色的字改成绿色的话；
实际的情况是：
1. 老板需要把顶部的登陆框改到左侧栏；
2. 老板需要把一排4个变成一排5个，同时把每个的图尺寸调小；
3. 老板需要让原先的紫色的其中一部分变成绿色，而另一部分变成红色；
4. 老板需要把原来直角的边框改成圆角的。
请问，这种情况下，你样式和结构要分离到什么程度才能保证“一处修改即可”？
二，一个版本，就可以支持所有的设备——如果我们的网站需要支持手机、盲人阅读器、低版本浏览器、未来的浏览器；
而实际情况是：
1. 97%的用户使用IE，其中70%使用IE6，就别提什么未来的浏览器了
2. 我们不在乎盲人是否能打开视频网站的页面
3. 对于手机业务，我们的问题不是要不要另做个页面，而是要不要另开一家公司。
三，构建模块，重用代码——如果我们的页面可以划分成固定不变的模块，同时需要它们的N种组合方式。
而实际的情况是：
1. 只有少数样式是被超过3个页面使用的。
2. 只有极少数样式是在被其他页面使用时，完全不需要做任何适应性改动
3. 很多时候，直接把一段CSS拷贝过去，比多链一个CSS文件要划算得多，无论从性能上还是从开发上讲。
诚然，用现在的情况，来抨击老人家在2000年时宣传CSS时说的话，是很不公平的。但时过境迁，如今CSS应用的如此广泛，我们理应呼唤一些更好的价值观和方法论，来指导我们如何克服在朝圣途中所遇到的阻难和纠结。
好吧，讲了N多废话（或许漏洞百出），是想宣布俺自己的一个计划：把过去15个月的关于CSS各方面的实践经验整理成系列的笔记。因为基本上在接下来一段时间，我不大会有机会如此密集的钻研一项技术了，所以也算是为这一阶段的工作做个交代吧。
既然说出口了，为了防止极可能出现的太监现象，我粗粗的整理了一个提纲。基本上它们不会包含什么具体的实践方法，可能只是一些纯理念。它们未必是最好的实践，也未必百分百正确，能抛砖引玉就好：
1. 选择符命名方法
   我个人是觉得选择符不需要有什么“规范”，尤其是在Firebug之类的工具如此方便的当下。但命名还是需要方法的，好的方法可以达到的目的：一，不用花时间起名字（这个很重要，呵呵）；二，不用怕起名字重复；三，节约字符；四，避免英文不好而丢脸。
2. 大网站的CSS架构
   好的架构可以带来的好处：一，避免冗余的定义；二，避免改动的风险；三，避免冗余的文件夹；四，便于更好的交接和协作。
3. 常用的CSS套路
   这就纯粹是讲个人习惯了，不建议照搬。做了N多网页，就能总结出一些套路，可以很快的搭好架子铺好路，不用每次都要一字一句的从body {margin:0; padding:0 }开始。
4. Sprite技巧
   也不知道sprite会流行多久。这个纯粹是sprite这一狭窄的技术的一些心得，如果你很有远见的认为sprite用不了多久就会被内联图片取代，那就随便看看吧。
5. CSS变更控制与管理
   CSS好写，可改起来就有些头疼了。尤其是对于一些有洁癖的人来说，更是纠结啊纠结。我想试着总结一些经验，包含从最开始如何搭建样式，到预测可能的变更，以及应对的更改方式。
6. 前端与其他工种的协作与沟通
   我之前说过，前端是集结设计与开发的重要环节，与其他工种的同学保持良好的默契与沟通，是优秀前端必备的技能。可能和前端有接洽的工种包括：UI设计、后端开发、产品经理、项目经理、测试、交互设计师、数据分析、SEO，等等。我未必讲得都对，不过我会尽量挑出遇到过的做得好的例子。
哈哈，摊子铺的有点大，我都开始害怕了。anyway，如果迟迟未能完成，或是写出来让大家觉得“也不过如此”，别怪我让你失望，就怪你自己之前期待太高吧（:P）
]]></description>
			<content:encoded><![CDATA[<p>事由<a href="http://hax.javaeye.com" target="_blank">Hax</a>写的<a href="http://hax.javaeye.com/blog/500015" target="_blank">一篇blog</a>，关于“样式类”的。难得看到他写这种浅显的主题，就认真看了一下。文末他讲了这一句：</p>
<blockquote><p>“总之，样式类虽然不至于罪大恶极，但还是应该，也可以尽量避免的。”</p></blockquote>
<p>这句话我同意。但我仍然要对我已经同意——同时也被那芸芸的web标准的信众同意——的话抛出个疑问：为什么要避免样式类？</p>
<p>标准答案自然是“结构样式分离”。所……以，为什么要分离？</p>
<p>话说我们当年被“感召”时，都笃信了这条“结构与样式分离”。很诡异的是，这么多信众中我始终没发现有人能站出来讲一个真正对柴米油盐有意义的理由。我试图回溯了那些曾经“感召”我的词句：</p>
<blockquote><p>“样式表能够再恰当的地方集中一批命令，以实现某种可视效果，而不是将它们到处分散在整个文档中。比如，假设要让文档中所有的标题都显示为紫色。……然而可能又决定（或许是老板决定）将标题变为暗绿色……那么又得回到前面，修改每一个FONT标签。……”</p>
<p>——Eric A. Meyer《CSS权威指南（第一版）》2000年，第一章</p></blockquote>
<blockquote><p>“以前重新设计网站需要几天或者几星期，现在只需要几小时，从而减少成本和避免工作烦恼”</p>
<p>“支持非传统的设备，从无线设备到孩子们想象到的、可以上网的智能手机以及盲人阅读器、屏幕阅读器等残疾人士使用的设备，都不需要再争论开发特殊版本的费用”</p>
<p>——Jeffrey Zeldman 《网站重构》 2004年，第1章</p></blockquote>
<p>这几句话勾勒出几点很梦幻的好处：<br />
一，原先每处都要一一修改，现在只用改一处就好；<br />
二，一个版本，就可以支持所有的设备；<br />
三，构建模块，重用代码。</p>
<p>OK，题外话，过去的15个月里，我把<a href="http://www.tudou.com" target="_blank">咱公司的网站</a>的样式表翻了个底朝天：重写了所有页面的CSS。鉴于此，我想我还是有权抛出这样一个观点：这些梦幻般的“好处”，都是非常，非常，非常的微不足道。我们实际工作中面临的问题要比这些复杂得多：</p>
<p>一，原先每处都要一一修改，现在只用改一处就好——如果老板仅仅要求把紫色的字改成绿色的话；</p>
<p>实际的情况是：<br />
1. 老板需要把顶部的登陆框改到左侧栏；<br />
2. 老板需要把一排4个变成一排5个，同时把每个的图尺寸调小；<br />
3. 老板需要让原先的紫色的其中一部分变成绿色，而另一部分变成红色；<br />
4. 老板需要把原来直角的边框改成圆角的。</p>
<p>请问，这种情况下，你样式和结构要分离到什么程度才能保证“一处修改即可”？</p>
<p>二，一个版本，就可以支持所有的设备——如果我们的网站需要支持手机、盲人阅读器、低版本浏览器、未来的浏览器；</p>
<p>而实际情况是：<br />
1. 97%的用户使用IE，其中70%使用IE6，就别提什么未来的浏览器了<br />
2. 我们不在乎盲人是否能打开视频网站的页面<br />
3. 对于手机业务，我们的问题不是要不要另做个页面，而是要不要另开一家公司。</p>
<p>三，构建模块，重用代码——如果我们的页面可以划分成固定不变的模块，同时需要它们的N种组合方式。</p>
<p>而实际的情况是：<br />
1. 只有少数样式是被超过3个页面使用的。<br />
2. 只有极少数样式是在被其他页面使用时，完全不需要做任何适应性改动<br />
3. 很多时候，直接把一段CSS拷贝过去，比多链一个CSS文件要划算得多，无论从性能上还是从开发上讲。</p>
<p>诚然，用现在的情况，来抨击老人家在2000年时宣传CSS时说的话，是很不公平的。但时过境迁，如今CSS应用的如此广泛，我们理应呼唤一些更好的价值观和方法论，来指导我们如何克服在朝圣途中所遇到的阻难和纠结。</p>
<p>好吧，讲了N多废话（或许漏洞百出），是想宣布俺自己的一个计划：把过去15个月的关于CSS各方面的实践经验整理成系列的笔记。因为基本上在接下来一段时间，我不大会有机会如此密集的钻研一项技术了，所以也算是为这一阶段的工作做个交代吧。</p>
<p>既然说出口了，为了防止极可能出现的太监现象，我粗粗的整理了一个提纲。基本上它们不会包含什么具体的实践方法，可能只是一些纯理念。它们未必是最好的实践，也未必百分百正确，能抛砖引玉就好：</p>
<p><strong>1. 选择符命名方法</strong><br />
   我个人是觉得选择符不需要有什么“规范”，尤其是在Firebug之类的工具如此方便的当下。但命名还是需要方法的，好的方法可以达到的目的：一，不用花时间起名字（这个很重要，呵呵）；二，不用怕起名字重复；三，节约字符；四，避免英文不好而丢脸。</p>
<p><strong>2. 大网站的CSS架构</strong><br />
   好的架构可以带来的好处：一，避免冗余的定义；二，避免改动的风险；三，避免冗余的文件夹；四，便于更好的交接和协作。</p>
<p><strong>3. 常用的CSS套路</strong><br />
   这就纯粹是讲个人习惯了，不建议照搬。做了N多网页，就能总结出一些套路，可以很快的搭好架子铺好路，不用每次都要一字一句的从body {margin:0; padding:0 }开始。</p>
<p><strong>4. Sprite技巧</strong><br />
   也不知道sprite会流行多久。这个纯粹是sprite这一狭窄的技术的一些心得，如果你很有远见的认为sprite用不了多久就会被内联图片取代，那就随便看看吧。</p>
<p><strong>5. CSS变更控制与管理</strong><br />
   CSS好写，可改起来就有些头疼了。尤其是对于一些有洁癖的人来说，更是纠结啊纠结。我想试着总结一些经验，包含从最开始如何搭建样式，到预测可能的变更，以及应对的更改方式。</p>
<p><strong>6. 前端与其他工种的协作与沟通</strong><br />
   我之前说过，前端是集结设计与开发的重要环节，与其他工种的同学保持良好的默契与沟通，是优秀前端必备的技能。可能和前端有接洽的工种包括：UI设计、后端开发、产品经理、项目经理、测试、交互设计师、数据分析、SEO，等等。我未必讲得都对，不过我会尽量挑出遇到过的做得好的例子。</p>
<p>哈哈，摊子铺的有点大，我都开始害怕了。anyway，如果迟迟未能完成，或是写出来让大家觉得“也不过如此”，别怪我让你失望，就怪你自己之前期待太高吧（:P）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/270/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>土豆网新导航</title>
		<link>http://www.mikkolee.com/169</link>
		<comments>http://www.mikkolee.com/169#comments</comments>
		<pubDate>Wed, 27 May 2009 14:09:17 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=169</guid>
		<description><![CDATA[土豆网新导航今天终于成功上线啦!
由于这次充分发挥了变态的优化手段，所以忍不住来炫耀一下：
1. 整个导航的样式图片只有一张：

大小7K的样子。不过如果考虑把LOGO拿掉，就只有大约2K。关于这点，我还在纠结中。
2. 很得意的实现了一个效果：两侧不同的背景自动延伸，见下图：

其实不容易的哦，得动动脑子，关键是要保证几个要点：
a. 两侧背景不同，但都得向外自动延伸
b. 中间的导航部分必须居中
c. 过渡部分的背景位置也要相对于居中模块固定
d. 这点也是最重要的：当把浏览器宽度缩小到比居中模块还小的时候，再将横向滚动条拉到右边，背景仍然会延伸。如果你不能体会，请试试看下面的代码：

&#60;div style=&#34;width: auto; background: red;&#34;&#62;
      &#60;div style=&#34;width: 900px; margin: 0 auto; background: blue;&#34;&#62;
            这是居中模块
    &#60;/div&#62;
&#60;/div&#62;

当窗口小于900时，外面红色的部分就只有窗口宽度那么宽，这样页面拉到右边时会有一段白色。
3. 底部菜单项之间的分割线，是用CSS做的。当然，这个没啥好炫耀的，方法在两年前就有被提到了。正淳同学最后提到说为啥没见人这么用。OK，就试试看像土豆网底部菜单那样居中且宽度根据内容自适应吧。
呃，不过还是得谦虚一下：我现在已经变得很不爱学习了，所以一些新的CSS方法都不了解。很可能我这些雕虫小技也是被流传了好多年的了。反正它们都是我自个儿琢磨出来，如果很火星，就请大家赐教哈。
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tudou.com" target="_blank">土豆网新导航</a>今天终于成功上线啦!<br />
由于这次充分发挥了变态的优化手段，所以忍不住来炫耀一下：</p>
<p>1. 整个导航的样式图片只有一张：<br />
<img src="http://www.mikkolee.com/blog/wp-content/uploads/2009/05/n2.png"  /><br />
大小7K的样子。不过如果考虑把LOGO拿掉，就只有大约2K。关于这点，我还在纠结中。</p>
<p>2. 很得意的实现了一个效果：两侧不同的背景自动延伸，见下图：<br />
<img src="http://www.mikkolee.com/blog/wp-content/uploads/2009/05/e69caae6a087e9a298-1.jpg" alt="" width="500" height="37"  /><br />
其实不容易的哦，得动动脑子，关键是要保证几个要点：<br />
a. 两侧背景不同，但都得向外自动延伸<br />
b. 中间的导航部分必须居中<br />
c. 过渡部分的背景位置也要相对于居中模块固定<br />
d. 这点也是最重要的：当把浏览器宽度缩小到比居中模块还小的时候，再将横向滚动条拉到右边，背景仍然会延伸。如果你不能体会，请试试看下面的代码：</p>
<pre>
&lt;div style=&quot;width: auto; background: red;&quot;&gt;
      &lt;div style=&quot;width: 900px; margin: 0 auto; background: blue;&quot;&gt;
            这是居中模块
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>当窗口小于900时，外面红色的部分就只有窗口宽度那么宽，这样页面拉到右边时会有一段白色。</p>
<p>3. 底部菜单项之间的分割线，是用CSS做的。当然，这个没啥好炫耀的，方法<a href="http://ued.taobao.com/blog/2007/08/12/css-notes/" target="_blank">在两年前就有被提到了</a>。正淳同学最后提到说为啥没见人这么用。OK，就试试看像土豆网底部菜单那样<strong>居中且宽度根据内容自适应</strong>吧。</p>
<p>呃，不过还是得谦虚一下：我现在已经变得很不爱学习了，所以一些新的CSS方法都不了解。很可能我这些雕虫小技也是被流传了好多年的了。反正它们都是我自个儿琢磨出来，如果很火星，就请大家赐教哈。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/169/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>CSS Sprite的新方法</title>
		<link>http://www.mikkolee.com/153</link>
		<comments>http://www.mikkolee.com/153#comments</comments>
		<pubDate>Tue, 14 Apr 2009 14:15:10 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=153</guid>
		<description><![CDATA[最正式的方法就是给一个透明图片加样式：

&#60;img src=&#34;blank.gif&#34; width=&#34;16&#34; height=&#34;16&#34; class=&#34;sprite&#34; /&#62;

但是这样做有一些缺点：
1.  会多一个图片的请求
2.  众所周知的，内联行里的图片和中文字的底端无法对齐。这个问题的解决办法也有，就是用“vertical-align: -2px;” 强行把图片拉下来一截。
第二种方法：

a {
    display: block;
    text-indent: -3000px;
    overflow: hidden;
    width: 20px;
    height: 20px;
    background: url(...);
}

这个方法很不错，唯一的缺点就是它只能用于样式被设为块级的元素。
第三种方法是我自己想出来的，比较山寨，但是挺实用：

&#60;span class=&#34;sprite&#34;&#62;&#38;nbsp;&#38;nbsp;&#60;/span&#62;
.sprite {
    font-family: &#34;Courier New&#34;, Courier, monospace;
   [...]]]></description>
			<content:encoded><![CDATA[<p>最正式的方法就是给一个透明图片加样式：</p>
<pre>
&lt;img src=&quot;blank.gif&quot; width=&quot;16&quot; height=&quot;16&quot; class=&quot;sprite&quot; /&gt;
</pre>
<p>但是这样做有一些缺点：<br />
1.  会多一个图片的请求<br />
2.  众所周知的，内联行里的图片和中文字的底端无法对齐。这个问题的解决办法也有，就是用“vertical-align: -2px;” 强行把图片拉下来一截。</p>
<p>第二种方法：</p>
<pre>
a {
    display: block;
    text-indent: -3000px;
    overflow: hidden;
    width: 20px;
    height: 20px;
    background: url(...);
}
</pre>
<p>这个方法很不错，唯一的缺点就是它只能用于样式被设为块级的元素。</p>
<p>第三种方法是我自己想出来的，比较山寨，但是挺实用：</p>
<pre>
&lt;span class=&quot;sprite&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
.sprite {
    font-family: &quot;Courier New&quot;, Courier, monospace;
    font-size: 12px;
    letter-spacing: -14px;
    padding-left: 50px;
    background: url(...);
}
</pre>
<p>其中padding-left用来调节宽度。</p>
<p>这个方法的好处在于：<br />
1. 没有多余的空白图片<br />
2. 支持inline样式<br />
3. 良好的垂直对齐</p>
<p>但这个山寨方法有很多局限性：<br />
1. 高度的调节很麻烦。不同的浏览器对字体和行高的解析不一致。<br />
2. 可能在不同操作系统中宽度和高度会不一致。（我还没全面测试）</p>
<p>不管怎么样，这至少是一个在某些固定环境中可以尝试的方法。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/153/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>把CSS全部归零</title>
		<link>http://www.mikkolee.com/126</link>
		<comments>http://www.mikkolee.com/126#comments</comments>
		<pubDate>Sat, 07 Mar 2009 04:29:35 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=126</guid>
		<description><![CDATA[我曾经佩服过google ads，它可以再任何网页上出现，而它的样式却不会被寄主网页的CSS给破坏。后来发现它其实是用的iframe，呵呵。
不过倒是引发了我一个思考：如何保证一个区域里的样式不会被外部样式“入侵”。要做到这点其实说难不难，说容易也不太容易。关键是两点：
1. 将该区域里的所有样式全部设为最初的默认值；
2. 保证上面的样式的优先级为最高。
所以呢，下面是一个尚未完善的例子：

#clearAllStyle *,
#clearAllStyle a:hover,
#clearAllStyle a:link,
#clearAllStyle a:visited,
#clearAllStyle a:active  {
&#160;&#160;&#160;&#160;position: static;
&#160;&#160;&#160;&#160;top: auto;
&#160;&#160;&#160;&#160;right: auto;
&#160;&#160;&#160;&#160;bottom: auto;
&#160;&#160;&#160;&#160;left: auto;
&#160;&#160;&#160;&#160;z-index: auto;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;float: none;
&#160;&#160;&#160;&#160;clear: none;
&#160;&#160;&#160;&#160;display: block;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;margin: auto;
&#160;&#160;&#160;&#160;padding: 0;
&#160;&#160;&#160;&#160;border-width: medium;
&#160;&#160;&#160;&#160;border-color: inherit;
&#160;&#160;&#160;&#160;border-style: none;
&#160;&#160;&#160;&#160;width: auto;
&#160;&#160;&#160;&#160;height: auto;
&#160;&#160;&#160;&#160;min-width: 0;
&#160;&#160;&#160;&#160;min-height: 0;
&#160;&#160;&#160;&#160;max-width: none;
&#160;&#160;&#160;&#160;max-height: none;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;color: #000;
&#160;&#160;&#160;&#160;background-attachment: scroll;
&#160;&#160;&#160;&#160;background-color: transparent;
&#160;&#160;&#160;&#160;background-image: none;
&#160;&#160;&#160;&#160;background-position: 0% 0%;
&#160;&#160;&#160;&#160;background-repeat: repeat;
&#160;&#160;&#160;&#160;
&#160;&#160;&#160;&#160;font-size: 12px;
&#160;&#160;&#160;&#160;font-family: sans-serif;
&#160;&#160;&#160;&#160;line-height: normal;
&#160;&#160;&#160;&#160;font-style: normal;
&#160;&#160;&#160;&#160;font-variant: normal;
&#160;&#160;&#160;&#160;font-weight: normal;
&#160;&#160;&#160;&#160;text-align: left;
&#160;&#160;&#160;&#160;text-decoration: none;
&#160;&#160;&#160;&#160;text-indent: 0;
&#160;&#160;&#160;&#160;text-transform: none;
&#160;&#160;&#160;&#160;white-space: normal;
&#160;&#160;&#160;&#160;letter-spacing: normal;
&#160;&#160;&#160;&#160;word-spacing: normal;
&#160;&#160;&#160;&#160;vertical-align: baseline;
&#160;&#160;&#160;&#160;overflow: visible;
&#160;&#160;&#160;&#160;visibility: visible;
}
#clearAllStyle span,
#clearAllStyle [...]]]></description>
			<content:encoded><![CDATA[<p>我曾经佩服过google ads，它可以再任何网页上出现，而它的样式却不会被寄主网页的CSS给破坏。后来发现它其实是用的iframe，呵呵。</p>
<p>不过倒是引发了我一个思考：如何保证一个区域里的样式不会被外部样式“入侵”。要做到这点其实说难不难，说容易也不太容易。关键是两点：</p>
<p>1. 将该区域里的所有样式全部设为最初的默认值；<br />
2. 保证上面的样式的优先级为最高。</p>
<p>所以呢，下面是一个尚未完善的例子：</p>
<pre>
#clearAllStyle *,
#clearAllStyle a:hover,
#clearAllStyle a:link,
#clearAllStyle a:visited,
#clearAllStyle a:active  {
&nbsp;&nbsp;&nbsp;&nbsp;position: static;
&nbsp;&nbsp;&nbsp;&nbsp;top: auto;
&nbsp;&nbsp;&nbsp;&nbsp;right: auto;
&nbsp;&nbsp;&nbsp;&nbsp;bottom: auto;
&nbsp;&nbsp;&nbsp;&nbsp;left: auto;
&nbsp;&nbsp;&nbsp;&nbsp;z-index: auto;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;float: none;
&nbsp;&nbsp;&nbsp;&nbsp;clear: none;
&nbsp;&nbsp;&nbsp;&nbsp;display: block;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;margin: auto;
&nbsp;&nbsp;&nbsp;&nbsp;padding: 0;
&nbsp;&nbsp;&nbsp;&nbsp;border-width: medium;
&nbsp;&nbsp;&nbsp;&nbsp;border-color: inherit;
&nbsp;&nbsp;&nbsp;&nbsp;border-style: none;
&nbsp;&nbsp;&nbsp;&nbsp;width: auto;
&nbsp;&nbsp;&nbsp;&nbsp;height: auto;
&nbsp;&nbsp;&nbsp;&nbsp;min-width: 0;
&nbsp;&nbsp;&nbsp;&nbsp;min-height: 0;
&nbsp;&nbsp;&nbsp;&nbsp;max-width: none;
&nbsp;&nbsp;&nbsp;&nbsp;max-height: none;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;color: #000;
&nbsp;&nbsp;&nbsp;&nbsp;background-attachment: scroll;
&nbsp;&nbsp;&nbsp;&nbsp;background-color: transparent;
&nbsp;&nbsp;&nbsp;&nbsp;background-image: none;
&nbsp;&nbsp;&nbsp;&nbsp;background-position: 0% 0%;
&nbsp;&nbsp;&nbsp;&nbsp;background-repeat: repeat;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;font-size: 12px;
&nbsp;&nbsp;&nbsp;&nbsp;font-family: sans-serif;
&nbsp;&nbsp;&nbsp;&nbsp;line-height: normal;
&nbsp;&nbsp;&nbsp;&nbsp;font-style: normal;
&nbsp;&nbsp;&nbsp;&nbsp;font-variant: normal;
&nbsp;&nbsp;&nbsp;&nbsp;font-weight: normal;
&nbsp;&nbsp;&nbsp;&nbsp;text-align: left;
&nbsp;&nbsp;&nbsp;&nbsp;text-decoration: none;
&nbsp;&nbsp;&nbsp;&nbsp;text-indent: 0;
&nbsp;&nbsp;&nbsp;&nbsp;text-transform: none;
&nbsp;&nbsp;&nbsp;&nbsp;white-space: normal;
&nbsp;&nbsp;&nbsp;&nbsp;letter-spacing: normal;
&nbsp;&nbsp;&nbsp;&nbsp;word-spacing: normal;
&nbsp;&nbsp;&nbsp;&nbsp;vertical-align: baseline;
&nbsp;&nbsp;&nbsp;&nbsp;overflow: visible;
&nbsp;&nbsp;&nbsp;&nbsp;visibility: visible;
}
#clearAllStyle span,
#clearAllStyle em,
#clearAllStyle strong {
&nbsp;&nbsp;&nbsp;&nbsp;display:inline;
}
#clearAllStyle a
#clearAllStyle a:hover,
#clearAllStyle a:link,
#clearAllStyle a:visited,
#clearAllStyle a:active {
&nbsp;&nbsp;&nbsp;&nbsp;display:inline;
&nbsp;&nbsp;&nbsp;&nbsp;text-decoration:underline;
}
</pre>
<p>这个代码还处于待完善的阶段。我没有对其进行全面的测试，不过基本上能够保证绝大多数的情况了。</p>
<p>注意几点：<br />
1. <strong>我这里考虑的是将所有的CSS属性设为默认值，而并不是将所有的HTML标签设为它们默认的样式。</strong>因为其实从实践的角度，每个浏览器里HTML标签的默认样式都是不一致，不可能也没有必要将其回复到默认样式。保证样式不被外部样式入侵，这才是我们的目的。<br />
2. 所谓的“属性的默认值”，是指在没有明确定义某个属性时，这个属性默认呈现出来的那个值。上面的值都是根据《CSS权威指南》里得到的，不过并不是所有的值都有默认值，没有的我就自己加了一个自己想要的那个值。<br />
3. 有一个比较麻烦的问题：某些属性无法被子元素继承，比如text-align。倘若接下来有如下定义：</p>
<pre>
#clearAllStyle .copyright {
    text-align: center;
}
</pre>
<p>对于.copyright的子元素，就会仍然靠左。解决的办法是一个很傻的写法：</p>
<pre>
#clearAllStyle .copyright,
#clearAllStyle .copyright * {
    text-align: center;
}
</pre>
<p>看起来不好看，但是应该没什么大问题。<br />
4. a标签在IE6下，其伪类的定义会被认为是最高优先级，所以需要显式声明。（感谢OoSleePinG指出）<br />
5. 其他还有些元素需要被归为display: inline，比如del。但是，如果我其实不用它，就没必要写了。</p>
<p>如果大家有什么看法，欢迎进一步讨论。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/126/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>作用域链 词法作用域 与闭包（三）</title>
		<link>http://www.mikkolee.com/89</link>
		<comments>http://www.mikkolee.com/89#comments</comments>
		<pubDate>Sun, 15 Feb 2009 06:11:14 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=89</guid>
		<description><![CDATA[在经历了漫长的作用域链、调用对象和词法作用域之后，终于可以讨论闭包了。
对于闭包这个概念，有各种各样的解释。我比较喜欢的是闭包是《Java 理论与实践: 闭包之争》中的定义：可以包含自由（未绑定）变量的代码块；这些变量不是在这个代码块或者任何全局上下文中定义的，而是在定义代码块的环境中定义。
听起来很抽象，但它指出了闭包定义的两个要素：允许自由变量，由定义环境而不是执行环境决定。
先说说自由变量。凡是不是在该代码块中定义的变量就叫做自由变量。如

function g() {return x;}

其中的x并不是在这个函数中定义的，它的值是存储在函数外部的。所以它就是一个自由变量。
那么一个代码块中的自由变量该到哪里去取呢？这个问题即是决定了这个代码块是否属于闭包。闭包定义要求，这个代码块中的自由变量，应该到定义它的环境中取。这也就是说，这个代码块的作用域应该是词法（静态）作用域。
由于同一个代码块，无论被调用多少次，或是在何处调用，它的定义只会在同一个环境中（否则就不能被认为是“同一个代码块”，因为定义环境不同）。闭包要求其自由变量的读取是在定义环境中决定，也就得到它的一个特性：闭包的自由变量永远指向同一处，无论它在何处被调用。
或许这样说，还是有点抽象。我做一个现实中的比喻。我之前为这个blog做模板的时候，需要在本机中装一个PHP+MySQL的环境。这就遇到一个问题：我白天在公司，晚上在家。如果白天做的时候对服务器配置做了一些调整，那么即使把所有的wordpress程序都copy回家，也无法在家接着做。如果把Wordpress程序文件看作是一个函数，它明显是受它的执行环境所影响的。换句话说，Wordpress有一部分“变量”，不是它自身定义的，而是从外部（PHP服务器或MySQL数据库）中得到的。
后来就找到一个很不错的软件，叫Uniform Server。它是一个文件包，里面包含了Apache和MySQL的环境。把它Copy到U盘上之后，点击Start.bat，就会自动在机器上建立一个服务器环境。更关键的是，下班回家时，关掉电脑，拔出移动硬盘带回家，在家里的电脑重新启动它，它就又可以在家里的电脑上重新建立一个服务器环境，而这个环境跟办公室电脑里一模一样，之前在公司作的改动，回到家里后还存在。
所以呢，可以认为这个Uniform Server就是一个闭包。它的变量（服务器配置）是在它被定义（也就是当我解压到U盘上）的时候就确定了的，而跟它在什么地方被调用执行（开启这个软件）无关。
其实从这个比喻中也可以看出，闭包的好处：作用域始终保持一样，不用担心执行环境不同导致的作用域不同。
最后举一个很简单的例子，来帮助理解闭包（我这里用jquery的写法，以简化代码）：

var t = $('input#text').val()     //取得文本框的值t
$('input#btn').click(function() {
     doSth(t);                 //把t传给某个函数
   //... 其他操作
});

这个例子稍微有点怪怪的，因为它的文本框的值是在绑定点击事件之前去取，而不是在点击的时候。我们姑且就把它当作是因为某些特殊的要求不得不这样做吧。所以呢，绑定到点击事件上的那个匿名函数中，t其实使用的是它上一层作用域里的变量t。
这个时候呢，需求有点改变：要求在点击按钮之后，先弹出来一个对话框，和用户进行某些交互（比如要求登录），之后再按原来的步骤继续。为了通用性，我们需要建一个函数：

function openDialog(f) {
     // ... 对话框要作的一些操作
   f() [...]]]></description>
			<content:encoded><![CDATA[<p>在经历了漫长的作用域链、调用对象和词法作用域之后，终于可以讨论闭包了。</p>
<p>对于闭包这个概念，有各种各样的解释。我比较喜欢的是闭包是《<a href="http://www.ibm.com/developerworks/cn/java/j-jtp04247.html">Java 理论与实践: 闭包之争</a>》中的定义：<strong>可以包含自由（未绑定）变量的代码块；这些变量不是在这个代码块或者任何全局上下文中定义的，而是在定义代码块的环境中定义。</strong></p>
<p>听起来很抽象，但它指出了闭包定义的两个要素：允许自由变量，由定义环境而不是执行环境决定。</p>
<p>先说说自由变量。凡是不是在该代码块中定义的变量就叫做自由变量。如</p>
<pre>
function g() {return x;}
</pre>
<p>其中的x并不是在这个函数中定义的，它的值是存储在函数外部的。所以它就是一个自由变量。</p>
<p>那么一个代码块中的自由变量该到哪里去取呢？这个问题即是决定了这个代码块是否属于闭包。闭包定义要求，这个代码块中的自由变量，应该到定义它的环境中取。这也就是说，这个代码块的作用域应该是词法（静态）作用域。</p>
<p>由于同一个代码块，无论被调用多少次，或是在何处调用，它的定义只会在同一个环境中（否则就不能被认为是“同一个代码块”，因为定义环境不同）。闭包要求其自由变量的读取是在定义环境中决定，也就得到它的一个特性：闭包的自由变量永远指向同一处，无论它在何处被调用。</p>
<p>或许这样说，还是有点抽象。我做一个现实中的比喻。我之前为这个blog做模板的时候，需要在本机中装一个PHP+MySQL的环境。这就遇到一个问题：我白天在公司，晚上在家。如果白天做的时候对服务器配置做了一些调整，那么即使把所有的wordpress程序都copy回家，也无法在家接着做。如果把Wordpress程序文件看作是一个函数，它明显是受它的执行环境所影响的。换句话说，Wordpress有一部分“变量”，不是它自身定义的，而是从外部（PHP服务器或MySQL数据库）中得到的。</p>
<p>后来就找到一个很不错的软件，叫<a href="http://www.uniformserver.com/">Uniform Server</a>。它是一个文件包，里面包含了Apache和MySQL的环境。把它Copy到U盘上之后，点击Start.bat，就会自动在机器上建立一个服务器环境。更关键的是，下班回家时，关掉电脑，拔出移动硬盘带回家，在家里的电脑重新启动它，它就又可以在家里的电脑上重新建立一个服务器环境，而这个环境跟办公室电脑里一模一样，之前在公司作的改动，回到家里后还存在。</p>
<p>所以呢，可以认为这个Uniform Server就是一个闭包。它的变量（服务器配置）是在它被定义（也就是当我解压到U盘上）的时候就确定了的，而跟它在什么地方被调用执行（开启这个软件）无关。</p>
<p>其实从这个比喻中也可以看出，闭包的好处：作用域始终保持一样，不用担心执行环境不同导致的作用域不同。</p>
<p>最后举一个很简单的例子，来帮助理解闭包（我这里用jquery的写法，以简化代码）：</p>
<pre>
var t = $('input#text').val()     //取得文本框的值t
$('input#btn').click(function() {
     doSth(t);                 //把t传给某个函数
   //... 其他操作
});
</pre>
<p>这个例子稍微有点怪怪的，因为它的文本框的值是在绑定点击事件之前去取，而不是在点击的时候。我们姑且就把它当作是因为某些特殊的要求不得不这样做吧。所以呢，绑定到点击事件上的那个匿名函数中，t其实使用的是它上一层作用域里的变量t。</p>
<p>这个时候呢，需求有点改变：要求在点击按钮之后，先弹出来一个对话框，和用户进行某些交互（比如要求登录），之后再按原来的步骤继续。为了通用性，我们需要建一个函数：</p>
<pre>
function openDialog(f) {
     // ... 对话框要作的一些操作
   f()                 //再执行后续的操作
}
</pre>
<p>这里的openDialog函数是打开一个通用的对话框，完成对话框的操作之后呢，再执行后续操作。这里的后续操作可以是一个函数，通过f变量传进openDialog里，让它来决定什么时候调用。</p>
<p>而之前的第一段代码就可以改为：</p>
<pre>
var t = $('input#text').val()     //取得文本框的值t
$('input#btn').click(function() {
     function f() {
         doSth(t);
       //... 其他操作
   }
    openDialog(f);
});
</pre>
<p>和第一段代码比较一下，我们只是简单的把原先的代码用一个函数装起来，然后传给openDialog，就搞定啦。</p>
<p>可能有人会觉得，这个本来就是自然而然的事情啊。其实这里面的关键在于，doSth(t);以及其他语句的执行，已经由原来的点击事件的地方，换到openDialog函数里去了，而后者的代码却是写在不知道什么地方的。之所以可以“自然而然”的随便把代码到处“扔”，就是因为闭包的特性（再想想我那个U盘）。</p>
<p>事实上，如果有兴趣，再仔细琢磨一下jquery的那个click函数，会发现，其实它也是因为有闭包，所以才可以把那个匿名函数扔进去（click函数本身的定义和执行，也是在遥远的未知的地方），从而实现绑定点击事件。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/89/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于JS变量声明的小细节</title>
		<link>http://www.mikkolee.com/120</link>
		<comments>http://www.mikkolee.com/120#comments</comments>
		<pubDate>Fri, 09 Jan 2009 16:36:34 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=120</guid>
		<description><![CDATA[对于从未声明过的对象，如果尝试给它赋值，会隐式的将它声明为全局对象。比如：

(function() {
  s = 'abc';
})();
alert(s); //会弹出 abc

如果尝试读一个未声明的对象，JS会报错。比如：

alert(a); //不会弹出对话框，会报错

这个结论是犀牛书中所写。但是有意思的是，在IE里，如果尝试读一个未声明的对象，并不会报错，当然也不会继续执行JS。这点其实挺要命，不执行也不告诉你为什么。
但这个结论是铁律，所以如下的写法是经常容易犯的错误：

if(!a) {
    //do sth. ...
}

这样写有时候的初衷是：如果变量a不存在，就执行里面的语句。但如果a未定义，在Firefox中会报错；在IE里不会报错，但也不会执行以后的所有语句。
所以该如何探测一个变量是否被定义呢？一个巧妙的办法是：

if(!window.a) {
    //do sth. ...
}

这个方法其实很奇妙，因为读一个未声明的变量，会报错；但读一个未声明的属性，就不会报错。天晓得JS为啥规定这样奇怪的语法。
但是这样的方法只适用与全局变量。若是某个函数里的局部变量，还是用typeof去判断吧：

if(typeof a == 'undefined') {
    //do sth. ...
}

所以，结论就是，养成习惯，不要在变量未定义之前使用它。
接下来再看一个例子：

var a = &#34;I'm out&#34;;
(function() {
    alert(a);
    var a = &#34;I'm in&#34;;
})();

好，提问，运行这段代码，会弹出什么文字？
回答一：弹出“I&#8217;m out”。错。JS没有块级作用域，无论var语句在何处，在整个函数体内它都是有定义的。
回答二：弹出“I&#8217;m in”。错。请再重新看上面那句话，它只是在整个函数体内有定义，但只有在被赋值之后才会有值。
正确答案是：“undefined”。是不是很晕？自己试试看吧。
总之，再重复一遍之前的结论：不要在变量未定义之前使用它。
最后介绍一个我也搞不明白的问题：
在HTML文档里写上这段代码：

&#60;script type=&#34;text/javascript&#34;&#62;
&#160;&#160;&#160;&#160;window['a'] = 'Hi';
&#60;/script&#62;
&#60;script [...]]]></description>
			<content:encoded><![CDATA[<p>对于从未声明过的对象，如果尝试给它赋值，会隐式的将它声明为全局对象。比如：</p>
<pre>
(function() {
  s = 'abc';
})();
alert(s); //会弹出 abc
</pre>
<p>如果尝试读一个未声明的对象，JS会报错。比如：</p>
<pre>
alert(a); //不会弹出对话框，会报错
</pre>
<p>这个结论是犀牛书中所写。但是有意思的是，在IE里，如果尝试读一个未声明的对象，并不会报错，当然也不会继续执行JS。这点其实挺要命，不执行也不告诉你为什么。</p>
<p>但这个结论是铁律，所以如下的写法是经常容易犯的错误：</p>
<pre>
if(!a) {
    //do sth. ...
}
</pre>
<p>这样写有时候的初衷是：如果变量a不存在，就执行里面的语句。但如果a未定义，在Firefox中会报错；在IE里不会报错，但也不会执行以后的<strong>所有</strong>语句。</p>
<p>所以该如何探测一个变量是否被定义呢？一个巧妙的办法是：</p>
<pre>
if(!window.a) {
    //do sth. ...
}
</pre>
<p>这个方法其实很奇妙，因为读一个未声明的变量，会报错；但读一个未声明的属性，就不会报错。天晓得JS为啥规定这样奇怪的语法。</p>
<p>但是这样的方法只适用与全局变量。若是某个函数里的局部变量，还是用typeof去判断吧：</p>
<pre>
if(typeof a == 'undefined') {
    //do sth. ...
}
</pre>
<p>所以，结论就是，养成习惯，<strong>不要在变量未定义之前使用它</strong>。</p>
<p>接下来再看一个例子：</p>
<pre>
var a = &quot;I'm out&quot;;
(function() {
    alert(a);
    var a = &quot;I'm in&quot;;
})();
</pre>
<p>好，提问，运行这段代码，会弹出什么文字？</p>
<p>回答一：弹出“I&#8217;m out”。错。JS没有块级作用域，无论var语句在何处，在整个函数体内它都是有定义的。</p>
<p>回答二：弹出“I&#8217;m in”。错。请再重新看上面那句话，它只是在整个函数体内有定义，但只有在被赋值之后才会有值。</p>
<p>正确答案是：“undefined”。是不是很晕？自己试试看吧。</p>
<p>总之，再重复一遍之前的结论：<strong>不要在变量未定义之前使用它</strong>。</p>
<p>最后介绍一个我也搞不明白的问题：</p>
<p>在HTML文档里写上这段代码：</p>
<pre>
&lt;script type=&quot;text/javascript&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;window['a'] = 'Hi';
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;out.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;alert(a);
&lt;/script&gt;
</pre>
<p>然后在out.js里写上这句：</p>
<pre>
 if(false) {
&nbsp;&nbsp;&nbsp;&nbsp; var a = 'Hello';
 }
</pre>
<p>然后用FF和IE6分别运行，看看你得到什么。</p>
<p>在FF里会弹出“Hi”，但是在IE6中，会得到“undefined”。</p>
<p>很神奇吧？按语法，无论如何，a都不可能是undefined。但是IE6里就会。</p>
<p>如果把两个语句都写在同一个文件里，就不会有这个情况。<br />
如果把out.js里改成window.a，或者把前一个改成var a，也不会有这个情况。<br />
如果把out.js里的var a移到if语句之外，或是把if的条件改为true，也不会有这个情况。</p>
<p>这个bug其实危害性很大。所以呢，只能给自己定一个好习惯，那就是<strong>不要在条件语句中声明变量</strong>，虽然这么做，语法上并不禁止。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/120/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>全局字体最佳实践</title>
		<link>http://www.mikkolee.com/118</link>
		<comments>http://www.mikkolee.com/118#comments</comments>
		<pubDate>Sun, 28 Dec 2008 08:14:07 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=118</guid>
		<description><![CDATA[
body {font-family: Arial, sans-serif; }

这是我迄今发现的最好的全局字体解决方案。当然，所谓“最好”，也只是基于我个人的评判标准。所以我还是得分析一下其他的写法有什么缺点，最后再总结这个写法的特点。

body {font-family: &#34;宋体&#34;, sans-serif; }

这个写法可能的缺点在于：
  1. 宋体在Safari和Vista的IE 7下，看起来很难看。（我稍后把截图补上）
  2. 宋体的英文字很难看。
  3. 如果在CSS里写中文，你得小心你HTML和CSS的编码是否一致。

body {font-family: SimSun,sans-serif; }

这样写，可以避免上面的第三个问题。但是宋体本身确实很难看。我们希望在不同平台下，都用各自默认的字体。XP是宋体，Vista是微软雅黑，Mac是黑体。这样的话，只能将字体的第一个设置为英文字体，这样遇到中文的时候，浏览器会自动调用默认字体（Vista IE 7的一些版本里貌似默认还是宋体，这个我就无能为力了，交给用户设置的自主权吧）

body {font-family: Tahoma, sans-serif; }

这是一个不错的解决办法。Tahoma其实是一个挺漂亮的字体（我同事喜欢称它“大河马”，哈哈）。但是它其实会带来一些问题：
    1. 由Tahoma显示的中文，在IE 6里，下划线会紧紧的贴住中文字，很难看。
    2. IE 6下，Tahoma无法正确的设定为13px。它会跟14px一样大。但是其他浏览器没有这个问题。
    3. 如果一行里同时出现中文和英文，且这一行里有元素被定义了vertical-align属性，在IE 6、7里会导致文字高低不齐，甚至下划线错位。

body {font-family: Arial, ans-serif; }

上述两个问题，Arial都没有。但是Arial也有缺点：
    1. 比Tahoma难看。
 [...]]]></description>
			<content:encoded><![CDATA[<pre>
body {font-family: Arial, sans-serif; }
</pre>
<p>这是我迄今发现的最好的全局字体解决方案。当然，所谓“最好”，也只是基于我个人的评判标准。所以我还是得分析一下其他的写法有什么缺点，最后再总结这个写法的特点。</p>
<pre>
body {font-family: &quot;宋体&quot;, sans-serif; }
</pre>
<p>这个写法可能的缺点在于：<br />
  1. 宋体在Safari和Vista的IE 7下，看起来很难看。（我稍后把截图补上）<br />
  2. 宋体的英文字很难看。<br />
  3. 如果在CSS里写中文，你得小心你HTML和CSS的编码是否一致。</p>
<pre>
body {font-family: SimSun,sans-serif; }
</pre>
<p>这样写，可以避免上面的第三个问题。但是宋体本身确实很难看。我们希望在不同平台下，都用各自默认的字体。XP是宋体，Vista是微软雅黑，Mac是黑体。这样的话，只能将字体的第一个设置为英文字体，这样遇到中文的时候，浏览器会自动调用默认字体（Vista IE 7的一些版本里貌似默认还是宋体，这个我就无能为力了，交给用户设置的自主权吧）</p>
<pre>
body {font-family: Tahoma, sans-serif; }
</pre>
<p>这是一个不错的解决办法。Tahoma其实是一个挺漂亮的字体（我同事喜欢称它“大河马”，哈哈）。但是它其实会带来一些问题：<br />
    1. 由Tahoma显示的中文，在IE 6里，下划线会紧紧的贴住中文字，很难看。<br />
    2. IE 6下，Tahoma无法正确的设定为13px。它会跟14px一样大。但是其他浏览器没有这个问题。<br />
    3. 如果一行里同时出现中文和英文，且这一行里有元素被定义了<code>vertical-align</code>属性，在IE 6、7里会导致文字高低不齐，甚至下划线错位。</p>
<pre>
body {font-family: Arial, ans-serif; }
</pre>
<p>上述两个问题，Arial都没有。但是Arial也有缺点：<br />
    1. 比Tahoma难看。<br />
    2. Tahoma里的第三个问题也同样存在。<br />
不过，这个bug是有个解决办法的，就是将这一行定义<code>zoom:1</code>。</p>
<p>所以，如果不嫌难看，定义为Arial是最合适的。如果实在不喜欢，可以将全局定义为Tahoma，然后再将有下划线的（如链接）文字定义为Arial，至少可以缓解一下。</p>
<p>最后，对于全局字体，补充一点：IE里，所有的表单元素都不继承body的字体属性，需要单独设置：</p>
<pre>
input, label, select, option, textarea, button, fieldset, legend {
    font-family:Tahoma,sans-serif;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/118/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>CSS选择符命名原则</title>
		<link>http://www.mikkolee.com/111</link>
		<comments>http://www.mikkolee.com/111#comments</comments>
		<pubDate>Fri, 19 Dec 2008 17:16:30 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=111</guid>
		<description><![CDATA[坦率的说，我写CSS时，有至少1/4的时间是在纠结选择符该如何命名。随意的命名，会让你陷入尴尬。
举个例子，我们需要在一段文字里将某些词标红。所以为此建了一个.red { color: red; }。结果产品经理觉得，红色太刺眼了，改成橘色比较好吧。这下头大啦，难道写成.red { color: orange; }么？要不然就是把HTML里的每个class="red"改成class="orange"？
在过去几年时间里，我经常遇到这样的尴尬。因此作为一些经验之谈，我整理出以下的几个命名原则：
原则一：CSS选择符命名应该体现结构而不是样式。
这句话听起来很奇怪。这样不是违反了结构和样式分离的原则么？恰恰相反，其实正是遵循分离原则。要知道，CSS选择符名真正的用处是在HTML代码里修饰标签。所以它其实应该被看作结构的一部分。因此选择符的名字不可以跟样式有关。
我开头将的那个例子，就是违反这一原则典型。正确的写法，应该是.highlight { color: red; }，或者索性就用em { color: red; font-style:normal; }。
同理，我尽量避免用带有left、right、颜色、bold等字眼的名字，总而言之，那些可以被作为CSS属性值的名字，都尽量少用作名字。
有时候，我们会遇到另一种情况。有一个很常见的布局：标题放在区块的左上方，而右上方是一个“查看更多”的链接。所以我们会用这样的代码

&#60;h2&#62;
    &#60;span&#62;&#60;a href=&#34;#&#34;&#62;查看更多&#60;/a&#62;&#60;/span&#62;
    精彩贴图
&#60;/h2&#62;

自然，会有相应的样式：

h2 span {float:right;}

但是这样做其实很危险。如果我们要求给标题后再加一个副标题（比如“超过1000万精美图片”之类的恶俗标语），就没法再用span了。用strong或是em，其实感觉怪怪的。
原则二：不要轻易将特殊样式直接赋给常用的HTML标签
上面那个例子的问题就在于，轻易的将样式应用在span这种常用的标签上了。h2 span这种选择符，意味着你认为h2里所有的span都要使用右浮动。但是这样的判断显然是很武断的。
另一个例子是，喜欢用ul.top10 li这种选择符。这样用并非不可，但请先确保这个排行榜里只是纯文字。倘若有一天产品经理发现，似乎应该把前三个的信息写得更详细，就意味着你可能需要用到下面这种结构：

&#60;ul class=&#34;top&#34;&#62;
    &#60;li&#62;
         &#60;div class=&#34;product&#34;&#62;
          [...]]]></description>
			<content:encoded><![CDATA[<p>坦率的说，我写CSS时，有至少1/4的时间是在纠结选择符该如何命名。随意的命名，会让你陷入尴尬。</p>
<p>举个例子，我们需要在一段文字里将某些词标红。所以为此建了一个<code>.red { color: red; }</code>。结果产品经理觉得，红色太刺眼了，改成橘色比较好吧。这下头大啦，难道写成<code>.red { color: orange; }</code>么？要不然就是把HTML里的每个<code>class="red"</code>改成<code>class="orange"</code>？</p>
<p>在过去几年时间里，我经常遇到这样的尴尬。因此作为一些经验之谈，我整理出以下的几个命名原则：</p>
<p><strong>原则一：CSS选择符命名应该体现结构而不是样式。</strong></p>
<p>这句话听起来很奇怪。这样不是违反了结构和样式分离的原则么？恰恰相反，其实正是遵循分离原则。要知道，CSS选择符名真正的用处是在HTML代码里修饰标签。所以它其实应该被看作结构的一部分。因此选择符的名字不可以跟样式有关。</p>
<p>我开头将的那个例子，就是违反这一原则典型。正确的写法，应该是<code>.highlight { color: red; }</code>，或者索性就用<code>em { color: red; font-style:normal; }</code>。</p>
<p>同理，我尽量避免用带有left、right、颜色、bold等字眼的名字，总而言之，那些可以被作为CSS属性值的名字，都尽量少用作名字。</p>
<p>有时候，我们会遇到另一种情况。有一个很常见的布局：标题放在区块的左上方，而右上方是一个“查看更多”的链接。所以我们会用这样的代码</p>
<pre>
&lt;h2&gt;
    &lt;span&gt;&lt;a href=&quot;#&quot;&gt;查看更多&lt;/a&gt;&lt;/span&gt;
    精彩贴图
&lt;/h2&gt;
</pre>
<p>自然，会有相应的样式：</p>
<pre>
h2 span {float:right;}
</pre>
<p>但是这样做其实很危险。如果我们要求给标题后再加一个副标题（比如“超过1000万精美图片”之类的恶俗标语），就没法再用span了。用strong或是em，其实感觉怪怪的。</p>
<p><strong>原则二：不要轻易将特殊样式直接赋给常用的HTML标签</strong></p>
<p>上面那个例子的问题就在于，轻易的将样式应用在span这种常用的标签上了。h2 span这种选择符，意味着你认为h2里所有的span都要使用右浮动。但是这样的判断显然是很武断的。</p>
<p>另一个例子是，喜欢用ul.top10 li这种选择符。这样用并非不可，但请先确保这个排行榜里只是纯文字。倘若有一天产品经理发现，似乎应该把前三个的信息写得更详细，就意味着你可能需要用到下面这种结构：</p>
<pre>
&lt;ul class=&quot;top&quot;&gt;
    &lt;li&gt;
         &lt;div class=&quot;product&quot;&gt;
            &lt;h6&gt;产品名称&lt;/h6&gt;
            &lt;ul&gt;
                  &lt;li&gt;型号：XXX&lt;/li&gt;
                  ...
            &lt;/ul&gt;
         &lt;div&gt;
    &lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>这下又傻眼了吧。只能用.top20 .product li {}去覆盖掉之前的样式。</p>
<p>我比较倾向的写法，是如 ul.top20 li.item这样写。（当然，CSS2准备了更多更精准的后代选择器，就犯不着这个了。等待IE8吧~~）</p>
<p><strong>原则三：设计好一系列的“全局保留字”，以避免命名冲突</strong></p>
<p>一些常用的单词，就不要用作特殊样式的名字。比如，我们会经常用到如下的选择符：</p>
<pre>
.tab li.current
</pre>
<p>或者</p>
<pre>
.nav li.current
</pre>
<p>以表示当前激活的标签或选项。很多样式都会用到“current”这个单词，为了避免彼此的样式冲突，有一个很简单的办法，就是人为商定，单纯的.current样式不作任何定义。换句话说，current这个名字只能出现在精确的后代选择符中。</p>
<p>类似的还有：<br />
“.active”：和current差不多，有人也喜欢用这个<br />
“.first”：经常在如“ 选项 | 选项 | 选项”的结构中用到<br />
“.last”：在田字格布局中可能会用到<br />
“.hover”：有时候需要用这个样式结合JS实现一些效果<br />
“.text”、“.button”、“.submit”等：在属性选择器普及前，input标签的样式都靠它们了。</p>
<p><strong>原则四：英文要正确</strong><br />
哎，这只能怪计算机是美国人发明的了。有时候会看到一些奇怪的选择符名。我解释一些常用单词的含义：</p>
<p><strong>header，footer</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;这两个的意思是指“头部”和“底部”，更确切点讲是“页头”和“页尾”。</p>
<p><strong>heading，footing</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;heading的意思是“标题、题目”，&lt;h1&gt;的h就是heading的缩写。<br />
&nbsp;&nbsp;&nbsp;&nbsp;footing的意思是“注脚”。</p>
<p>所以呢，我的看法是，整个页面的顶部和底部用header和footer，而区块的标题和底部用heading和footing。</p>
<p><strong>caption</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;这个词的意思也是“标题”，但是它特指“图片的文字说明”。所以记得用在图片底部的文字。</p>
<p><strong>primary，secondary</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;这两个词是“首要”“次要”。它们往往是指同级别的事物，只是重要性不同。比如提交按钮和取消按钮。</p>
<p><strong>main，sub</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;这两个词才是上下级关系。如“主菜单”和“子菜单”。</p>
<p><strong>top，middle，bottom</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;这里主要是“中”这个词。“上中下”里的“中”是用middle。参见text-align属性。</p>
<p><strong>left，center，right</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;“左中右”的“中”是center。参见vertical-align。</p>
<p>此外，还有一些常用的词语：</p>
<p>rating：打分<br />
rank：“第几位”<br />
showcase：展示橱窗，可以用作一行五个这种排布。<br />
category：分类<br />
thumbnail：缩略图<br />
snapshot：截图。这个单词的意思是“快照”，所以一般指原大小。<br />
breadcrumbs、pathway：这两个都可以用来指这个东西：“首页 > 二级页面 > 内容页”<br />
quicklinks：这个可以用作页面右上角的“ 登录 | 帮助 | 客服 ”，也可以指页面底部的“ 关于我们 | 网站地图 ”<br />
tip：提示。可以用作输入框旁边的文字，或是弹出的提示框。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/111/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>我最近的CSS习惯</title>
		<link>http://www.mikkolee.com/109</link>
		<comments>http://www.mikkolee.com/109#comments</comments>
		<pubDate>Sun, 14 Dec 2008 06:52:40 +0000</pubDate>
		<dc:creator>小麦</dc:creator>
				<category><![CDATA[网页标准]]></category>

		<guid isPermaLink="false">http://www.mikkolee.com/?p=109</guid>
		<description><![CDATA[之前有要求我多写点CSS方面的，那就写吧。因为习惯其实是会变的，所以只能写“最近”的。这些习惯都跟技术无关，如果不遵守，也不会出错。但是我觉得良好的习惯会体现一个人的素质。
1. 用class_name方式写类名。以前喜欢用class-name写，不过好像两样也没什么差别。但我比较反对用className写类名，因为始终对浏览器大小写敏感的问题抱有怀疑态度。但是id我会写成驼峰式，理由见下一条。
2.样式都用class而不用id。有三个理由，一，id不可以重复，所以用class的话，可以肆无忌惮的用无数次。二，id的优先级太高，若是写了一个#page_content a {color:#f60} ，那你完蛋了，里面要改链接颜色，都必须加上#page_content才能越过这个优先级。三，id专门留给JS用，这样才符合表现与行为分离的原则。所以id我用驼峰式，也是为了体现这一点。
3.margin和padding，尽量省略最后一个值。比如margin: 20px 10px 5px 10px; ，左右值是一样的，就应该省略掉最后一个值，写成margin: 20px 10px 5px; 这样到时候要改左右间距，改一个就好，免得改漏了。其实这个问题虽然很细小，但是可以看得出对margin四个值省略规则的熟练程度。
4.按标准写CSS,再针对特定浏览器作hack。比如，通常我们会遇到如下的写法：

.side_col {
    float:left;
    display: inline;
    margin-left: 20px;
}

而我的写法会是：

.side_col {
    float: left;
    margin-left: 20px;
}
*   .side_col {
    _display:inline;  /*hacked for IE 6*/
}

看明白了么？不应该把hack混在一起，也不应该用一种侥幸的心态，觉得float:left与display:inline写在一起没事。嗯，它们俩确实没事儿，但是其他的hack就不一定了。而且这里写display:inline纯粹就是为了解决IE6的bug，所以前面加上下划线，以明确的表达你的目的。
另外不要以为凡是hack都是为IE准备的。其实有些hack是针对其他浏览器的，比如FF。这就要求你对CSS标准的熟练掌握，能够自信的判断哪些渲染是遵守标准，哪些违反标准的。
此外，我喜欢在hack前面加上星号，其实这纯粹是个人习惯了。可能过段时间我就不这么用了，呵呵。
5. 记得加空格。.class_name { [...]]]></description>
			<content:encoded><![CDATA[<p>之前有要求我多写点CSS方面的，那就写吧。因为习惯其实是会变的，所以只能写“最近”的。这些习惯都跟技术无关，如果不遵守，也不会出错。但是我觉得良好的习惯会体现一个人的素质。</p>
<p>1. <strong>用<code>class_name</code>方式写类名。</strong>以前喜欢用<code>class-name</code>写，不过好像两样也没什么差别。但我比较反对用<code>className</code>写类名，因为始终对浏览器大小写敏感的问题抱有怀疑态度。但是id我会写成驼峰式，理由见下一条。</p>
<p>2.<strong>样式都用class而不用id。</strong>有三个理由，一，id不可以重复，所以用class的话，可以肆无忌惮的用无数次。二，id的优先级太高，若是写了一个<code>#page_content a {color:#f60}</code> ，那你完蛋了，里面要改链接颜色，都必须加上<code>#page_content</code>才能越过这个优先级。三，id专门留给JS用，这样才符合表现与行为分离的原则。所以id我用驼峰式，也是为了体现这一点。</p>
<p>3.<strong>margin和padding，尽量省略最后一个值。</strong>比如<code>margin: 20px 10px 5px 10px;</code> ，左右值是一样的，就应该省略掉最后一个值，写成<code>margin: 20px 10px 5px; </code>这样到时候要改左右间距，改一个就好，免得改漏了。其实这个问题虽然很细小，但是可以看得出对margin四个值省略规则的熟练程度。</p>
<p>4.<strong>按标准写CSS,再针对特定浏览器作hack。</strong>比如，通常我们会遇到如下的写法：</p>
<pre>
.side_col {
    float:left;
    display: inline;
    margin-left: 20px;
}
</pre>
<p>而我的写法会是：</p>
<pre>
.side_col {
    float: left;
    margin-left: 20px;
}
*   .side_col {
    _display:inline;  /*hacked for IE 6*/
}
</pre>
<p>看明白了么？不应该把hack混在一起，也不应该用一种侥幸的心态，觉得<code>float:left</code>与<code>display:inline</code>写在一起没事。嗯，它们俩确实没事儿，但是其他的hack就不一定了。而且这里写<code>display:inline</code>纯粹就是为了解决IE6的bug，所以前面加上下划线，以明确的表达你的目的。</p>
<p>另外不要以为凡是hack都是为IE准备的。其实有些hack是针对其他浏览器的，比如FF。这就要求你对CSS标准的熟练掌握，能够自信的判断哪些渲染是遵守标准，哪些违反标准的。</p>
<p>此外，我喜欢在hack前面加上星号，其实这纯粹是个人习惯了。可能过段时间我就不这么用了，呵呵。</p>
<p>5. <strong>记得加空格。</strong><code>.class_name<span style="background:red"> </span>{<span style="background:red"> </span>property:<span style="background:red"> </span>value;<span style="background:red"> </span>}</code> 。我个人觉得合理的空格是优秀代码的一个指标。按英文的习惯，标点后面都应该带空格（如果你写This is a pen.That&#8217;s a pencil.句点后面不加空格， word里面会有错误提示）。所以既然CSS是外国人发明的，应该按他们的格式来写。类似的，在JS里var a = b + c;里面的空格也应该都要加。</p>
<p>6.<strong>适当的层叠（Cascading)或缩进以定义CSS的“作用域”。</strong>啥叫“CSS的作用域”？其实并不是所有的样式都在所有的地方使用。有的样式只用在某一块里面，比如“导航栏”里的“搜索框”，可能应该写成：</p>
<pre>
.nav .search {}
</pre>
<p>而有时候用层叠会增加代码优先级，所以也可以用缩进来“象征性的”体现作用域。像这样：</p>
<pre>
.login_box {}
   .forgot_pwd{}
</pre>
<p>缩进，是为了表示它们对应的标签具有父子关系。但这样只能起一个提醒的作用。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikkolee.com/109/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
