人人都能看懂的全栈开发教程——CSS

人人都能看懂的全栈开发教程——CSS

Chris Yue 2 comments
Posts

虽然我们现在没有设计师帮我们设计漂亮的页面,但现在的界面实在是太丑了,我们可以用我们程序员的审美稍作改动把页面做得好看一些,而美化页面最重要的工具,就是 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 也是选择器,比起标签选择器多了一个点 .,它的意思是『给设置了属性 classbtn 的元素添加定义的样式。我们在首页的『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

小白

二月 20, 2020 在 10:03 下午

:hover是伪类,不是伪元素。

    Chris Yue

    二月 21, 2020 在 10:34 上午

    感谢,已经更改

     

发表评论

18 − = 15