虽然我们现在没有设计师帮我们设计漂亮的页面,但现在的界面实在是太丑了,我们可以用我们程序员的审美稍作改动把页面做得好看一些,而美化页面最重要的工具,就是 CSS (Cascading Style Sheets)了。
在我们开始优化页面之前,我们得想好我们要让它显示成什么样的风格。虽然我已经很多年不玩 WOW 了,但是 WOW 依然是我心中的 MMORPG 类型游戏的第一,所以我就来教大家如何仿照 WOW 网站的风格,用一点点代码,来改善我们的任务清单网站。
颜色
首先我们将网站的背景调成暗色。在 CSS 中,我们有很多方法来表示颜色,比如 RGB(Red Green Blue) 红绿蓝三原色来表示,或者用 HSL (Hue Saturation Lightness)即 颜色种类/饱和度/明暗 来表示,或者最简单的,用颜色英文名来表示,比如 black
white
。但英文名用来表示颜色缺点也很明显,颜色肯定是无穷的,但颜色名是有限的,所以表达不出那么多颜色来。虽然 RGB 和 HSL 也不能表达无穷的颜色,却也比英文名能表示的颜色多得多(其实计算机本身就不可能表达无穷的颜色,但人眼已经分辨不出来了)。我个人习惯用 RGB,用着还挺顺手的,所以文中所有的颜色我也都使用 RGB 来表示,HSL 如何使用大家可以自行搜索。
RGB 实际上也有两种表达方式,为了表示黑色,RGB 可以写成 rgb(0,0,0)
,表示红绿蓝三种颜色的占比都是 0,即一点颜色都没有,也就是黑色;另外也可以用 16 进制的方式来表达,如 #000000
。我个人是倾向于使用 16 进制,写起来比较简单,而且上面的黑色如果用 16 进制还可以再简化成 #000
。红绿蓝三原色其中一色的取值,如果使用 rgb(r,g,b)
的形式,可以从 0~255,如果是 #rgb
的形式,是从 00~ff,16 进制也是编程常遇到的一种表示数的形式,我们常见的十进制,如果只是一位数,就是 0~9 一共 10 个数字来表达,16 进制中一位数则是 0~9a~f 来表达。很容易算出来,00~ff 一共也是 255 个数,其实两种写法本质上一模一样。
刚才有说 16 进制的写法的简化,简化规则是这样的:如果三原色中三个颜色的值个位十位都一样,比如 #112233
那么颜色可以简化成三位 #123
。
在 CSS3 中,颜色除了三原色之外,还新增了 Alpha 通道,也就是透明度,会 Photoshop 的同学应该比较熟悉。如果要支持透明度,16 进制的方式就不能用了,但是 10 进制的写法还是能用的,只不过需要在 rgb
后面加个 a
来表示透明(即 Alpha):rgba(0,55,111,0.5)
,a 取值范围从 0 到 1。
行内样式/内部样式/外部样式
从 WOW 的官网上,我们通过查看源代码,或者使用取色器能发现背景色为 #170e09
,这是一种非常接近黑但有点偏暖的深灰色。我们可以通过在 body
标签上添加 style
属性来更改我们的颜色,刷新页面即能立马看到效果:
<body style="background: #170e09">
在 HTML 里可以给所有能看见的元素添加 style
属性,值就是 CSS 样式规则;background
即背景的意思,冒号后面的值是我们定的颜色的值。实际上 background
也是缩写,设置背景的属性全名是 background-color
。如果 CSS 可以用缩写,尽量用缩写,所有走网络的文件,如果能节省流量,又没什么损失,那么尽量写得少一些。
这种直接写在标签 style
属性的 CSS 叫做『行内(inline)CSS』。可以想象的出来,如果每个标签都写一堆行内 CSS,维护起来还是很头疼的。我们先把 body
标签的 style
属性删除,改成在 head
标签下加 style
标签的方式来重写:
<head>
..
<style>
body {
background: #170e09;
}
</style>
</head>
我们可以把所有样式的代码全部集中到 style
标签里面来维护。这样相对于散落在 HTML 各个代码里,要稍微好维护一些。在 HTML 的 style
标签里写 CSS 叫做『内部样式』。
我们还可以通过把样式规则单独写在一个文件里,然后让 HTML 文档引用它。我们把 style
里的内容复制一下,在 web
目录创建 main.css
文件后把内容复制进去。文件名以及路径其实是没有要求的,放哪儿叫啥都可以,只要通过网站能被访问到就行。
<head>
<!-- 删掉 style 标签,替换成下面的标签 -->
<link rel="stylesheet" type="text/css" href="main.css">
</head>
我们通过 link
标签告诉浏览器:要引入一个外部链接(即 link
标签的作用),它是一个样式表,需要浏览器按样式表的方式加载(即 rel="stylesheet"
),这个样式表的文件类型是 CSS 格式的文本文件(即 type="text/css"
),地址是 main.css
(即 href
属性)。
如果我们整站风格都是一致的(很显然大部分情况都是这样的),所有的页面都可以加载同一个 CSS,而不用每个页面都单独重新写,另外我们还可以设置 HTTP 缓存信息,让 CSS 在被加载一次之后,就缓存在本地不再被加载第二次,不过本文不讨论优化的事情,我们只先沿用外部 CSS 的做法。
实际上 JS 也是可以使用外部引入的方式的,也可以享受到缓存的好处,只是引入语法稍有不同:
<script src="main.js"></script>
选择器
回看我们设置背景所使用的 CSS 规则:
body {
...
}
示例中 body
是一个『选择器』,表示『选择 body
标签』。可能有人就会问了,那是不是同一种标签只能添加同样的样式呢?CSS 的选择器当然不会这么蠢,CSS 的选择器是设计得非常灵活的。
现在背景变黑了,为了还能看到文字,我们先把整个文档的默认文字颜色变成浅色,并且把字调大,也是在 body
标签添加规则即可:
/* 这是 CSS 的注释 */
body {
..
color: #ebdec2; /* color 属性负责文字颜色 */
font: 19px/1.5 Arial; /* font 设置与字体相关的选项 */
/*
上面的写法等同于
font-size: 19px;
line-height: 1.5;
font-family: Arial;
*/
}
接下来我们把『新增』超链接做成一个按钮的样式。但要注意的是,整个网页中会出现各种各样的链接,可能我们只想让某些我们想强调或者突出的链接变成按钮样式,这个时候,我们就可以这么写:
.btn {
color: #f7b10a;
text-transform: uppercase; /* 字母全大写显示 */
background: rgba(159,22,0,.6);
text-decoration: none; /* 设置字体修饰,这里用于去掉链接自带下划线 */
padding: 12px 30px; /* 字四周的留白,这也是缩写 */
border: 1px solid #ea3012; /* 边框粗细,样式,颜色,这也是缩写 */
/*
等同于
border-width: 1px;
border-style: solid;
border-color: #ea3012;
*/
}
.btn
也是选择器,比起标签选择器多了一个点 .
,它的意思是『给设置了属性 class
为 btn
的元素添加定义的样式。我们在首页的『New』按钮上使用这个 class 试试效果:
<a href="/?c=new" class="btn">New</a>
感觉是不是立马好看了不少?
我们还可以在选择器上面添加所谓的『伪类』,来表示元素的某一种状态。比如我们的按钮就可以新增带伪元素的选择器,定义当鼠标移动到按钮上时的显示状态:
.btn:hover {
background: rgba(159,22,0,1); /* 鼠标移动上去后将透明度变成不透明 */
}
:hover
就是一个表示鼠标移动到头上的伪类。选择器的用法很丰富也很灵活,可惜我们页面上的元素实在太少,所以也无法多举例了,这里提供 MDN 上的文档链接,大家可以先了解一下。
需要注意的是,我们在定义按钮的时候,有很多属性因为在 body
上已经定义过了,所以在 .btn
没有再此定义,这是因为 body 里的所有元素都『继承』了 body 里的部分样式(比如字体),一般来说,子元素都会继承父元素的某些样式,说『某些』是因为这也不是绝对的,举个例子,父元素设置了宽度为 50%
,那么子元素就不会自动继承,因为基本上不可能有那样的需求,CSS 的继承规则还是很人性化的。
长度单位
可以说 CSS 定义的值里面,除了颜色外用得最多的就是长度了,我们上面的例子已经用了很多跟长度相关的设置,比如 px
,即 pixel 像素的意思,它是一个『绝对长度』;我们也用到了百分比,就是相对于父元素来说增加或者减少多少的意思,是一个『相对长度』。因为长度的单位实在太多了,我也无法跟大家一一介绍,但长度如何用却很重要,尤其是各种相对长度单位的用法,所以单独出来强调一下,我们后面的例子遇到新的知识点也会说的。奉上MDN 的参考链接,权威参考应该随时收藏。
一点学习建议
CSS 是典型的有太多技巧,全靠经验的工具,就好比之前说样式继承的问题,哪些继承哪些不继承,又或者说各种盒模型,或者各种网页布局有哪些优点和缺点,都最好自己试一下。如果大家想掌握这门工具,我建议的方法很简单,就是多『参考』,但也不能参考完就不管了,代码里有不熟悉的,第一时间查资料,让不熟悉变成熟悉,才能让自己下一次遇到类似问题不再去参考,而是自己发挥。
本章最后……
本着多提供例子,让大家在例子中学习的初心,最后把完整的 CSS 发出来,除了我们的首页之外,记得在登录页以及新增任务页也引入我们的样式文件。老规矩,请注意代码中的注释:
body {
background: #170e09;
color: #ebdec2;
font: 19px/1.5 Arial;
margin: 50px;
/* 如果把 body 看成一个盒子,margin 定义了这个盒子跟四周的距离 */
/*
上面的写法是缩写,等同于
margin: 50px 50px 50px 50px
分别对应上右下左,顺序按时钟来记很好记,12 点开始顺时针
其实这种写法本身也是缩写,等同于
margin-top: 50px;
margin-right: 50px;
margin-bottom: 50px;
margin-left: 50px;
*/
/* 下面出现的 padding 和 margin 语法完全一样,只不过 padding 是指的是盒子跟盒子内部元素的距离 */
}
/*
因为登录输入框和任务内容输入框也想要按钮的『框』,所以『框』的样式被独立出来增加复用性
但不要忘记 class 属性里得提到它,像这样 class="btn border"
是的,class 属性可以有不只一个值
*/
.border {
color: #ebdec2;
border: 1px solid #ea3012;
background: rgba(159,22,0,.6);
display: block;
width: 128px;
box-sizing: content-box; /* 统一盒模型,用于防止 input 按钮的样式和 a 按钮的样式不一致,因为他们的默认盒模型不一致 */
/* 在设置盒 width/height 的时候,content-box 设置的是内容的大小,而 border-box 设置的是盒边框的大小(区别在于是否包含 padding) */
padding: 12px 15px;
font-size: 19px; /* input 不会继承父元素的 font-size */
}
/* 所有的按钮都应该添加 btn 类 */
.btn {
color: #f7b10a;
text-transform: uppercase;
text-decoration: none;
margin: 50px 0; /* 另外一种缩写,等同于 margin: 50px 0 50px 0 */
text-align: center; /* 按钮文字都居中显示 */
transition: background .5s; /* CSS3 新增属性,这里定义了背景变化时增加动画过渡效果,持续时间 0.5 秒 */
}
.btn:hover {
background: rgba(159,22,0,1);
}
/* 所有的输入框,比如登录账户密码框,和任务输入框都需要添加这个类 */
.input {
/* 下面所有属性是为了跟 .border 一起用的时候可以覆盖 .border 的属性值 */
/* 从这可以看出来如果两个类定义有冲突,后添加的规则优先级更高 */
/* 选择器优先级也是 CSS 一个重要的点,不是说后面的写的规则全都可以覆盖前面的规则,优先级有它自己的计算公式,建议大家好好看一下我之前提供的 MDN 的文档最后那部分 */
background: rgba(0,0,0,.4);
width: 256px;
margin: 10px 0;
border-color: #c77e19;
}
/* 给首页任务列表用的,记得给 ul 标签加上这个 class */
.tasks {
margin: 50px 0;
list-style: none;
padding: 0;
}
从注释可以看出来,如前所说,CSS 很多时候完全靠经验,要记的东西不少,但大家也不用过于担心,我敢说大家在使用 CSS 时遇到的 95% 的问题,网上已经有解答了,是比较好搜到的,基本不需要自己去研究。
记得在 HTML 代码里用上这里面的样式,可以参考本章完整代码。
人人都能看懂的全栈开发教程——CSS by Chris Yue is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

写作累,服务器还越来越贵
求分担,祝愿好人一生平安
天使打赏人
2 Comments
小白
2月 20, 2020 在 10:03 下午:hover是伪类,不是伪元素。
Chris Yue
2月 21, 2020 在 10:34 上午感谢,已经更改