前言
近期在翻阅陈旧的历史资料,整理之前饱受争议的CSS Reset问题,不过好像十多年过去,现在大家统一了口径,纷纷推荐使用[Normalize.css](http://necolas.github.io/normalize.css/),包括Bootstrap都进行了内置使用,可见它的认可程度之高。

由于文章涉及内容较多,会分为章节进行介绍:

第一章
整理CSS Reset历史的演变痕迹,从第一份CSS Reset的诞生,到提出No CSS Reset的思想,再到国产CSS Reset 1.0版本的骄傲诞生;最终时过境迁,CSS Reset被Normalize.css所替代;
随后开始认识Normalize.css,了解它都做了那些事情,诉说与CSS Reset的区别,突出优势,告诉你为什么要使用它。

第二章
由于Normalize.css只提供了英文文档,没有提供对应的中文版本,所以从这章开始对其源码进行翻译整理与解读,本章包含 html与body,HTML5元素,链接,语义化文本标签,内嵌元素,群组元素等内容解读。

第三章,
继续来介绍源码中的表单和表格部分,并且整理一份normalize-zh.css中文注释的版本上传至Github,供大家参考使用,敬请期待

CSS Reset 历史回顾

第一份 CSS Reset

为什么会有CSS Reset的存在呢?那是因为早期的浏览器支持和理解的CSS规范不同,导致渲染页面时效果不一致,会出现很多兼容性问题。 关于 浏览器的默认样式 请点击查阅!

根据玉伯的文章中透漏,最早的一份CSS Reset来自Tantek 的undohtml.css,从URL中的日期可以看出时间是2004年,Tantek根据自身需要对于一些标签进行了简单的重置,源码如下:

  1. /* undohtml.css */
  2. /* (CC) 2004 Tantek Celik. Some Rights Reserved. */
  3. :link,:visited { text-decoration:none }
  4. ul,ol { list-style:none }
  5. h1,h2,h3,h4,h5,h6,pre,code { font-size:1em; }
  6. ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,
  7. fieldset,input{ margin:0; padding:0 }
  8. a img,:link img,:visited img { border:none }
  9. address { font-style:normal }

核心代码与作用

随后加入到CSS Reset的行列的大牛越来越多,比如业界领袖 YUI团队 以及Eric Meyer把这份代码内容变的更加充实,但是不难发现代码的核心部分还是对样式进行重置,在此可以结论出早期的CSS Reset的作用就是清除所有浏览器默认样式,让它一切归零!

  1. * { margin:0; padding:0 }

不过在此之后一段时间内,有人开始批判这种暴力清零的CSS Reset方式,随后部分前端开发者们也传来一些争议声音,比如:

  1. *{ margin:0; padding:0; }会带来性能问题
  2. 使用通配符存在隐性问题
  3. 过渡的标签重置等于画蛇添足
  4. 过渡的标签重置导致语言元素失效

注:由于都是一些陈旧的老问题,就不提供出处了,再此不过多讨论,感兴趣Google~

No CSS Reset 思想

其实面对于争议问题,国外的大牛Jonathan Snook是第一个提出No CSS Reset思想,其核心是Less is more,少即是多,不再提倡使用暴力归零的方法。

后来玉伯也在《Reset CSS研究》文章中阐述说明,其实 Eric Meyer 并不期望大家下载他的 CSS Reset 后直接就拿去用,而是应该按照自己的需求,适量裁剪和修改后再进行使用。

后来YUI更新了CSS Reset,还配套了 cssfonts.csscssbase.csscssreset.css只负责清除默认样式,而cssfonts.csscssbase.css 则负责将一些元素的默认样式再重设回来,这样就消除了之前的争议,这一方案迅速被大家接受了,又开始愉快的拷贝使用起来。

YUI 提供的cssfonts.css

  1. /*
  2. YUI 3.18.1 (build f7e7bcb)
  3. Copyright 2014 Yahoo! Inc. All rights reserved.
  4. Licensed under the BSD License.
  5. http://yuilibrary.com/license/
  6. */
  7. /**
  8. * Percents could work for IE, but for backCompat purposes, we are using keywords.
  9. * x-small is for IE6/7 quirks mode.
  10. */
  11. body {
  12. font:13px/1.231 arial,helvetica,clean,sans-serif;
  13. *font-size:small; /* for IE */
  14. *font:x-small; /* for IE in quirks mode */
  15. }
  16. /**
  17. * Nudge down to get to 13px equivalent for these form elements
  18. */
  19. select,
  20. input,
  21. button,
  22. textarea {
  23. font:99% arial,helvetica,clean,sans-serif;
  24. }
  25. /**
  26. * To help tables remember to inherit
  27. */
  28. table {
  29. font-size:inherit;
  30. font:100%;
  31. }
  32. /**
  33. * Bump up IE to get to 13px equivalent for these fixed-width elements
  34. */
  35. pre,
  36. code,
  37. kbd,
  38. samp,
  39. tt {
  40. font-family:monospace;
  41. *font-size:108%;
  42. line-height:100%;
  43. }
  44. /* YUI CSS Detection Stamp */
  45. #yui3-css-stamp.cssfonts { display: none; }

国产 CSS Reset

上面展现的是YUI最新版本V3.18.1,但是很尴尬的发现,YUI 提供的 cssfonts.csscssbase.css 只考虑了西欧文字,对汉字的支持却不多,这就导致中国很多用户只使用了cssreset.css,而没有使用其他两个。

据说nake和adiaos两大运动品牌到天朝后,有些运动科技会缩水,但是万万没想到,万能的代码到了天朝也是会缩水的。

于是乎,有些大牛不甘心,不仅仅厌倦了国内抄来抄去的CSS Reset现状,也受够了YUI只考虑西欧洲字体,不考虑汉字的缺陷,大厂们就开始摸索制定属于自己的CSS Reset,比如2009年阿里Kissy框架 (源码连接已失效,主页留纪念) 的第一份CSS Reset

  1. /* KISSY CSS Reset
  2. 理念:清除和重置是紧密不可分的
  3. 特色:1.适应中文 2.基于最新主流浏览器
  4. 维护:玉伯(lifesinger@gmail.com), 正淳(ragecarrier@gmail.com)
  5. */
  6. /* 清除内外边距 */
  7. body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */
  8. dl, dt, dd, ul, ol, li, /* list elements 列表元素 */
  9. pre, /* text formatting elements 文本格式元素 */
  10. fieldset, lengend, button, input, textarea, /* form elements 表单元素 */
  11. th, td { /* table elements 表格元素 */
  12. margin: 0;
  13. padding: 0;
  14. }
  15. /* 设置默认字体 */
  16. body,
  17. button, input, select, textarea { /* for ie */
  18. /*font: 12px/1 Tahoma, Helvetica, Arial, "宋体", sans-serif;*/
  19. font: 12px/1 Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif;
  20. /* 用 ascii 字符表示,使得在任何编码下都无问题 */
  21. }
  22. h1 { font-size: 18px; /* 18px / 12px = 1.5 */ }
  23. h2 { font-size: 16px; }
  24. h3 { font-size: 14px; }
  25. h4, h5, h6 { font-size: 100%; }
  26. address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */
  27. code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 统一等宽字体 */
  28. small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */
  29. /* 重置列表元素 */
  30. ul, ol { list-style: none; }
  31. /* 重置文本格式元素 */
  32. a { text-decoration: none; }
  33. a:hover { text-decoration: underline; }
  34. abbr[title], acronym[title] { /* 注:1.ie6 不支持 abbr; 2.这里用了属性选择符,ie6 下无效果 */
  35. border-bottom: 1px dotted;
  36. cursor: help;
  37. }
  38. q:before, q:after { content: ''; }
  39. /* 重置表单元素 */
  40. legend { color: #000; } /* for ie6 */
  41. fieldset, img { border: none; } /* img 搭车:让链接里的 img 无边框 */
  42. /* 注:optgroup 无法扶正 */
  43. button, input, select, textarea {
  44. font-size: 100%; /* 使得表单元素在 ie 下能继承字体大小 */
  45. }
  46. /* 重置表格元素 */
  47. table {
  48. border-collapse: collapse;
  49. border-spacing: 0;
  50. }
  51. /* 重置 hr */
  52. hr {
  53. border: none;
  54. height: 1px;
  55. }
  56. /* 让非ie浏览器默认也显示垂直滚动条,防止因滚动条引起的闪烁 */
  57. html { overflow-y: scroll; }

这应该是国内的第一份CSS Reset,是玉伯和另外一位前辈完成的,向他们致敬,记得玉伯在写完第一版本后,在总结文章的结尾还是千叮咛,万嘱咐说:

请记住:永远不存在万能解决方案,永远没有银弹。
因此我的建议和 Eric 是一样的:请根据具体需求,适量裁剪和修改后再使用。

替代品 Normalize.css

再把历史拉回到今天,时过迁境,中国的前端职位越发的火热,开发者们也变得更为专业,CSS Reset 泛滥使用逐渐淡出的前端的视野,被取而代之就是[Normalize.css](https://github.com/necolas/normalize.css),关于对CSS ResetNormalize.css的区别?可以引用知乎上 张小核桃 的一个回答:

CSS Reset 是革命党,CSS Reset 里最激进那一派提倡不管你小子有用没用,通通给我脱了那身衣服,凭什么你 body 出生就穿一圈 margin,凭什么你姓 h 的比别人吃得胖,凭什么你 ul 戴一胳膊珠子。于是 *{margin:0;} 等等运动,把人家全拍扁了。看似是众生平等了,实则是浪费了资源又占不到便宜,有求于人家的时候还得贱贱地给加回去,实在需要人家的默认样式了怎么办?人家锅都扔炉子里烧了,自己看着办吧。

Normalize.css 是改良派。他们提倡,各个元素都有其存在的道理,简单粗暴地一视同仁是不好的。body 那一圈确实挤压了页面的生存空间,那就改掉。士农工商,谁有谁的作用,给他们制定个规范,确保他们在任何浏览器里都干好自己的活儿。

下面开始对Normalize.css进行简单的介绍,关于两者的差异区别可以看问答平台:
使用normalize.css遇到的问题?
Normalize.css 和 Reset CSS 有什么本质区别没?

Normalize.css 简单介绍

关于对Github的介绍,这里引用 咀嚼之味 针对 官方介绍 翻译的的 中文版本

简要概述

Normalize.css@necolas@jon_neal 两位大牛花了几百个小时来研究不同浏览器的默认样式的差异而得出的结晶,感谢前辈们的贡献。

Normalize.css 只是一个很小的CSS文件,但它在默认的HTML元素样式上提供了跨浏览器的高度一致性。相比于传统的CSS Reset,Normalize.css是一种现代的、为HTML5准备的优质替代方案。Normalize.css现在已经被用于Twitter Bootstrap、HTML5 Boilerplate、GOV.UK、Rdio、CSS Tricks 以及许许多多其他框架、工具和网站上。

目前Normalize.css 已经成为了CSS Reset的替代方案是无可争议的事情了。国内著名的AliceUIAmazeUI 框架都是基于或者借鉴Normalize.css进行的制定化版本。

可以从这里下载:
Github:https://github.com/necolas/normalize.css/

做了那些事

Normalize.css做了以下几件事:

  • Preserves useful defaults, unlike many CSS resets.
    保护有用的浏览器默认样式而不是完全去掉它们
  • Normalizes styles for a wide range of elements
    一般化的样式:为大部分HTML元素提供
  • Corrects bugs and common browser inconsistencies
    修复浏览器自身的bug并保证各浏览器的一致性
  • Improves usability with subtle improvements
    优化CSS可用性:用一些小技巧
  • Explains what code does using detailed comments
    解释代码:用注释和详细的文档来

优势对比

前面讲到CSS Reset的核心作用就是清零,而且过于暴力;那么作为后者Normalize.css,到底有什么优势可以完全取代前者呢?

1.Normalize.css 保护了有价值的默认值
Reset通过为几乎所有的元素施加默认样式,强行使得元素有相同的视觉效果。 相比之下,Normalize.css保持了许多默认的浏览器样式。 这就意味着你不用再为所有公共的排版元素重新设置样式。 当一个元素在不同的浏览器中有不同的默认值时,Normalize.css会力求让这些样式保持一致并尽可能与现代标准相符合。

2.Normalize.css 修复了浏览器的bug
它修复了常见的桌面端和移动端浏览器的bug。这往往超出了Reset所能做到的范畴。 关于这一点,Normalize.css修复的问题包含了HTML5元素的显示设置、预格式化文字的font-size问题、在IE9中SVG的溢出、许多出现在各浏览器和操作系统中的与表单相关的bug。

3.Normalize.css 修复了浏览器的bug
使用Reset最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链。在Normalize.css中就不会有这样的问题,因为在我们的准则中对多选择器的使用时非常谨慎的,我们仅会有目的地对目标元素设置样式。

4.Normalize.css 是模块化的
这个项目已经被拆分为多个相关却又独立的部分,这使得你能够很容易也很清楚地知道哪些元素被设置了特定的值。因此这能让你自己选择性地移除掉某些永远不会用到部分(比如表单的一般化)。

5.Normalize.css 拥有详细的文档
Normalize.css的代码基于详细而全面的跨浏览器研究与测试。这个文件中拥有详细的代码说明并在Github Wiki中有进一步的说明。这意味着你可以找到每一行代码具体完成了什么工作、为什么要写这句代码、浏览器之间的差异,并且你可以更容易地进行自己的测试。

这个项目的目标是帮助人们了解浏览器默认是如何渲染元素的,同时也让人们很容易地明白如何改进浏览器渲染。

源码解析

虽然Normalize.css第五条优势是说提供了详细的文档,但是它并没有提供对应的中文版本,首先英文注释看起来不够清晰,其次对问题的解析程度也不够细化,而且也不包含问题案例,所以接下来一章会对Normalize.css源码进行模块解读与翻译整理。