Skip to content

改善CSS编写习惯

即便你已经掌握了 CSS 提供的全局属性,知道如何修补烦人的浏览器缺陷,也学会了制作精美网页的技巧,仍然要学习一些方法,让 CSS 更易于创建、使用和维护

添加注释

创建样式表几周后、几个月后或者几年后,如果要修改,你可能会苦苦思索: “当时我为什么创建这个样式?它有什么用?” 与所有项目一样,构建网站时应该记录做了什么,为什么那样做。
幸好,我们不用在一叠纸上记录。我们可以使用 CSS 注释,把说明写在样式表里

CSS 注释是写在 /**/ 之间的说明。与 HTML 注释一样,Web 浏览器不会读取或解析 CSS 注释,但是使用 CSS 注释可以在样式表中添加有用的提示。
我们无需为样式表中的所有代码添加注释,毕竟,大多数属性,如 color、font-family、border-color 等,都不解自明。
但是,如果样式或属性的作用不明显,就可以加上注释。例如,我们可能会重设 CSS 的盒模型,把元素的边框和内边距算在宽度和高度内:

1
2
3
* {
    box-sizing: border-box;
}

编写这个样式时,我们知道在做什么,可是,三个月之后还能记得吗?如果不熟悉这个技巧的人以后想编辑你编写的 CSS 呢?添加注释吧,这样你自己和维护网站的其他人就知道这个样式的作用,以及创建样式的原因:

1
2
3
4
/* 让宽度值包括内边距和边框 */
* {
    box-sizing: border-box;
}

如果要说的内容很多,可以把注释写成多行。我们只需以/*开头,然后输入全部注释,最后再以*/结尾。如图所示:

CSS添加注释示例

图18-1 CSS 注释可以表述样式的作用,方便以后编辑。此外,还可以使用注释提供有用的介绍信息,记录网站或样式表的版本和版权信息,注明自己是 CSS 代码的作者

注意,添加注释就是在文件中添加代码,这会导致文件体积变大,下载速度变慢。其实,添加大量注释后才会对文件的下载速度有明显影响。
把 CSS 文件上传到服务器之前,可以使用在线工具,如CSSMinifier(http://cssminifier.com),去掉注释。不过,Sass 是更好的工具。

合理组织样式

我们已经学了很多创建样式和样式表的知识。如果想让你设计的网站长久发展,还要采取几项措施,为将来做打算。
你总有一天会修改网站的外观,调整某个样式,或者把工作交给其他人负责。除了为自己和他人留下说明之外,我们还要做些规划,合理地组织 CSS,让未来的发展道路更平顺。

类的名称要清晰明确

我们已经学过命名不同类型选择符的技术原则,知道类选择符以点号(.)开头,把样式标识为类样式;也知道 ID 样式以#开头。
此外,ID 和类名必须以字母开头,不能包含符号,如&*!。除了遵守这些规则之外,我们还可以采用一些经验法则,让样式的条理更清晰,从而提高工作效率。

根据用途而不是外观来命名类

如果某个样式使用消防车那样吸引力强的红色装饰文本,你可能想把样式命名为.redhighlight
可是,如果你(或者你的上司或客户)觉得橙色、蓝色或浅绿色更好看,那该怎么办呢?
事实情况是,如果样式的名称是.redhighlight,而真正使用的是浅绿色,会让人摸不着头脑。使用能描述样式用途的名称更好。
如果醒目的红色是为了表示访客填写表单过程中出现的错误,可以使用.error这个名称。
如果样式装饰的是提醒访客的重要信息,可以命名为.alert。这样,修改样式里的颜色或其他格式选项就不会让人困惑,因为不管使用什么颜色,样式的作用仍然是提醒访客。

类似地,不要使用包含具体大小的名称,如.font20px。今天使用的字号可能是 20 像素,或许明天就会改成 24 像素,或者把 px 改成 em 或百分比了。
使用标签选择符或许更好: 把字号应用到<h2><p>标签上,甚至还可以使用后代选择符,如.sidebar p

不要使用体现位置的名称

与不要根据外观命名的原因一样,我们也要避免根据位置命名。
有时,.leftSidebar 这样的名称看起来非它莫属,因此“我想把这些内容组织在一起,放到页面的左边!”可是,以后你(或其他人)可能想把左侧边栏移到页面右边、上边,甚至是底部。这样一来,使用.leftSidebar这个名称就完全说不通了。
那个侧边栏的名称更能更好地表明它的用户,如.news.events.secondaryContent.mainNav,而不管它在页面中的位置。

我们很容易使用.header.footer这样的名称(分别表示位于页面顶部和底部的元素),因为特别易于理解,可是,通常有更好的名称能表明内容的作用,例如,可以用.branding代替.header
不过,有时使用带有位置信息的名称却是合理的。比如说我们想创建两个样式,一个把图像浮动到页面的左边,一个把图像浮动到页面的右边。
因为这两个样式的作用只是把图像放在左边或右边,所以名称中可以带有位置信息。因此,完全可以使用.floatLeft.floatRight这两个名称

不要使用晦涩的名称

.s.s1.s2 这样的名称可以让我们少按几次键盘,也能让文件稍微小些,不过,升级网站时会带来麻烦。
到时,你会直抓脑袋,想知道这些奇怪的样式有什么用。起名时应该简洁,但也要明了。
.sidebar.copyright.banner 这样的名称不需要花多长时间输入,但是作用不言自明。

注意: 从别人的网站采用的命名约定中也能学到很多。大多数浏览器都内置了 Web 审查器,使用这个工具可以快速查看样式的名称

不要自我重复

重复输入相同的代码不仅浪费时间,还为样式表添加了多余的代码,导致样式表下载速度变慢。
如果页面中几个元素看起来十分相似,只有些许差别,可能会发现自己要重复输入相同的 CSS 属性

比如说按钮分成三种类型: 橙色按钮用于把物品添加到购物车里,红色按钮用于从购物车中删除物品,绿色按钮用于提交订单。
在 HTML 代码中可以分别为三个按钮设置不同的类,如下所示:

1
2
3
<button class="add">Add to Cart</button>
<button class="delete">Delete</button>
<button class="order">Submit Order</button>

然后创建三个样式,如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
.add {
    border-radius: 30x;
    font: 12px Arial, Helvetica, sans-serif;
    color: #444;
    background-color: orange;
}
.delete {
    border-radius: 30x;
    font: 12px Arial, Helvetica, sans-serif;
    color: #444;
    background-color: red;
}
.order {
    border-radius: 30x;
    font: 12px Arial, Helvetica, sans-serif;
    color: #444;
    background-color: green;
}

注意,这三个样式中的大部分属性是一样的。重复的代码不仅增大了文件的体积,而且,如果决定修改按钮的字体,一次实现不了,要编辑三个样式。

更好的方法是,创建一个所有按钮共用的基础样式,再分别创建实现差异化的样式。
例如,我们使用<button>标签标识按钮,那就为这个标签创建一个样式,应用到所有按钮上,然后再创建三个样式,分别应用到各个按钮上,如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
button {
    order-radius: 3px;
    font: 12px Arial, Helvetica, sans-serif;
    color: #444;
}
.add {
    background-color: orange;
}
.delete {
    background-color: red;
}
.order {
    background-color: green;
}

这样做,不仅代码量少,而且更易于管理。如果想修改所有按钮的字体,只需在 button 样式里修改一次

使用多个类可以节省时间

我们可以使用多个类,进一步践行“不要自我重复”原则。比如说,我们想让一些图像向左浮动,右边有些外边距;
还想让一些照片向右浮动,左边有些外边距。而且,这两种图像都使用相同的边框样式。但是,不想让页面中的所有图像都有边框。如图 18-2 所示。

最明显的方法是,创建两个类样式,每个样式中都设置相同的边框属性,但是浮动和外边距不同。
然后,把一个类样式应用到应该向左浮动的图像上,把另一个类样式应用到应该向右浮动的图像上。
可是,如果要更新这些图像的边框样式呢?我们要编辑两个样式,如果忘了一个,页面一边的图像就会使用错误的边框。

图18-2

图18-2 图中两张照片使用了相同的类样式。那个样式为图像提供四周的边框。
此外,左边的图像还用了一个类样式,其作用只是向左浮动图像;右边的图像用了不同的类样式,把图像向右浮动。也就是说,每个图像都有两个类

有个技巧所有浏览器都支持,但并不是所有设计师都知道--在同一个标签上使用多个类。
意思是,设置标签的 class 属性时,提供两个(或更多个)类名,例如<div class="note alert">。在这个示例中,<div>标签会使用.note.alert两个样式里的格式指令。

假如我们想让一组图像使用相同的边框样式,但是想让某些图像向左浮动,另一些图像向右浮动,可以像下面这样做:

1.创建一个类样式,在样式里写入所有图像共用的格式属性
我们可以把这个样式命名为.imgFrame,在样式里把四个变的边框都设为 2 像素宽的黑色实线

2.再创建两个类样式,一个用于向左浮动图像,另一个用于向右浮动图像
例如,分别命名为.floatLeft.floatRight。其中一个样式包含一部分图像专用的样式(向左浮动,右边有些外边距),另一个样式包含另一部分图像专用的属性

3.每个标签上都设置两个类,如下所示:

<img src="photo1.jpg" height="100" class="imgFrame floatLeft">

<img src="photo1.jpg" height="100" class="imgFrame floatRight">

此时,每个标签上都有两个类,Web 浏览器会把两个类样式里的属性结合起来,应用到标签上。
现在,如果想修改边框样式,只需修改一个样式.imgFrame就能改变向左或向右浮动的图像的边框

注意: 这种方法不局限于只能使用两个类。我们只需记得在类之间添加空格

如果只想修改某个元素的部分属性,而不影响其他外观相似的元素,也可以使用这个方法。
我们可能想创建一个通用的侧边栏,浮动在右边,为其添加好看的背景图,还仔细装饰了排版。
在网站中可以多次使用这个样式,不过在不同的地方,侧边栏的宽度有所不同,在某些页面中的宽度是 33%,而在另一些页面中的宽度则是 25%。
此时,我们要创建一个类样式(如.siddbar),定义侧边栏的基本外观,再创建几个样式,定义不同的宽度,如.w33per.w25per
然后,在各个侧边栏上应用两个类样式,例如<div class="sidebar w33per">

使用属性的简写形式

很多 CSS 属性可以使用简写形式简化,这样能减少代码量,也能减少按键次数。
例如,padding 属性可以代替四个内边距属性: padding-top, padding-right, padding-bottom 和 padding-left。因此,下述代码:

1
2
3
4
5
6
td {
    padding-top: 5px;
    padding-right: 10px;
    padding-bottom: 5px;
    padding-left: 10px;
}

可以替换成:

1
2
3
td {
    padding: 5px 10px;
}

有简写形式的属性包括: 字体,边框,内边距,外边距,过度,背景和列表。如果记住这些简写形式,能提高工作的效率。

提示: 如果属性的值是某种度量值,例如 30px、40% 和 10em,而且值为 0,可以省略单位。也就是说,应该写成:

1
padding: 0;

而不是:

1
padding: 0px;

把相关的样式放在一起

逐个编写样式是构建样式表的常规方式,但是要不了多久,只有五个样式的 CSS 文件会变成有 500 个样式。那时,如果想迅速找到要修改的样式,像大海捞针一样难(当然,大海没有“查找”功能。不过,我想你应该明白我的意思)。
如果从一开始就合理组织样式,从长远来看,你的生活会更轻松。组织样式的方式没有严格的规则,不过有两种常见做法:

  • 把页面相关部分的样式放在一起: 把装饰横幅中国呢文本、图形和链接的所有规则放在一起,把装饰主导航栏的规则放在一起,把装饰主内容区域的样式放在一起。
  • 把相同用途的样式放在一起: 把用于布局的样式放在一起,把用于排版的样式放在一起,把链接的样式放在一起,以此类推。

使用注释区分不同的样式分组:

不管采用哪种方法,记得要使用 CSS 注释引出各个样式分组。
比如说,我们把控制页面布局的样式集中放在样式表里的一个地方,那么,可以像下面这样使用注释引出这一组样式:

1
/* *** 布局 *** */

或者

1
2
3
/* ---------------------
          布局
--------------------- */

只要以 /* 开头,以*/结尾,里面可以随意使用星号、连字符或其他符号,让这种注释易于识别。有多少 Web 设计师,这种注释就有多少编写方式。

使用多个样式表

我们可以为不同的媒体类型创建不同的样式表,例如一个针对屏幕,一个针对打印机。不过,纯粹为了合理组织,也可以把屏幕设备使用的样式表分成多个。

如果一个样式表里的内容很多,难以查找和编辑样式,或许可以分成多个样式表,分别实现不同的功能。
我们可以把装饰表单的样式放在一个样式表里,把用于布局的样式放在一个样式表里,把设置颜色的样式放在一个样式表里,等等。
但是,文件的数量要合理,如果有 30 个外部样式表文件,根本节省不了时间。此外,外部样式表文件越多,Web 服务器要响应的请求越多。而这是影响网站性能的一个因素。

乍一看,这样做可能会导致网页的代码量变多,因为要链接或导入多个外部样式表,多一个文件就要多写一行代码。不过有个更好的方法: 创建一个外部样式表,在其中使用@import指令导入多个样式表。这种方法如图 18-3 所示

图18-3多个样式表

这种安排方式的做法如下:

1.创建多个外部样式表,装饰网站中不同的元素:
例如,创建一个 color.css 文件,控制网站使用的颜色;创建一个 forms.css 文件,装饰表单;创建一个 layout.css,控制布局;再创建一个 main.css 文件,存放其余的样式(如图 18-3 右边)

2.创建一个外部样式表,导入第一步创建的各个样式表
这个文件可以命名为 base.css、global.css、site.css,或者使用其他表示通用的名称。这个 CSS 文件中没有任何规则,而是使用@import指令导入其他样式表,如下所示:

1
2
3
4
@import url(main.css);
@import url(layout.css);
@import url(color.css);
@import url(forms.css);

在这个文件中只需写入上述代码,不过,也可以添加一些注释,包含版本号,网站名称等,说明这个文件的作用

3.最后,在网站的 HTML 页面中使用<link>标签或@import指令,链接第2步创建的那个样式表。例如:

1
<link rel="stylesheet" href="base.css">

现在,浏览器加载网页时,首先加载 base.css 文件,而这个文件会告诉浏览器,再加载四个样式表

看起来,好像浏览器要加载很多内容,但其实,浏览器下载这些文件之后会将其存储在缓存里,后续不会再通过互联网下载

使用单个外部样式表加载多个其他样式表有一个好处: 如果以后决定把样式进一步分成更多的样式表,无需修改网站的 HTML 代码。
我们只需在入口样式表中添加一个 @import 指令。如果决定把文字相关的样式从 main.css 文件中拿出来,放在单独的 type.css 文件里,无需修改网站中的网页。
我们只需打开包含全部 @import 指令的样式表,再添加一个指令: @import url(type.css)

这样安排还便于做试验,更换为不同的样式表就能查看临时的设计变更。比如说,我们决定根据日期、月份或季节更换网站的颜色。
如果我们已经把定义主色的样式放在单独的 color.css 文件里,那么,可以再创建一个文件(如summer_fun.css),使用不同的颜色,然后,在入口文件中,修改导入 color.css 文件的 @import 指令,改为导入新的颜色样式文件(例如,@import url(summer_fun.css))

注意: CSS 预处理器兼具两方面的优点: 先在多个 CSS 文件中编辑,然后转换成一个样式表,供网站使用,以减少下载时间。

消除浏览器对样式的干扰

使用后代选择符

装饰特定的标签时,可以使用类和 ID。例如,我们可以为一个段落设置类,例如<p class="intro">,然后使用.intro样式,只装饰那个段落的外观。
可问题是,为标签添加类或 ID 太简单了,因此很多设计师经常为所有(其实是几乎所有)标签添加类或 ID。专家甚至为这种行为起了个名字 -- 类狂症(classitis)。
为每个标签添加类不仅浪费时间,而且会导致 HTML 页面的下载速度变慢。最重要的是,不过度依赖类或 ID 也能精确选取标签,而且效果更好,方法是使用后代选择符。

后代选择符能提升构建网站的速度。后代选择符选取标签的精度比标签选择符高,而且比类选择符更省事。
大多数时候,我们想使用相同的方式装饰导航栏里的所有链接,而不想使用相同的方式装饰整个网页中的所有链接。
我们只需(在 CSS 中)找到一个方法,表述“只以这种方式装饰导航栏里的链接”,而不用把类样式应用到哦各个链接上。
也就是说,我们要能根据标签所在的位置,以不同的方式装饰相同的 HTML 标签。而后代选择符正好能做到这一点

划分页面

后代选择符的得力帮手之一是<div>标签。使用这个 HTML 标签可以把页面划分成多个逻辑区域,因此我们可以使用<div>标签标识不同的布局元素,如横幅、侧边栏、一列文本等。
我们可以把 HTML 代码放到<div>标签里,把页面中的内容分成不同的区域。

把故事的标题和故事页面的导航链接列表划在一起,如下所示:

1
2
3
4
5
6
7
8
<div>
    <h2>The CosmoFarmer Revolution</h2>
    <ul>
        <li><a href="page1.html">page 1</a></li>
        <li><a href="page2.html">page 2</a></li>
        <li><a href="page3.html">page 3</a></li>
    </ul>
</div>

添加<div>标签之后,为了能在 CSS 中选取它,再设置 class 属性: <div class="plullQuote">
如果想在页面中放置多个相同的布局元素,例如在一个故事中放多个重要引述,应该使用类

假如上述 HTML 代码里的链接列表在页面中出现两次,一次在故事开头,一次在故事末尾。我们可以为链接列表设置一个类,如下所示:

1
2
3
4
5
6
7
8
<div class="storyNav">
    <h2>The CosmoFarmer Revolution</h2>
    <ul>
        <li><a href="page1.html">page 1</a></li>
        <li><a href="page2.html">page 2</a></li>
        <li><a href="page3.html">page 3</a></li>
    </ul>
</div>

注意: 为了装饰一组元素,不一定非得添加<div>标签。如果上述 HTML 代码中只有一个无序列表,没有那个<h2>标签,那就可以不添加<div>标签,直接把类添加到无序里诶包上: <ul class="storyNav">
此外,也可以把<ul>标签放在 HTML5 新引入的<nav>标签里,然后再设置类

使用<div>标签标识好页面中的各个区域后,使用后代选择符可以轻易选取某个区域里的标签。
假如我们想为上述 HTML 代码中的链接应用独特的外观,可以使用后代选择符创建样式,如下所示:

1
2
3
4
.storyNav a {
    color: red;
    background-color: #ccc;
}

现在,链接会显示成红色,背景为淡灰色。可是,只有链接在类为 storyNav 的标签里,才会显示成这样。
这么做的好处是,如果想在列表中添加一个链接(例如指向 page4.html),无需动一根手指头,那个链接的外观就会于其他链接一样。浏览器应用后代选择符样式时会自动处理一切。

如果想装饰那个<div>标签里的其他标签也很简单,只需以类名.storyNav开头,创建后代选择符,例如,在其后面加上空格和想装饰的标签名。
如果想装饰那个<div>标签里的<h2>标签,创建后代选择符.storyNav h2即可

标识主体

后代选择符能准确选取要装饰的目标,使用它除了可以创建专门用于页面中某个区域的样式之外,还可以创建应用于网站中特定类型页面的样式。
假如我们想让首页中的<h1>标签与其他页面中相同的<h1>标签具有不同的外观。区分首页中的<h1>标签,有个简单的方法 -- 为首页的<body>标签添加一个类:

1
<body class="home">

然后,使用后代选择符创建样式(.home h1),装饰首页中的<h1>标签。使用这种方法,可以为网站中特定页面上的任何标签创建完全不同的外观(如图18-6)。
方法之一是,标识各个页面属于网站的哪个版块。假设网站分成四个版块: 新闻、活动、文章和链接。在属于某个板块的各个页面中,为<body>标签添加类或 ID。
例如,新闻板块中的各个页面里有下述 HTML: <body class="news">,而活动板块中的页面是<body class="events">

图18-6

注意: 另一种常见的做法是,使用类表示特定页面要使用的布局类型(如一栏、两栏或三栏布局)

为了标识页面属于网站的哪个板块,可以在导航栏中突出显示当前板块。突出显示的按钮表示的意思是,“你在这里,”如图 18-6 所示。
如果某个页面属于网站的新闻板块,我们可以突出显示“news”,让访客一眼就能看出身在哪个板块

下面是针对网站的各个板块,给其导航按钮定义不同外观的方法:

1.为<body>标签添加一个类,表明页面所属的板块:
例如,<body class="home">。每个板块中的页面都要这么做,因此,新闻板块中的页面包含这样的代码: <body class="news">

2.在页面中添加导航栏:

3.标识导航栏里的各个链接
指向首页的链接,代码可能是这样的: <a href="/index.html" class="homeLink">Home</a>。其中,类用于标识这个链接,说明它是指向首页的链接。
其他链接都要这么做,例如,<a href="/news/" class="newsLink">News</a>

至此,HTML 代码中已经有足够的信息,能使用 CSS 装饰各个板块的链接了。
在这个示例中,我们知道,只有在首页,指向首页的链接才在类为 home 的 <body> 标签里

4.使用后代选择符装饰各个板块的链接,当链接在相应的板块中时,显示成不同的外观

对这个示例中的首页来说,所需的后代选择符是:

1
.home .homeLink

仅当 .homeLink 链接在类为 home 的标签里时,这个选择符才会起作用。
大多数情况下,我们都想让表明身在各个板块的链接使用相同的外观,因此可以使用一个群组选择符,把各个板块中按钮的后代选择符放在一起。
这样,我们可以把相同的样式应用到每个按钮上,而无需分别为各个按钮创建规则。下述样式使用浅黄色背景突出显示当前板块的导航按钮:

1
2
3
4
5
6
.home .homeLink,
.news .newsLink,
.articles .articlesLink,
.links .linksLink {
    background-color: #FBEF99;
}

提示: 如果群组选择符中有多个后代选择符,一行写一个,如前面的示例所示。这样,如果以后需要编辑样式表,易于识别群组里的各个选择符

使用这个方法还可以为悬停、点击或者已经访问的链接应用不同的外观。

我们只是举几个例子,说明后代选择符的几种用法。这样做可能会让样式表变得稍微复杂一些。
例如,可能有 .home .mavbar a 这样的样式,而不是简单的类样式和,如 .navLink。不过,样式一旦创建好了,以后也无需做太多改动。
页面中不同区域里相同的 HTML 代码自动获得了明显不同的外观,简直像变魔术一样。