关于如何写类名,网上已经有很多讨论了:
总结来说,BEM
命名法更好,下面就以自己的实际例子来讨论,为什么更好。
先来看两段代码:
1 | <ul class="news"> |
1 | <ul class="news"> |
两段代码的作用都是相同的,即渲染新闻列表,颜色为#eee
,并且第一条新闻颜色为red
。不过可以看到两者的选择器不同,前者给每一个li
标签添加了类名,而后者直接使用标签选择器li
。
性能
如果搜索关于网页渲染性能的文章,几年前(2011~2013 左右)都会提到选择器的优化。简单来说就是浏览器渲染样式,选择器是从右向左进行查找的,所以:
1 | .news li { |
该段代码,会先找到所有的li
标签,再筛选出在.news
下的li
标签,所以性能不如直接给li
标签添加类名,使用类选择器。
同时给出了效率列表,从高至低排序:
- id选择器(#myid)
- 类选择器(.myclassname)
- 标签选择器(div,h1,p)
- 相邻选择器(h1+p)
- 子选择器(ul > li)
- 后代选择器(li a)
- 通配符选择器(*)
- 属性选择器(a[rel=”external”])
- 伪类选择器(a:hover,li:nth-child)
来源 - CSS选择器的优化
但是,在现代浏览器下,使用标签选择器或者类选择器之间的差别已经可以忽略了。经过测试存在 10000 个标签时,可能只有 200ms 左右的渲染时间差别,如果考虑给li
标签加类名导致增加了html
文件字节数,总时间其实真的差不多。
易于维护
不过,从易于维护的角度来考虑,更建议使用类名选择器。
1 | <div class="goods"> |
这是一个商品页面,有商品标题、子标题以及商品信息,需要给商品标题设置颜色,给子标题设置文字大小,上面的样式实现了该需求。
之后由另一个人来维护,需要给子标题设置一个颜色,所以要先在html
文件内找到子标题对应的节点,而我们的html
文件可能是这样的:
1 | <div class="goods"> |
因为数据往往是通过ajax
请求后填充到页面中。到底哪个是子标题呢,从语义化的角度,能够猜测出small
可能是,那怎么确定呢,可以在浏览器打开页面右键审查元素,或者看看js
文件,在填充数据的时候是将子标题填充到了哪个标签中:
1 | var subTitle = data.subTitle; |
这两种方式都能够确定到底哪个标签是子标题,但是有没有更好的方式呢?如果直接给类名呢?
1 | <div class="goods"> |
只要看了html
,就知道要在样式文件中搜索title_sub
就能够准确找到对应的样式。
组件化
还有一个理由就是,现在组件化的开发方式,要求我们将页面上的元素拆分为一个一个组件,尽可能通过组件的组合实现页面。
举个例子,一个新闻列表板块,可以分为Title
、List
、Item
三个组件:
这样划分是考虑到Title
很可能在其他地方也要使用,封装为组件便于复用。
样式,同样可以依照这个思路,所以样式会这样写:
1 | .title { |
1 | <body> |
重点是,在另一个地方同样需要相同样式的Title
,只是文字不同,就可以将html
结构复制,就能够快速得到相同样式的板块。
1 | <div class="goods"> |
同时可以注意到,.news
与.goods
都是和页面,或者说和业务有关的,这些无法“复用”的组件,就负责最终的布局,一般是设置位置与大小。
如果是react
或者Vue
,代码可能会是这样的:
1 | <div class="news"> |
总结
写代码的过程中,不只是实现功能,更多的要有自己的思考,总结出如何更好更快的写代码,就能够节省更多时间做其他的事情了。