CSS reset的重新审视 – 避免样式重置

这篇文章发布于 2010年04月14日,星期三,22:56,归类于 CSS相关。 阅读 256901 次, 今日 2 次 65 条评论

 

一、CSS reset(CSS重置)的历史

根据淘宝射雕的叙述,最早的一份CSS reset来自Tantek 的undohtml.css,很简单的代码,Tantek 根据自己的需要,对浏览器的默认样式进行了一些重置。

其余一些有名的CSS reset如业界领袖Eric Meyer的reset,或是Tripoli Reset

CSS reset的作用是让各个浏览器的CSS样式有一个统一的基准,而这个基准更多的就是“清零”!如下面常见但事实上极不推荐的代码:

*{ margin:0; padding:0; }

可以说,兼容性是CSS reset诞生的的主要原因之一,还有一方面的原因是类似于“库”的作用。然而,这些又是我认为CSS reset这个概念应该淘汰的原因。

二、CSS reset的滥用

物极必反,在集体主义的亚洲国家,从众服从以及跟风是相当常见的,这在CSS reset的应用上可见一般,Eric在其reset代码页面中提到:要根据您自己的要求做修改。然而,目前的状态是(尤其一些中小型网站),CSS reset代码直接拷贝过去,也不做一番思考,我真是哀其不幸,怒其不争。我今天就见到了这么一行CSS reset代码:

body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td { margin: 0;padding: 0; }

看到这样子的CSS代码我只能无奈的摇摇头,浮躁的不严谨这些词立马涌现在我脑中。姑且先不说CSS reset这东西的出现以及推崇就是个错误,光看看这段样式代码,我就吐血三升了。我想,有类似这段样式代码的网站不在少数,但是却是很屎的一段CSS样式代码。

1. div标签默认有margin值吗?有padding值吗?怎么会想到应用div{margin:0; padding:0;}属性呢?真是画蛇添足,多此一举。
2. dt标签有默认的marginpadding值就是0,这里为什么还要使用呢?
3. li标签默认有margin值吗?有padding值吗?压根就没有,也不自己测测,还没事找事设置个li{margin:0; padding:0;}声明,真是衰!
4. code标签是个属于inline水平的元素,居然也扯到marginpadding的重置,真是好笑。
5. 还有,像form, input, button, textarea这样子的表单元素,有margin值吗?有padding值吗?我真是不解!
6. fieldset, legend这两个90年代的标签你的网站上使用了吗?使用概率不足1%的标签也拿来重置,我实在无语了。
7. 还有thtd这些标签,幸好没有写上tabletr标签,否则我一起痛批一段。

在我看来,就算要CSS默认属性要reset重置,也应该如下:

body, dl, dd, h1, h2, h3, h4, h5, h6, p, form{margin:0;}   ol,liul{margin:0; padding:0;}

这样子的CSS reset才是高效的,简洁的,其他一些标签都要通通的去掉,完全没有必要。

三、CSS reset的不足

CSS文件的大小
显然,CSS reset平白无故的增加了CSS文件的大小,虽然,增加的大小可能有限,但是,要知道,即使0.1秒的载入时间差异也会影响互联网企业的收入的。

样式的重置
许多的CSS样式要重写与重新覆盖,典型的多此一举。

CSS的渲染
这可以说是最大的问题,样式无缘无故增加了很多的渲染,想想看,一个项目或是一个页面中有多少个div标签,居然使用div{margin:0; padding:0;}当然,*{margin:0; padding:0;}更是无法容忍的。

四、CSS reset本没有存在的必要

当您静下心来,审视你这几年对CSS的使用,您再去思考CSS reset,从它的历史,从它繁盛的原因,去思考CSS reset的本质,标签的意义所在,您就会发现,CSS reset这个概念本不应该流行与繁盛,虽然它有道理,但是实际上是个可有可无的东西。

我可以从多方面阐述我的观点:

1. 那些所谓的需要重置的标签
我现在问您一个问题,在您制作的或参与开发的页面中,h1~h6标签您使用了几个,我想不可能全部都使用吧,使用三种类型的标题标签就不多了。您有必要对h1~h6所有标签都使用margin的清除吗? OK,我们现在换个角度思考,假如我们没有对h1~h6标签设置{margin:0;}的重置怎么办?从SEO的角度讲,一个页面最多只能出现一个h1标签,所以,显然,h1标签的CSS reset完全没有必要,页面什么地方用就设置相应的样式,只要你记住,h1标签是有个默认的margin-top与margin-bottom值的,所以,我们就可以由这样的属性:

h1{margin:10px 0 0;}

对比下CSS reset下的使用:

h1, h2, h3, h4, h5, h6{margin:0;}
.
.
.h1{margin-top:10px;}

使用CSS reset不仅文件大小增加了,CSS代码属性也发生了重置,CSS渲染也增加了。显然不及没有CSS reset来的高效。

您可能会说:“哎呀,小旭啊!你这里的h1标签是个特殊情况啊,是只出现一次的标签啊。

反驳地好,我们拿h4标签举例说明CSS reset是个多余的东西。一个页面上往往有很多个模块,没有模块都有一个小小的标签,而这个标题往往就使用h3或是h4标签,例如腾讯首页的模块选项卡标题,如下图:

腾讯首页选项卡标题的h4标签 张鑫旭-鑫空间-鑫生活

我们看看腾讯页面时如何对这个h4标签设置样式的,见下图:

腾讯首页h4标签的设置 张鑫旭-鑫空间-鑫生活

上图标注部分,有个margin属性,现在对比下面两种样式设置:

腾讯做法:

h1, h2, h3, h4, h5, h6{margin:0;}

#finance h4, #car h4, #tech h4, #edu h4, #kid h4, #astro h4, #sports h4 {
float:left;
font-weight:200;
height:20px;
line-height:20px;
margin-right:1px;
overflow:hidden;
padding-top:3px;
text-align:center;
width:73px;
}
我的做法:

#finance h4, #car h4, #tech h4, #edu h4, #kid h4, #astro h4, #sports h4 {
float:left;
font-weight:200;
height:20px;
line-height:20px;
margin:0 1px 0 0;
overflow:hidden;
padding-top:3px;
text-align:center;
width:73px;
}

通过对比可以发现,我的做法避免了右侧margin值的重置,而且也节省了可能不会使用的h5,h6标签。就算这里的h4标签没有margin值,我们可以直接设置margin:0就好了,没有任何的损失。CSS reset就是个可有可无,没有最好的东西。

同样的原理也可以应用在ul,ol标签上,你说你使用ul列表进行列表元素的布局的时候,不会设置margin值与padding值吗?既然可能要设置这些属性,为何不在就在要使用它们的时候设置呢?没有什么损失啊,反而可以避免不必要的渲染。
CSS reset就像是一种宁可错杀三千不可放过一个的做法。

2. 那些所谓的兼容性
所谓兼容性,我想,大多数人都是听别人说的,不同浏览器下标签的一些属性有差异啊!我倒要问一问,哪些标签的默认属性在不同浏览器下有差异?您可以花点时间想想。//zxx:假设您经过了短暂的思考
我所知道的就是h1标签的文字的大小,在有些浏览器下大些,有些小些;然后就是一些margin值的些许偏差,然后还有呢?事实上,目前浏览器而言,对于这些默认标签的属性其实差异是很少很小的,兼容性一说实在不能用在标签的默认属性上。

回过来,就算有一些差异,为何非得在头部已CSS reset的位置同一呢?当需要的时候,在设置,又有什么差异呢,这样,反而更直接,更高效!

3. CSS库的概念
我认为,CSS reset是个非常尴尬的概念,这是与性能,优化的概念是相悖的,但是,实际上,有时候它的存在似乎有一定的道理的,比如设置默认的a标签的属性。不过,我们也可以不用CSS reset的概念来解释它。如下面的代码:

body{margin:0; font:normal 12px/1.5 '宋体';}
a{color:#34538b;}

这样子的代码您想到了CSS reset吗?

再看下面的代码:

body{margin:0; font:normal 12px/1.5 '宋体';}
a{color:#34538b;}.l{float:left;}.r{float:right;}.cl{clear:both;}img{border:0;}.tc{text-align:center;}.tr{text-align:right;}.tl{text-align:left;}.g0{color:#000;}.g3{color:#333;}.g6{color:#666;}.g9{color:#999;}.r3{color:#f30;}.wf{color:#fff;}.vm{vertical-align:middle;}.vtb{vertical-align:text-bottom;}.vt{vertical-align:top;}.vn{vertical-align:-2px;}.ml2{margin-left:2px;}.ml5{margin-left:5px;}.ml10{margin-left:10px;}.ml20{margin-left:20px;}.mr2{margin-right:2px;}.mr5{margin-right:5px;}.mr10{margin-right:10px;}.mr20{margin-right:20px;}.mt2{margin-top:2px;}.mt5{margin-top:5px;}.mt10{margin-top:10px;}.mt20{margin-top:20px;}.mb2{margin-bottom:2px;}.mb5{margin-bottom:5px;}.mb10{margin-bottom:10px;}.mb20{margin-bottom:20px;}……

这样子您想到了CSS reset了吗?看这里的a标签属性以及img属性,我们发现我们可以用CSS库的概念来解释类似于a标签属性设置的原因,这样就可以避免CSS reset解释的一些尴尬。其实想想,本来就是,这些属性与.l{float:left;}.r{float:right;}库样式作用是一致的,方便高效的使用。对于CSS库的概念,我的思考还不是很成熟,就提这么多。

五、少即是多

武侠的最高境界是什么? – 无招胜有招
设计的最高境界是什么? – 减少设计
所以,最少的CSS代码,最少的渲染,最少的重置就是最好的CSS样式代码,这反应了您的CSS层次。说句不好听的话,CSS reset是用来让那些CSS菜鸟,对CSS不太了解的人准备的。

个人观点,不要客气,欢迎积极反驳,提出您的观点。争论中提高……

最后附上最近看到的一个相关的ppt(补充于2010-04-27):

参考文章:
1. Reset CSS 研究(技术篇)
2. No CSS Reset
3. To CSS Reset or Not to CSS Reset

(本篇完)

分享到:


发表评论(目前65 条评论)

  1. Frankie说道:

    实际项目里,用得较多的是 normalize.css。

  2. 某某某说道:

    开个玩笑啊!

    *{all:reset}

    然而到现在仍然有样式奇怪的手机浏览器。

  3. WE!D说道:

    学校老师说,要”reset”一下。当时也不知道为什么。受教了!

  4. 被阻挡的鸟兽说道:

    其实那样写是无奈的,谁知道现在的浏览器会给你出什么样的问题,百花齐放的浏览器,说白了就是胡闹

  5. wdy说道:

    其实,我从来没有用过这些库来重置标签的默认样式,只是在必要的时候,对个别的标签样式重写

  6. w3c0929说道:

    我的理解:reset可有可无,完全取决于个人;
    我本人的看法如下:
    对于一些不是共同开发的网站一个人通到底的可以考虑,还有一些追求高性能极致的也可以考虑;
    对于多人合作的网站,各种设备匹配,一套设计图完成搞定多个终端的,reset真有必要,避免带来不必要的麻烦,可以说一种偷懒的做法;
    今天特意去看了一下各大型网站的做法;
    京东:
    *{margin:0,padding:0;},
    腾讯:
    body, dd, dl, fieldset, form, h1, h2, h3, h4, h5, h6, input, legend, ol, p, select, td, textarea, th, ul {margin: 0;padding: 0;}

  7. clover说道:

    margin:0 1px 0 0;

  8. 不乱说道:

    这文章之前看过的,当时看完后也是深受启发的,然后逐一去测试了标签,然后也形成了自己的一套reset,然而今天在回来看这文章,也不知道我的这套reset是不是还是有不足的地方,毕竟我的项目都是比较小的,挺想知道张神目前用的reset能不能共享下?

  9. helloworld说道:

    bat 三大企业 你可以去看看 有没有用 样式重置 (微笑)

  10. 意见说道:

    对于您所说的li标签不应该被重置,据我的测试li标签应该加入重置样式表。

  11. wingyiu说道:

    reset会高调有价值的默认值,是一种错误的、一刀切、无脑、懒惰的做法。更正确的做法是normalize

  12. 魔蝎说道:

    移动端上游览器百花齐放,各种乱七八糟的,不用 reset ,光测试就要测死

  13. 远方的风说道:

    我是觉得很赞,多谢博主,一直关注您的文章,仁者见仁嘛,我觉得很实在,我考虑过这个问题,就是自我感觉能力不足,不敢去否定那些大人的东西,受教了。

  14. 流心奸商说道:

    看完了,很详细,说得很好,没有任何问题。reset给菜鸟用,对菜鸟帮助很大,所以reset.css是有意义的,菜鸟熟练成熟为老鸟之后根据自己惯用的习惯设置css重置。
    而你这篇文章是给谁看的?
    菜鸟?菜鸟还不熟悉各种浏览器的兼容,容易出现各浏览器异常。所以使用reset.css
    老鸟?老鸟自个会根据自己的行为习惯设置有必要花时间看这个吗?
    你成功的证明了自己是老鸟,但是这篇文章还有其他的意义吗?
    看你写了那么多我也努力水了一把,别在意。

    • Sytana说道:

      什么菜鸟老鸟的,菜鸟到大神不会还有一个过渡期吗?这个给过渡期的人看不是最合适了吗

      • 流心奸商说道:

        (›´ω`‹ )老鸟就是用来讽刺的,和菜鸟比起来的优势是时间长,也就是比菜鸟要老的意思,如果要夸他的话,我会用大神dalao之类的词。他先是谈历史,再说到滥用,然后是不足,最后再否定reset的存在。然后在最终句说出这样一句话

        “说句不好听的话,CSS reset是用来让那些CSS菜鸟,对CSS不太了解的人准备的”

        他首先层次分明地展示自己对reset文件的理解,然后从根本上否定它,表明自己不需要,最后再说需要这个的是菜鸟。

    • helloworld说道:

      我很赞同

  15. 咳咳,这篇文章很不错,我以前是就是html,body,div….{margin:0;padding:0;}。
    刚试了一下,div的确没margin、padding,…
    谢谢前辈。‘
    额,话说下面的返回顶部没反应= =

  16. chasonma说道:

    在项目我更常用Normalize.css,它既保留了原来的样式,但又保证每个浏览器的统一性,没有直接margin:0;padding:0,全部清0那么暴力。

  17. 小马说道:

    讲的真细,受益良多。不过像我这种做了三四年网站的 还是想说一句 闲的蛋疼

  18. paddingme说道:

    小旭哥,”从SEO的角度讲,一个页面最多只能出现一个h1标签” 这个结论是错误的,详情见:http://www.quora.com/Does-using-multiple-h1-tags-on-a-page-affect-search-engine-rankings
    According to Matt Cutts (lead of Google’s webspam team and the de facto expert on these things), using multiple “ tags is fine, as long as you’re not abusing it (like sticking your whole page in an “ and using CSS to style it back to normal size). That would likely have no effect, and might trigger a penalty, as it looks spammy.
    If you have multiple headings and it would be natural to use multiple “’s, then go for it.

  19. 风芯说道:

    看了前辈的文章,感觉受益匪浅。reset的使用会波及到一些本不需要修改的属性,个人觉得也不是要放弃使用reset,而是依据实际特点对reset做更进一步的精简。

  20. 小可说道:

    .ml10{margin-left:10px;}.ml20{margin-left:20px;}.l{float:left;}.r{float:right;}这样的命名不妥。模块化、组件化样式后,这样的命名在各页面是潜在风险,各结构调整时,要修改HTML id/class 属性,与结构、样式、内容分离相违背。css reset,在个人或企业网站是有冗余之嫌,但在大型门户网站是有必要的。

  21. Bepo说道:

    li,div之类的padding,margin重置确实是不应该存在的,看了文章总体上有些受教

  22. 侯永禄说道:

    首先我就是你所谓的那个css菜鸟。其次,博主这篇文章很有指导意义,但只停留于思想层面,在现实中很难实现。

  23. filed说道:

    存在就有ta的合理。对于小的网站确实没有必要做所有元素的reset,但是对于大型网站,reset还是有必要的,前端前辈们研究了很久搞出来的css reset 你就这样完全否定,楼主有点偏激

  24. higocn说道:

    很认真的看完了,我觉得楼主有些左倾了。

  25. Storm说道:

    嗯!确实要精心来认真思考一下,重置是否真的有那个必要,是否真的需要

  26. children117cl说道:

    好吧,我来被博主打几巴掌的~

  27. 伯恩说道:

    博主文章还是不错滴,不过这篇文章我几乎没有一条认同的,就大标题来说,CSS Reset:是应该被广泛推广和标准化的,而不是扼杀掉他,只是我们在推广标准化的道路上没有权威的人士和组织来搞这件事情,其实关于样式重置问题,博主的例子只能片面的说明了使用方法,在模块化开发环境下,你这样的写法太过于单一片面,无法大面积灵活使用,所以我个人认为重置样式是必须的虽然看起来貌似让样式解读有了误区,但应用于实际工作中却是大大方便了不少。

  28. 前端菜鸟说道:

    button 在chrome内核浏览器下有margin的。

  29. 大德乾元说道:

    看了博主的论述,觉得博主根本未理解HTML元素,在CSS下,是什么结构。

    每一个HTML元素,在CSS下,都是盒子结构,从内到外,分别是:内容-内容与边界的留白(padding)-边界(border)-边界外沿,也即是元素之间的距离(margin)。

    也就是,每个元素,天生就是这种结构。只不过是,你让不让它显示出来,以及显示多少的问题。而已。不要说某个元素没有padding,没有margin之类的无知语言。

    深刻地理解元素的盒子结构,抓住本质,很多东西就能融汇贯通。

    有时间,看看First Head系列的相关书籍吧。会让你获益良多。哪怕你做了100年网站,不会思考,不会理解本质,你也还是个菜鸟。

  30. 前端之路说道:

    确实,每个前端攻城师都会经历样式重置的纠结,我个人觉得博主有些偏激了,看法稍有不同。
    存在即是合理,对于大公司大项目,效率、效果、效益是首要的,有人做过测试:css reset对渲染的影响是微乎其微,机器的诞生就是要为人类服务,太过于在乎1hzCPU消耗,结果可能会带来更多的维护成本。
    没有最好的办法,只有相应场景下更好的办法。

  31. body, tl, td, h1, h2, h3, h4, h5, h6, p, form{margin:0;} ol,li{margin:0; padding:0;}

    这里面的li是不是该改成ul了? li的margin,padding 默认就是0吧?

  32. wasin说道:

    楼主提到,ul,ol在用到的时候reset,如果一个大型的门户网站,可能用到的地方很多,如果每个地方再reset,从代码的简洁来看,本身就不够简洁。 我觉得应该衡量 css的渲染和代码的简洁和重用性,然后再决定用何种方式。

  33. preston说道:

    貌似ul的 margin-left: 40px; 也没人说,FF下
    IE下当ul标签下的 li 浮动后
    ul也有margin-left: 40px;

    所以ul 还是需要 magin:0;下的

  34. preston说道:

    楼主不错,实力很强啊。但有点错误哟 td th是有默认的padding:1px;
    赶紧改过来,这种理论性的东西还是不能误导人的。
    嘻嘻,有些地方别人指出了,这里就不复述了

  35. will说道:

    不清楚大家是怎么理解CSS Reset的应用的,直接套用别人的Reset固然可以省些很多不便,但是自己在使用的时候适当的调整自己的css reset是很有必要的,我自己在使用reset的时候是用了自己的一套,因为时间长了,也就慢慢的习惯了这套reset,但理想化的情况应该是根据不同的网站,不同的项目来重新reset自己的css reset,而不是一味的图方便使用之前自己总结好或者别人总结好的reset css.

  36. 博看文思说道:

    li不需要设maigin,padding

  37. noco说道:

    看了几篇关于CSS的文章,印象最深的就是“CSS库”,博主对于“CSS库”有偏好!

  38. 周笑笑说道:

    个人觉得reset还是必要的,毕竟各个游览器对有些标签的默认值的简析是不一样的,如果你不在一两个像素的差别,那就另当别论了,不过我们做事情都应该严谨一点好

  39. phoenix说道:

    根本没有必要纠缠这个东西上。*通配符和yahoo rest渲染时间都可以测试的。由于JavaScript最小单位为毫秒,所以没有更精细的数据。

    * ie8 2毫秒左右 ff 3.6.8 0毫秒左右 chrome 6 0毫秒左右
    yahoo 4毫秒左右 ff 3.6.8 1毫秒左右 chrome 6 1毫秒左右

    相差最多不过2毫秒 做这么多工作 为了两毫秒值得么?而且yahoo初始化里面 tt code small dfn等标签根本是不用的,初始化这些也会浪费资源,abbr,acronym这两个标签有严重的兼容性问题。

    还有yahoo的文件量比*大了好几百比特,下载完全超过2毫秒!

    搞这些根本是无意义的

  40. vapour说道:

    受教了,真正需要reset的元素很少。而现在的css reset大部分都是为了reset而reset,从而达到完美统一。过于追求统一,而忽略了reset的必要性。

  41. 一路彷徨说道:

    我觉得事先重置,然后在重新定义需要的样式,毕竟同样的标签在不同的地方表现都不一定一样,要不然的话,等大急了才来挖粪坑就不好了

    特别是在浏览器的兼容上,很多时候你会在开发半途的时候才会发现,

  42. 思远说道:

    个人认为可以适当地CSS Reset,根据网站的具体的情况吧~
    当然不能盲目地复制粘贴,这样“滥用不如不用”~

  43. dony说道:

    body, tl, td, h1, h2, h3, h4, h5, h6, p, form{margin:0;} ol,li{margin:0; padding:0;}
    这里的td在IE,FF,chrome里的margin都是0,是不是也该把这里的td去掉

  44. dony说道:

    同样补充下,刚刚发现的textarea在FF下有margin:1px 0; ie下好像为0….

  45. dony说道:

    博主:
    input其实是有padding值的,在IE下padding:1px;在FF下是padding:1px 0
    button在IE下的确padding:0;但在FF下padding:0 3px
    所以我觉得很多地方reset.css里定义那么多标签是有它的作用的,只是博主可能某些地方没注意到…

  46. walkingp说道:

    这个css reset我觉得从设计模式上来理解更恰当一些,在程序设计的角度,当然是最大限度地复用。
    腾讯的这个h1, h2, h3, h4, h5, h6{margin:0;}杀伤力很强,逻辑清晰,而且实现了很大的程序复用,如果使用你的这种方法,在当前一个页面里的确代码较少, 但在团队开发中极难维护。

    • 张 鑫旭说道:

      对于目前大多数的web开发团队而言,人员较少,规范制定不严,经常在维护的时候 – 例如临时添加一个模块或一个宣传页面,常常会自己写一个类似于h1, h2, h3, h4, h5, h6{margin:0;}的东西,久而久之,就会发现,一个页面上会有多个h1, h2, h3, h4, h5, h6{margin:0;}的样式重置,这可以说是一个相当普遍的问题。
      有什么方法可以规避这个问题呢?一是团队运作机制很成熟,例如腾讯、阿里这样的的公司;二就是避免没有必要的CSS reset。

  47. 杰加说道:

    级联是CSS里很重要的一个设计思想,覆盖之前的样式也并不为过。
    很喜欢读博主的文章。

  48. 没觉得你说的好说道:

    样式重置很多时候是帮你节省工作的事情,试问一下,程序没有派生,开发的速度能快吗?虽然会有垃圾代码,但是为什么现在写程序都不直接写功能,不去派生从而生成那么多代码?因为社会的一种进步,很多时候样式表的重置能给你解决很多出错的可能和调试的麻烦,腾讯也这样写,不要去专牛角尖。这样会给你带来更大的回报

    • 张 鑫旭说道:

      真是好笑,腾讯这么写就一定要这么写吗?如果您关注目前优秀互联网企业的网站,会发现,CSS reset使用的越来越少。国外也有些优秀的网页设计师开始表达自己“不使用CSS reset”的观点。
      CSS reset真是个可有可无的东西!

  49. 小西说道:

    又来挑刺了,呵呵
    在“CSS reset的滥用”中的第5条 关于form没有margin值的说法 其实在IE系列中form是有margin默认值的 在一个form标签的上下部分各添加点内容 就会发现form和他们之间是有明显间隙的

  50. chunlei85说道:

    看了博主的观点,静下心来想想,css reset真的是没多大必要。当你真正对css很了解后,那些默认样式说不定会帮你省下不少事了。支持博主,回头再整整我的css了。