doudou.css 开发感想

项目地址:Github: h2y/doudou.css

浏览器自带的标签样式实在是太难看了,不手动编写 CSS 是根本没法看的!
让浏览器默认样式变得好看的一款 CSS 框架,覆盖了标签的默认显示效果,使其更加美观好看。除了导入 css 文件至 head,你不需要做任何额外的事情。

效果预览:https://h2y.github.io/doudou.css/test.html


感想是必要的

前几天我在知乎听了我的第一场 Live,小芋头君 的《前端开发者成长之路》,可以说受益匪浅,其中一点就是要多做 Review,因为在总结的这个过程之中,其实自己就能学到不少的东西。

之前我每在 Github 上写一个小工程,博客作为我的主要内容发布平台,我都会发一点东西,通常就是那个工程的 Readme,复制一份发布过来。这造成了一个很尴尬的问题,一是没啥实际的意义,重复的内容,而是 Github 那边的 ReadMe 会不断地更新,博客这边的内容还必须跟进,然而却没有任何的卵用。

我也算是彻底明白了,我的博客作为我每个项目之后写总结的地方,这将是非常有必要也是非常合适的,我会将这个习惯保留下去。

开发的意义

算是为了自身需求吧,去年 11 月在我的灵感仓库中记录的《开箱即用的 css 框架》是这么写到的:

前端开发往往都需要导入 css 框架,比如 bootstrap,不然浏览器自带的样式太难看了。但是这些框架并不是开箱即用的,需要为标签按照规定加上各自的类。

我打算开发一个完全重写浏览器默认样式的 css 框架。比如 <button> 标签,不需要添加额外的 .btn 类就能显示出美化后的效果。

对于开发者而言,只需要引入我这个 css,就可以将原本丑陋的 html 变得好看。

我想做的是一个代替 normalize.css,成为开发一个 web 项目第一个导入的 css 框架,以更漂亮的方式重写了浏览器默认样式。

这不是一个大的的工程,拖到现在比较闲所以花了 2 天时间认真的搞定了,目前可以放心地用在我的下一个开发项目当中。

最大的缺点

你可以在某个页面当中使用 Bootstrap 的同时使用其他 CSS 框架,使用 class 来区分即可。

但是你一旦使用了我的 doudou.css,就不允许导入其他任何一个别的框架了,因为 doudou.css 将全局样式给修改了。

那么,开发的意义究竟在哪?

很简单,当我开发一个简单的页面时,我并不想去导入任何一个 CSS 框架来实现特效,并不是因为页面负载,而是查阅他们的开发手册很麻烦很耗时,还不自由。

不需要别人的框架,自己手写就能搞定这个页面的样式时,我会采用 doudou.css 作为最底层的样式开始编写,让默认的浏览器样式更好看一点,减少我的工作量。

CSS

浏览器为什么对标签的默认渲染效果如此难看?其实不是的,浏览器只是为了尽可能的简单,这样方便开发者在当中做出倾尽自己的才华,使其变成自己心中所想的那个样子。另外还有一个原因就是历史遗留,曾经做得很丑,随着版本更新,再丑也不能改了。

我很清楚的知道,我开发的这个 CSS 不可能是一个一劳永逸的框架,我只能提供一个最通用的美化结果,实际开发当中肯定还会基于这个底层的样式进行进一步的开发。

就拿 <table> 来说,我写了奇偶行色差,又写了 hover 特效,比原生的样式好看多了,后来突然想到:尼玛,万一我某个页面不需要这些效果,那怎么办,岂不是还要寻找 css 源码,并想办法移除由 doudou.css 产生的效果,这怎么行。于是我删掉了其中大部分美化效果。

学习 HTML 标签

我用 MDN 提供的 HTML5 标签列表 进行开发,所以也系统的回顾了这些标签的用法。

比较有价值的标签:

  • <abbr> 拥有 title 属性,和 a 标签一样,在鼠标悬停时会显示。
  • <kbd> 表示按键。
  • <fieldset> 将一组 DOM 框在一起。被包裹在其中的 <legend> 会作为 fieldset 的标题。

关于标签学到的小知识:

  • <i> <em> 在语义上分别是术语和重要内容的意思,只是浏览器都是用斜体对其进行渲染。
  • <code> 用来表示行内代码,标签内部的内容不会换行输出。
  • <pre> 指已经过排版的代码,浏览器会将其 HTML 代码中的内容原样输出到页面中,包括换行符,所以常作为代码块的显示方式。

计量单位的区别

CSS 当中的计量单位主要有 px/em/rem 三种,我将一篇写得比较好的文章剪藏到了我的知识库中:《CSS 单位区别 px、em、rem

这篇文章写得很详细,我不重复了,我需要补充以下几点:

  • px 是始终固定的,不会由浏览器自动改变,所以产生了按比例计量的 em。
  • 1.25em 其实也就是 font-size: 125%

比例是继承的,加入一个 div 被设置为字体大小为 .5em,该 div 下面的所有元素基数就是 50%,于是,我觉得其中有个元素太小了,于是设定它的字体大小为 1.2em,但是呢,很明显,最终渲染的结果该元素大小为 50% * 120% = 60%,于是就产生了歧义。

于是,就产生了 rem,总是相对于根元素进行字体大小的设定。

所以,rem 就是最好的吗?当然不是~

  • px 的用途在于精确赋值,比如 border 的值,我就只需要 1px 的 border,难道我得写一个 .05rem 吗,谁知道最后会被换算成多少 px。。。

  • em 的特点是会继承比例,让人头疼,但这正是其特点。我的 doudou.css 中使用的所有单位都是 em,因为作为一个对基础元素所写的 CSS,我需要的就是标签之间字体大小的继承。嵌套的时候大小会相互影响,正合我意。

  • 其他时候可以说用 rem 最多没错。不过 em 和 rem 掌握理解其中的差异之后,是各有用途的。

工程化

前段工程化真是个好东西,大大的减少了工作环节。这次我主要还是使用熟悉的 gulp 来构建的 doudou.css

主要使用了 autoprefixer 为 CSS 自动增加浏览器前缀,神器。clean-css 用于压缩,属于语义级别的压缩,也是神器。sourcemaps 用来创建 map 文件。

写完代码,gulp 会自动帮我自动执行这一系列工作,实在是太方便了。

目前前端开发主要也就是使用 gulp 和 webpack,至于后者,虽然知道它的作用,但它到底用在哪种情况下,还没想明白,也没有用过。

关于 CSS 编译工具

doudou.css 我使用 Less 来编写,很方便。

你问为什么不使用 Sass?额,我根本没有去尝试使用过它,因为简单看了看就感觉它不让我喜欢:

  1. 我需要丢弃 CSS 语法去重新学习新的语言。而 Less 是兼容 CSS 的。

恩,没有第二的原因了。当然也正是因为 Sass 有了新的语法,不必考虑兼容性问题,所以拥有了一系列高端功能。但在我看来,兼容 CSS 才是王道,就像是当时的 CoffeScript 一样,自从有了 ES6 之后就少有看到它活跃在社区了。

当然,我或许会在以后小项目中试着用用 Sass,看看所谓高端大气上档次的语法有哪些。

不过我需要的功能非常少,目前而言,在 Less 中我主要也就是用这些功能:

  1. 层级嵌套。
  2. import 实现模块化。
  3. 颜色的变量,以及颜色相关函数。(不多)
  4. 样式继承。(极少)

所以说 Sass 对我不是很有吸引力,另外还有个 PostCSS 我倒是非常感兴趣,这个工具将 CSS 的处理过程用插件来实现,你需要什么功能,都可以自己选择并且搭配,虽然比一体化的 Less 麻烦了些,但是自由度超高,对于 doudou.css 这种纯 CSS 项目来说,说不定 PostCSS+Plugins 就能构建起完善的工作流了。这工具我是很感兴趣,下次一定试试。

这次我想用处于草案阶段的 CSS4 的大小写匹配功能,Less 就不能识别那样的语法,不仅如此,还报错,无奈只好删掉相关的语句,很是不爽。而如果是 PostCSS+cssnext 插件就没有这样的问题。

NPM?NO~

由于我的 doudou.css 目需要以后用在我的其他项目开发中,所以我打算上传到 Github 的同时也上传到 NPM,这也是我第一次尝试上传模块到 npm。

注册了我的 npm 账号:https://www.npmjs.com/~h2y。不得不说 npm 是一个伟大的平台,为我们免费托管了如此多的模块,为 Node 的进步带来了巨大的贡献。

NPM 的缺点

什么,NPM 不能和某个 Git 项目绑定,实现自动更新?为什么我每一次 Push 都得要多一个 Publish 步骤来将文件上传到 npm,太繁琐了啊。

版本管理这种东西,有一个就好了,两处一模一样的发布完全是多余的。

我的解决方法

经过查阅资料,我找到 npm 在安装模块时是可以直接从 github 下载的,而不一定必须使用 npmjs.com 上托管的命令。

npm install github:h2y/doudou.css#branch

这也可以加入到 Dependencies 当中,和普通的安装没什么大的不同,所以我上传到 Github 的项目也可以被今后的工程所使用。

缺点:版本控制

使用这种方法安装的模块,最大的缺点是不能像 npm 那样语义化控制版本:^1.2.1 这样。总是 clone 当前最新的代码。

于是,该怎么办呢?后来我想到了一个解决办法,很方便而且也同样好用:

我将 master 分支作为我的开发分支,创建 1.x 分支储存模块的 1.x 版本。

安装 latest 版本(master 分支)

npm i github:h2y/doudou.css

安装指定的主版本(1.x 分支)

npm i github:h2y/doudou.css#1.x

大概就是这个意思,以后如果我大面积的重构代码,只需要保留 1.x 分支的代码不变,当时使用上面第二条命令进行安装的用户将不受任何影响。

这样就控制了主版本号,事实上 # 后面除了跟分支名,还可以是 commit ID 或者 tag 名,实现版本的固定。还是挺灵活的,为自己的想法点赞。

在如此方便的 Git 面前,有相对完美的解决方案,我是找不到理由再发布一份代码到 npm 上面了。

Github raw

我发现,虽然可以直接访问,但将 https://raw.githubusercontent.com/h2y/doudou.css/1.x/dist/doudou.min.css 作为 CSS 的链接放到页面里不会生效。

原因是 Github 返回的 Respond Header 中 Content-Type: text/plain; 导致这是一个纯文本,并且 X-Content-Type-Options: nosniff,这条语句从浏览器级别限制了不允许自动识别文件类型,以及使用 type="text/css" 来进行类型的指定,也就不能作为 CSS 来调用了。

用 Github 来充当 CDN 看来是不可取的了,后来我找到了一个第三方服务解决了这个问题:https://rawgit.com/,功能为:

RawGit serves raw files directly from GitHub with proper Content-Type headers.

有趣的是 RawGit 使用 Node 开发,开源并且托管在 Github 上,免费的很好用。

将 CSS 链接修改为 https://cdn.rawgit.com/h2y/doudou.css/1.x/dist/doudou.min.css 之后,就可以顺利在浏览器中调用了。

感谢开源社区如此多的好工具。

1 条评论
  1. 第一次写开发感想,写了好多。
    觉得关于项目本身的介绍太多了,没啥必要,放到 ReadMe 中就可以了,以后在博客还是侧重写获得的经验教训。

发表一条评论