精简CSS代码

十度 CSS 2016年03月29日 收藏

精简CSS代码可以帮助减小样式文件的大小,使代码清晰,方便维护。

使用简写属性及默认值

  1. .header {
  2.   margin-top: 10px;
  3.   margin-right: 20px;
  4.   margin-bottom: 30px;
  5.   margin-left: 40px;
  6. }
  7.  
  8. /* 可以使用简写属性 margin */
  9. .header {
  10.   margin: 10px 20px 30px 40px; /* 4个值分别对应方向为 top right bottom left */
  11. }
  12.  
  13. /* ========== 我是分割线 ========== */
  14.  
  15. .nav-list {
  16.   font-style: italic;
  17.   font-variant: small-caps;
  18.   font-weight: bold;
  19.   font-size: 14px;
  20.   font-family: Georgia, Serif;
  21.   line-height: 24px;
  22. }
  23.  
  24. /* 可以使用简写属性 font */
  25. .nav-list {
  26.   font: italic small-caps bold 14px/24px Georgia, Serif;
  27. }

常用简写属性包括 animation、background、border、font、margin、padding、transition...

使用简写的 font 属性时如果不使用 icon 等关键字时至少要指定 font-sizefont-family 属性,并且 font-size 必须位于 font-family 之前,其他的属性(如font-weight,font-style,font-variant)如未指定将自动使用默认值,并且必须位于 font-size 之前,line-height 必须位于 font-size 之后,并且和 font-size 用 “/” 分隔

 

省略了部分简写属性值的时候,缺失的部分就会使用该属性的默认值,

  1. div {
  2.   font: 14px Serif;
  3. }
  4. /* 相当于 */
  5. div {
  6.   font: normal normal normal 14px/normal Serif; /* 1 */
  7. }
  8.  
  9. /**
  10.  * 1.此处缺失的 font-style/font-variant/font-weight/line-height 
  11.  * 都会被解析为默认值 normal,该默认值甚至会覆盖继承的值
  12.  * 这和下面的分开申明是有区别的
  13.  * 下面代码的 font-style/font-variant/font-weight/line-height 并没有申明,
  14.  * 则会继承自父元素,也就是 inherit
  15.  */
  16. div {
  17.   font-family: Serif;
  18.   font-size: 14px;
  19. }

如果对简写属性使用 !important,会将该简写属性下的所有子属性全部设置为重要。

可以指定不带颜色的边框实现变化效果

  1. {
  2.   border: 1px solid;  /* 边框颜色默认和字体颜色一样 */
  3.   color: red;
  4. }
  5.  
  6. a:hover {
  7.   color: green;  /* 字体颜色变化了,边框颜色也会跟着变化 */
  8. }

过渡效果可以精简到只需要指定一个持续时间就可以了

  1. transition: 0.4s;    /* transition-duration 不指定的话默认为 0s,那就没有效果了 */
  2. /* 相当于 */
  3. transition: all 0.4s ease 0s;

background-position 的默认值为 0% 0%,

  1. background-position: 0% 0%;

在使用简写 background 属性的时候可以省略,如果只省略其中一个,那么省略掉的那一个会变成 50%/center,

  1. background-position: 0%;
  2. /* 相当于 *
  3. /background-position: 0% 50%;

有几个例外的简写属性省略了的部分并不会使用默认值,而是从已有的值复制(可以这么理解),

比如包括 border-color, border-style, border-width, border-radius, margin, padding...

这些属性的特点是一个属性通常有4个值分别对应4个不同的方向,

  1. border-width: 1px; /* => */ border-width: 1px 1px 1px 1px; /* 复制3次 */
  2. margin: 10px 20px; /* => */ margin: 10px 20px 10px 20px; /* 复制1次 */
  3. padding: 10px 20px 30px; /* => */ padding: 10px 20px 30px 20px; /* 复制中间那个放在最后 */

还有就是有些用户代理(浏览器)样式表已经定义过的样式,同时在所有现代浏览器中都表现一致的话,没有必要再定义了,

  1. div {
  2.   display: block; /* 根本没有意义 */}

结论:有些属性如果你期望的值与默认值或者用户代理样式表指定的值是一致的,那么就可以省去不写,避免重复。

 

合理利用继承

通常情况下,指定了样式的元素的后代会自动继承某些样式属性,比如 color

  1. .content h1,
  2. .content div,
  3. .content p,
  4. .content ul,
  5. .content li {
  6.   color: #666;
  7. }
  8.  
  9. /* 这样更简单 */
  10. .content {
  11.   color: #666;
  12. }

注意,有些元素会带有浏览器默认样式,比如 h1 的 font-size,该默认样式会覆盖掉继承值

常用可继承属性包括 color, font, text-align, text-indent...

也可以强制指定一个不能继承的属性实现继承效果,

  1. div {
  2.   padding: inherit; /* 它自己继承了,但是它的后代依然是不能继承的 */}

 相对的,也可以强制指定一个应该继承的属性不继承,

  1. div {
  2.   font-size: initial; /* 恢复为默认值 */}

由于兼容的问题,这两个值并不是很常用。

结论:如果一个值可以通过继承得到,那就省去。

 

群组选择器

  1. h1 {color: blue;}
  2. h2 {color: blue;}
  3. h3 {color: blue;}
  4. h4 {color: blue;}
  5. h5 {color: blue;}
  6. h6 {color: blue;}
  7.  
  8. /* 这样更简单 */
  9. h1, h2, h3, h4, h5, h6 {color: blue;}

将具有很多相同样式的选择器群组在一起,可以有效地精简代码。比如这里定义了两个不相关的东西,

  1. .badge {
  2.   background-color: orange;
  3.   border-raidus: 5px;
  4.   color: #fff;
  5.   font-size: 13px;
  6. }
  7.  
  8. 中间还有很多其它样式
  9.  
  10. .label {
  11.   background-color: orange;
  12.   border-raidus: 5px;
  13.   color: #fff;
  14.   font-size: 12px;
  15. }

对比发现两者有很多相同的样式,把相同的样式群组后,

  1. .badge,
  2. .label {
  3.   background-color: orange;
  4.   border-raidus: 5px;
  5.   color: #fff;
  6. }
  7.  
  8. 中间还有很多其它样式
  9.  
  10. .badge {
  11.   /* 只看这里的话看不出来该类还有其它样式 */
  12.   font-size: 13px;
  13. }
  14.  
  15. 中间还有很多其它样式
  16.  
  17. .label {
  18.   /* 只看这里的话看不出来该类还有其它样式 */
  19.   font-size: 12px;
  20. }

这样造成同一个组件的样式散落在各处,维护会变得困难,使用 CSS 预处理器可以有效解决这个问题,比如 Sass 的 %占位符语法,几乎就是为群组选择器量身打造的,

  1. %label {
  2.   background-color: orange;
  3.   border-raidus: 5px;
  4.   color: #fff;
  5. }
  6.  
  7. 中间还有很多其它样式
  8.  
  9. .badge {
  10.   /* 在这里可以清晰地看出来该类还有其它样式 */
  11.   @extend %label;
  12.   font-size: 13px;
  13. }
  14.  
  15. 中间还有很多其它样式
  16.  
  17. .label {
  18.   /* 在这里也可以清晰地看出来该类还有其它样式 */
  19.   @extend %label;
  20.   font-size: 12px;
  21. }

群组选择器的时候需要注意不要将有浏览器兼容性的选择器群组在一起,会造成不能识别而忽略整个规则集,以下代码就不能群组在一起,

  1. input::-webkit-input-placeholder {
  2.   color: #999;
  3. }
  4.  
  5. input::-moz-placeholder {
  6.   color: #999;
  7.   opacity: 1;
  8. }
  9.  
  10. input:-ms-input-placeholder {
  11.   color: #999;
  12. }

十六进制RGB颜色值

如果每两位都相等,则可以简写

  1. color: #ff3300;/* 可以简化为,其代表的颜色是一样的 */
  2. color: #f30;

 

使用较短的具体数值代替较长的关键字

  1. h2 {
  2.   font-weight: 700;
  3. }
  4.  
  5. {
  6.   font-weight: 400;
  7. }
  8.  
  9. /* 相当于 */
  10. h2 {
  11.   font-weight: bold;
  12. }
  13.  
  14. {
  15.   font-weight: normal;
  16. }

数字 400 等价于 normal,而 700 等价于 bold。

 

简化背景图片路径

背景图片路径可能会是这样,

  1. background-image: url("../../images/bg.gif");

背景图片和CSS文件分这么开起什么作用呢?两者本来就是密切相关的,所以应该把背景图片文件夹和CSS文件放在同一目录下,那路径就会变成这样

  1. background-image: url("images/bg.gif");

简单多了,甚至图片文件夹根本没必要命名为复数形式,如果路径中没有空格或者一些特殊符号,引号也可以去掉,

  1. background-image: url(img/bg.gif);

再进一步,用一个字母来命名图片文件夹,

  1. background-image: url(i/bg.gif);

虽然文件夹的名字已经没有什么语义了,但是,通常在这个目录下常用的也就两个文件夹而已,一个图片文件夹,一个字体文件夹,还有可能会有一个放置其它文件的文件夹,对于背景图片相对较多的情况来说这种方式可以减少相当可观的代码字节量。

可以在 Sass 中把路径保存为一个变量以方便任意切换,

  1. $bg-path: "../images" !default;
  2. ...background-image: url(#{bg-path}/bg.gif);

 

去掉 0 值的单位

  1. margin: 0px;/* 为0的值带不带单位都是0 */margin: 0;

 

Firefox暂时不支持去掉为0的时间值的单位,也就是说 

  1. transition: color 0.5s linear 0; /* 当前 Firefox(28.0) 会忽略这条属性 */

与其这样,不如干脆就不指定这类值,通常情况下默认的值就是 0秒

  1. transition: color 0.5s linear; /* 完事 */

 

去掉浮点数两端的0

  1. div {
  2.   background-color: rgba(0,0,0,0.3);
  3.   opacity: 0.9}

对于不透明度,去掉小数点前面的0也可以很好的理解,因为它不会大于1

  1. div {
  2.   background-color: rgba(0,0,0,.3);
  3.   opacity: .9;
  4. }

不过对于其它可能大于1的浮点值来说,也许会让其他人以为你是忘记了小数点前面的数,

  1. transition: all .5s;

 

去掉ID选择器前面的限定符

ID本来就是唯一的,在前面加上元素限定和祖先元素通常情况下都是没有意义的,

  1. .container div#box { }/* 精简后 */#box { }

 

下面的内容多多少少有点喜新厌旧的意思了

去掉老旧浏览器兼容代码

  1. body {
  2.   text-align: center;
  3. }
  4.  
  5. .container {
  6.   margin: 0 auto;
  7.   text-align: left;
  8.   width: 960px;
  9. }
  10.  
  11. /* 上面的代码是为了实现怪异模式下的 IE 以及 IE5.x 的块元素居中效果 */
  12. .container {
  13.   margin: 0 auto;
  14.   width: 960px;
  15. }

请始终使用标准模式,如今IE6/7/8 都要面临淘汰了。

 

去掉多余的浏览器前缀

还在你的CSS代码中写一大堆浏览器厂商前缀吗?那你就out了!

  1. .header {
  2.   -webkit-border-radius: 5px;
  3.      -moz-border-radius: 5px; /* 1 */
  4.       -ms-border-radius: 5px; /* 2 */
  5.        -o-border-radius: 5px; /* 3 */
  6.           border-radius: 5px;
  7. }
  8.  
  9. /**
  10.  * 1.新版本的 Firefox 已经不再支持 -moz-border-radius 属性,
  11.  *   同时,从 Firefox 4.0 就开始支持标准的 border-radius 写法了。
  12.  * 2.IE 9+ 支持标准的 border-radius 写法,IE 8 及更低版本什么写法都不支持。
  13.  * 3.Opera 10.50+ 支持标准的 border-radius 写法
  14.  * 换芯后的 Opera 同时还支持 -webkit-border-radius 写法
  15.  */
  16. .header {
  17.   -webkit-border-radius: 5px;
  18.           border-radius: 5px;
  19. }
  20. /* 更进一步 */
  21. .header {
  22.   border-radius: 5px; /* 4 */
  23. }
  24.  
  25. /**
  26.  * 4.另外 Android 2.1+, iOS 4.0+, Safari 5+ 均支持标准 border-radius 写法
  27.  */

可以使用 Sass 定义一个 Mixin 来完成这件事情,

  1. @mixin border-radius($radius) {
  2.   -webkit-border-radius: $radius;
  3.           border-radius: $radius;
  4. }
  5.  
  6. .header {
  7.   @include border-radius(5px);
  8. }

用 Less 同样,

  1. .border-radius(@radius) {
  2.   -webkit-border-radius: @radius;
  3.           border-radius: @radius;
  4. }
  5.  
  6. .header {
  7.   .border-radius(5px);
  8. }

将常用的 CSS3 属性全部封装成 Mixin,既可以减少代码量,也可以很好地控制哪些浏览器前缀应该去掉,而哪些应该保留,当某个前缀不再需要的时候可以很轻松地删掉,更多资料请参考 http://css3please.com/,在这里你可以更清楚地看到某个属性需要哪些浏览器厂商前缀,也可以参考使用以下项目,都有很成熟的 Mixins 供使用,

还有,就是压缩代码了!关于代码压缩的内容,就不在这里说了!