可维护css,编写高性能可维护的css代码

[TOC]

前言

CSS代码重构的目的:

我们写CSS代码时,不仅仅只是完成页面设计的效果,还应该让CSS代码易于管理,维护。我们对CSS代码重构主要有两个目的:

1、提高代码性能

2、提高代码的可维护性

在这里我主要讲解CSS代码性能提升的一些知识。

性能优化

性能优化是一门做减法的艺术。我们首要要尽力简化页面渲染过程,然后要使渲染过程的每一步都尽量高效。

提高CSS代码性能主要有两个点:

1、提高页面的加载性能

提高页面的加载性能,简单说就是减小CSS文件的大小,提高页面的加载速度,尽可以的利用http缓存

2、提高CSS代码性能

不同的CSS代码,浏览器对其解析的速度也是不一样的,如何提高浏览器解析CSS代码的速度也是我们要考虑的

[TOC]

1.CSS选择器

CSS选择器具有高效的继承性,引用Steve Souders的话, CSS选择器效率从高到低的排序如下:

ID选择器 比如#header

类选择器 比如.promo

元素选择器 比如 div

兄弟选择器 比如 h2 + p

子选择器 比如 li > ul

后代选择器 比如 ul a 7. 通用选择器 比如 *

属性选择器 比如 type = “text”

伪类/伪元素选择器 比如 a:hover

以上引用自Steve Souders的Even Faster网站

纵使ID选择器很快、高效,但是它也仅仅如此,,尽量不要再css里面使用id。从Steve Souders的CSS Test我们可以看出ID选择器和类选择器在速度上的差异很小很小。

1.1组合选择器

你可以有一个标准的选择器比如#nav,来选择任何在此元素下的后代元素。此刻,我们读这些是从左到右的方式。我们是先找到#nav,然后从它的里面找其他元素。但是浏览器解析这些不是这样的:浏览器解析选择器是从右到左的方式。

如果想要知道更多浏览器这样解析的原因,请看Stack Overflow上的讨论

1.2关键选择器

渲染样式时重要的是选择器的最后面的部分即为关键选择器(即用来匹配目标元素的那部分,而不是该元素的祖先元素)。在以下例子中将使用该术语讲解。

例如,在下面规则中:

a img,

div > h1,

h1 + p {

}

关键选择器为:img、h1、p

CSS规范并没有明确浏览器如何去实现样式系统,仅仅是说明了它们必须这样做。有鉴于此,不同的样式系统引擎可能会拥有完全不同的表现和行为,特别是 Gecko 与 WebKit, 这两个引擎都是开源项目,实现了类似的算法,具有极其相近的优缺点。接下来就让我们一睹样式系统如何工作...

[TOC]

2.样式系统工作原理

2.1样式系统如何拆分规则

编写好的CSS代码,有助提升页面的渲染速度。本质上,引擎需要解析的CSS规则越少,性能越好。样式系统将规则拆分成四个主要类别,如下所示,性能依次降低。

ID规则

class规则

标签规则

通用规则

理解这些分类是十分关键的,因为它们是构建规则匹配块的基础。

ID规则

即包含了那些将 ID 选择器作为关键选择器的规则。

示例

#nav {.....}

a#person-intruc {.....}

#nav[href="#"] {.....}

.....

class规则

如果一个规则将一个 class 明确作为它的关键选择器,那么它就属于该类别。

示例

.nav {.....}

a.person-intruc {.....}

.nav[href="#"] {.....}

.....

标签规则

如果既没有 class 也没有 ID 来明确作为关键选择器,那么接下来的候选者就是 标签 类别。 如果一条规则将一个标签作为它的关键选择器,那么这条规则就属于该类别。

示例

li {.....}

a > img {.....}

a[href="#"]{.....}

p+ul{.....}

.....

通用规则

不属于上面那些类别的规则都属于这个类别。

示例

[hidden="true"] {…} /* A universal rule */

* {…} /* A universal rule */

tree > [collapsed="true"] {…} /* A universal rule */

2.2样式系统如何匹配规则

样式系统从关键选择器开始匹配规则,然后左移(查找规则选择器的任何祖先元素)。只要选择器的子树(substree)一直在检查,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该条规则。在这其中涉及到规则过滤的基本概念,分类的意义恰恰在此,过滤掉无关的规则(避免浪费时间去匹配)。

现在问题来了,那么什么样式的CSS代码能够更快的匹配,不浪费时间呢?

[TOC]

3.高效的CSS代码编写

3.1避免使用通用规则和单个属性选择器作为关键选择器

如*、[hidden="true"]等通用规则十分浪费匹配时间。不必要时尽量不使用。

3.2避免过度约束

不要用标签名或 classes 来限定 ID 规则,不要用标签名限定 class 规则

如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签名。因为 ID 是唯一的,增加标签只会没必要地减缓匹配过程。

对于ID的在class这里同样适用。标签可能会随着设计改变,所以仅仅选择严格语义化的名字作为类名并运用是很好的选择。

【注意】定义过多id会使重用性降低,维护更困难,所以不建议多用id。

尽量使用最具体的类别,即能一次搞定就一次搞定。解析速度变慢的罪魁祸首就是标签类别中有过多的规则。通过增加 class 到元素上,我们就可以进一步的将这些规则划分到 Class 类别中,这将减少用于匹配标签的时间。

3.3避免后代选择器

后代选择器是 CSS 中性能耗用最大的选择器。它的性能开销相当大——特别是当选择器在标签或通用类别中。通常我们需要的是 子选择器。不仅性能低下而且代码很脆弱,html代码和css代码严重耦合,html代码结构发生变化时,CSS也得修改。

treehead treerow treecell {…}

略好,但还是差(查看下一条指南)

treehead > treerow > treecell {…}

3.4标签分类的规则不要包含子选择器

标签类别的规则中避免使用子选择器。否则的话,在该元素出现的所有地方,匹配时间都将极大延长(特别是当规则很可能会被匹配)。

treehead > treerow > treecell {…}

好//采用class规则

.treecell-header {…}

当使用子选择器时要十分谨慎。能免则免。

3.5了解依赖继承,减少代码量

了解哪些属性能够继承,然后允许它们这样做!

不可以继承的属性:

position、z-index、top、right、bottom、left、clip、display、

可以继承的属性:

color、font、text-transform、white-space、tab-size、word-break、word-wrap、overflow-wrap、text-align、text-align-last、text-justify、word-spacing、letter-spacing、text-indent、line-height、text-size-adjus、text-shadow、direction、writing-mode、list-style、list-style-image、list-style-position、list-style-type、table-layout、border-collapse、border-spacing、empty-cells、quotes、cursor、zoom、pointer-events

3.6避免链式(交集)选择符

// bad

.menu.left.icon {..}

// good

.menu-left-icon {..}

3.7尽可能精简规则、尽量不要在选择符定义过多层级,层级越少,同时也降低了css和dom结构的耦合程度,提高样式的可维护性

定义简洁的css规则

使用复合(紧凑)语法

// bad

.someclass {

padding-top: 20px;

padding-bottom: 20px;

padding-left: 10px;

padding-right: 10px;

background: #000;

background-image: url(../imgs/carrot.png);

background-position: bottom;

background-repeat: repeat-x;

}

// good

.someclass {

padding: 20px 10px 20px 10px;

background: #000 url(../imgs/carrot.png) repeat-x bottom;

}

【特别注意】合理使用简写

你可能知道,以下两行 CSS 代码并不是等价的:

background: rebeccapurple;

background-color: rebeccapurple;

前者是简写,它可以确保让你得到 rebeccapurple 纯色背景;但如果你用的是展开式的单个属性(background-color),那这个元素的背景最终有可能会显示为一个粉色的渐变图案、一张猫的图片、或任何东西,因为同时可能会有一条 background-image 声明在起作用。通常在使用展开式属性的写法时,会遇到这样的问题:展开式写法并不会帮助你清空所有相关的其他属性,从而可能会干扰你想要达到的效果。

了解更多,请参考CSS 编码技巧

避免不必要的命名空间

// bad

.someclass table tr.otherclass td.somerule {..}

//good

.someclass .otherclass td.somerule {..}

避免不必要的重复

// bad

.someclass {

color: red;

background: blue;

font-size: 15px;

}

.otherclass {

color: red;

background: blue;

font-size: 15px;

}

// good

.someclass, .otherclass {

color: red;

background: blue;

font-size: 15px;

}

在上面规则的基础上,合并相同定义(进一步合并不同类里的重复的规则),删除无效的定义

3.8避免 !important

更多关于!important请仔细阅读该篇文章!important 的重要性:CSS 不变性。建议阅读英语版本,该篇中文翻译某些地方感觉不太恰当。仅仅在不得不使用它的时候辅助规则

3.9避免使用CSS表达式和滤镜

使用CSS 的expression()通常会造成多次运算。实际上,需要用到CSS表达式的地方,通常能够找到其他替代方案,所以避免使用CSS表达式。

那么什么是css expression?

IE5及其以后版本支持在CSS中使用expression,用来把CSS属性和Javascript脚本关联起来,这里的CSS属性可以是元素固有的属性,也可以是自定义属性。就是说CSS属性后面可以是一段Javascript表达式,CSS属性的值等于Javascript表达式计算的结果。在表达式中可以直接引用元素自身的属性和方法,也可以使用其他浏览器对象。

3.10关于@import

import规则一定要先于除了@charset的其他任何CSS规则,尽可能少用该方法引进。在编写scss时如果引进文件需要合并需采用@import "xxx.scss"。

示例:

#myDiv {

position: absolute;

width: 100px;

height: 100px;

background:#c00;

left: expression(document.body.offsetWidth - 180 "px");//这儿

top: expression(document.body.offsetHeight - -80 "px");//这儿

text-align:center;

line-height:90px;

color:#fff;

}

[TOC]

4.CSS中的图片处理

4.1不给图片设置不符合自身的尺寸(即缩放)

【解释】:、同一张图片可能会在页面不同地方多次使用,比如缩略图、正常图、大图。问题来了,如果图片原始尺寸和实际需求不同,在使用过程中就会存在性能问题,利用样式缩放会带来cpu的额外计算过程,增加了图片在浏览器的渲染时间,网络传输过程也会占更多带宽,增加下载时间。因此,最佳做法是,为需要的部分单独做一套图片,初始页面加载时就能更快展示。

4.2使用css"雪碧图"

是将零散的图片合并成一张大图,在利用css进行背景定位。好处是减少请求数,提高了图片整体的加载速度。

但它也存在一些缺点:

比如,多张图片合并成大图,需要精确计算,仔细的调整位置,单纯手工制作是一件很复杂的事情。(所幸现在有一些工具可以帮我们做)

另外,维护过程复杂,要尽量让已有的图片保持原来的位置不变,如果是背景图的尺寸发生变化导致原有区域无法放置,那就只好放弃,如果非要在原有位置修改,则剩余的图片样式都需要修改,是很繁琐的过程。新加的图片最好放在最后面。

使用不当会导致性能问题,最大的问题就是内存消耗。如果制作过程不做任何的规划,随意摆放,则可能会使图片变得相当大,从而很占内存。

建议

雪碧图的尺寸要优化好,空白尽可能少;

及时清理不再使用的图片;

将雪碧图权重做分离,全局/框架级的和局部/模块级的分离开;

缓存设定和更新频率匹配,如果将每天更新的雪碧图的缓存设置到一个月很容易出问题的。

4.3最佳实践

1、在项目后期应用css sprite技术

因为一般在开发过程中,会比较频繁的修改或者更换图片,如果这个时候使用sprite技术,就会增加很多开发成本。

2、合理组织“雪碧”图

如果要把所有的图片放在一张图上面,也会有不妥,维护方面也不会很方便。组织背景图主要按照模块和背景图的风格来划分。比如,作为展示的缩略图放在一起,评论、点赞、上下箭头等图标放在一起等。

3、控制“雪碧”图的尺寸和大小

因为大尺寸的图片会占用大量的内存,所以要控制在合理尺寸,推荐长宽相乘不超过2500,大小在200kb内

4、合理控制背景图单元间的距离及背景图位置

这个原则是为了防止在背景图比元素大小更小的时候,区域出现别的无关背景图

5、借助相关工具处理sprite

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值