W3C-CSS工作组特邀专家对CSS编码技巧终极揭秘(上)

 2016-09-23 08:05

《CSS揭秘》这本书的引言中,讲述了Web标准的制定过程,谈及了CSS3、CSS4以及其他传说,并且讲述了浏览器前缀的故事。但这些都不是我们所关注的,今天,我们重点说说引言中的CSS编码技巧。

尽量减少代码重复

在CSS开发中,应该尽量保存代码的DRY(Don'trepeatyourself)和可维护性。这是众多设计师所追去的。

举例来说,如果在放大一个按钮时需要在一堆规则中进行10 处修改,那就很可能会漏改其中某处,灵活的CSS 通常更容易扩展: 在写出基础样式之后,只用极少的代码就可以扩展出不同的变体,因为只需覆盖一些变量就可以了。现在,我们想做一个这样的按钮:

20160923082041.png

padding: 6px 16px;  
border: 1px solid #446d88;  
background: #58a linear-gradient(#77a0bb, #58a);  
border-radius: 4px;  
box-shadow: 0 1px 5px gray;  
color: white;  
text-shadow: 0 -1px 1px #335166;  
font-size: 20px;  
line-height: 30px;

这段代码在可维护性方面存在一些问题,我们来一一修复。

最软的杮子应该是跟字体尺寸相关的部分了。如果我们决定改变字号(可能是为了生成一个更大、更重要的按钮),就得同时调整行高,因为这两个属性都写成了绝对值。更麻烦的是,行高并没有反映出它跟字号的关系,因此我们还得做些算术,算出字号改变之后的行高该是多少。当某些值相互依赖时,应该把它们的相互关系用代码表达出来。

◆让大小随之而变化

在这个例子中,行高是字号的1.5 倍。因此,把代码改成下面这样会更易维护:

font-size: 20px;  
line-height: 1.5;

既然跨出了这一步,我们为什么还把字号定为绝对长度值呢?如果改用百分比或em 单位就好多了:

font-size: 125%; /* 假设父级的字号是 16px */  
line-height: 1.5;

现在,如果我们改变父级的字号,按钮的尺寸就会随之变化。但是,它看起来很不协调,因为所有其他效果都是为一个小按钮设计的,并没有跟着缩放。如果我们把这些长度值都改成em单位,那这些效果的值就都变成可缩放的了,而且是依赖字号进行缩放。

按照这种方法,我们就可以在一处控制按钮的所有尺寸样式了:

padding: .3em .8em;  
border: 1px solid #446d88;  
background: #58a linear-gradient(#77a0bb, #58a);  
border-radius: .2em;  
box-shadow: 0 .05em .25em gray;  
color: white;  
text-shadow: 0 -.05em .05em #335166;  
font-size: 125%;  
line-height: 1.5;

现在我们的大号按钮看起来更像是一个原按钮的等比例放大版本了。

请注意还有一些长度值是绝对值。此时就需要重新审视到底哪些效果应该跟着按钮一起放大,而哪些效果是保持不变的。比如在这个例子中,我们希望按钮的边框粗细保持在1px,不受按钮尺寸的影响。

◆颜色也是一重要变数

比如,假设我们要创建一个红色的取消按钮,或者一个绿色的确定按钮,该怎么做呢?

眼下,我们可能需要覆盖四条声明(border-color、background、box-shadow 和text-shadow),而且还有另一大难题: 要根据按钮的亮面和暗面相对于主色调#58a 变亮和变暗的程度来分别推导出其他颜色各自的亮色和暗色版本。此外,若我们想把按钮放在一个非白色的背景之上呢?显然使用灰色( gray)作投影只适用于纯白背景的情况。

其实只要把半透明的黑色或白色叠加在主色调上,即可产生主色调的亮色和暗色变体,这样就能简单地化解这个难题了:

padding: .3em .8em;  
border: 1px solid rgba(0,0,0,.1);  
background: #58a linear-gradient(hsla(0,0%,100%,.2),  
transparent);  
border-radius: .2em;  
box-shadow: 0 .05em .25em rgba(0,0,0,.5);  
color: white;  
text-shadow: 0 -.05em .05em rgba(0,0,0,.5);  
font-size: 125%;  
line-height: 1.5;

现在我们只要覆盖background-color 属性,就可以得到不同颜色版本的按钮了:

button.cancel {  
    background-color: #c00;  
}  
button.ok {  
    background-color: #6b0;  
}

我们的按钮现在已经非常灵活了。不过,这个例子并没有涵盖所有能让代码变得更DRY 的方法。你会在下面几节中发现更多的技巧。

  1. 代码易维护vs. 代码量少:

    有时候,代码易维护和代码量少不可兼得。比如在上面的例子中,我们最终采用的代码甚至比一开始的版本略长。我们要为一个元素添加一道10px 宽的边框,但左侧不加边框:

    border-width: 10px 10px 10px 0;

    只要这一条声明就可以搞定了,但如果日后要改动边框的宽度,你需要同时改三个地方。如果把它拆成两条声明的话,改起来就容易多了,而且可读性或许更好一些:

    border-width: 10px;  
    border-left-width: 0;


  2. currentColor:

    在CSS 颜色(第三版)(http://w3.org/TR/css3-color)规范中,增加了很多新的颜色关键字。我们得到了一个特殊的颜色关键字currentColor,它是从SVG 那里借鉴来的。这个关键字并没有绑定到一个固定的颜色值,而是一直被解析为color。实际上,这个特性让它成为了CSS 中有史以来的第一个变量。

    举个例子,假设我们想让所有的水平分割线(所有<hr>元素)自动与文本的颜色保持一致。有了currentColor 之后,我们只需要这样写:

    hr {  
        height: .5em;  
        background: currentColor;  
    }

    你可能已经注意到了,很多已有的属性也具有类似的行为。举例来说,如果你没有给边框指定颜色,它就会自动地从文本颜色那里得到颜色。这是因为currentColor 本身就是很多CSS 颜色属性的初始值,比如border-color和outline-color,以及text-shadow和box-shadow的颜色值,等等。


  3. 继承:

    尽管绝大多数开发者都知道有inherit这个关键字,但还是很容易遗忘它。inherit可以用在任何CSS 属性中,而且它总是绑定到父元素的计算值(对伪元素来说,则会取生成该伪元素的宿主元素)。举例来说,要把表单元素的字体设定为与页面的其他部分相同,你并不需要重复指定字体属性,只需利用inherit的特性即可:

    input, select, button { font: inherit; }

    与此类似,要把超链接的颜色设定为与页面中其他文本相同,还是要用inherit:

    a { color: inherit; }


20160923093621.png

这个inherit关键字对于背景色同样非常有用。举个例子,在创建提示框的时候,你可能希望它的小箭头能够自动继承背景和边框的样式:


.callout { position: relative; }  
.callout::before {  
content: "";  
position: absolute;  
top: -.4em; left: 1em;  
padding: .35em;  
background: inherit;  
border: inherit;  
border-right: 0;  
border-bottom: 0;  
transform: rotate(45deg);  
}
作者头像

作者:紫铜炉

自由博主,网页设计师。我关注科技产品和个人博客发展,注重用户体验和界面优化。

 发表评论: