网页开发入门|06 层叠样式
网页中的样式效果之间的继承关系,导致有一些样式被覆盖和遮挡,而其它的依然露了出来,层峦叠嶂,这就是层叠样式表CSS(Cascading Style Sheets)。

不知道经过上一节的综合练习后,你是否感受了使用代码进行创作的快乐,希望如此😊

不过,快乐之余,我们还是留下了一些没有解决的问题,导致最终的成稿和设计之间出现了一些差异。为了解决这些问题,还需要的一些新的知识,咱们将在接下来的几节课中依次展开。
在本节课,让我们先把目光聚焦在一个可能会被忽视的细节上。为了发现它,让我们再次观察一下上节课中的这段代码:
<div style="font-size: 0.9em; color: gray">
【作者】
<a href="https://baike.baidu.com/item/王之涣"
style="text-decoration: none">王之涣</a>
【朝代】唐
</div>

明明是在div
标签的style
属性中设定的font-size
,怎么对a
标签里的内容也生效了呢?
而与此同时,同样也进行设定了的color
却没有类似的效果,又是为什么呢?
对这个问题的探索,将为我们打开一片新的天地。

样式的继承
让我们先关注font-size
所产生的效果,这里的div
元素是a
元素的父元素。当我们对父元素设定样式时,对子元素也生效了。
这个能力被称作继承inherit。
Inherit被翻译成了继承,但它在英文中还有另外一个含义「通过遗传获取特征」。其实在这里,更接近「遗传」的含义,即子元素遗传了父元素的样式。但是为了和主流的说法保持一致,我们后文中仍然会使用「继承」的说法。

子元素不仅会继承父元素的样式,还能继承父元素的父元素,以及一路向上的所有祖辈元素。
继承可以让我们很方便的,一次性为一大片的元素设定统一的样式。比如,我们现在需要将上节课中图文页面中文字的字体全部改为楷体。

为了不破坏上节课的成果,建议大家在workspace
中复制一份poem.html
,命名为poem2.html
,接下来的尝试都在这个副本中进行。
需要说明的是,在不同的设备和操作系统中,自带的字体并不完全一样。如果我们给网页中的文字设定的字体,并未被安装到用户的系统中,那就不会有任何效果。
简单起见,我们只考虑MacOS和Windows上的情况。在这两个系统上,自带的楷体分别叫STKaiti
, KaiTi
。
幸运的是用于修改字体的font-family
支持同时指定多个字体,并将找到的第一个可用字体作为最终的效果,就像这样。
font-family: STKaiti, KaiTi
通过在每一段文字的style
属性进行设定font-family
,便可以将页面中的文字全部改为楷体。
<h1 style="font-family: STKaiti, KaiTi">登鹳雀楼</h1>
<div style="font-size: 0.9em; color: gray; font-family: STKaiti, KaiTi">
【作者】
<a href="https://baike.baidu.com/item/王之涣"
style="text-decoration: none">王之涣</a>
【朝代】唐
</div>
<!-- 此处省略部分代码 -->

想想看,如果页面中有几百段文字,如果要对每个段落都要进行设置,岂不是很麻烦?但是如果我们有一个所有元素的公共父元素,便可以通过样式的继承能力,快速达到相同的效果。
我们可以使用body
标签作为这个公共父元素。body
是W3C建议的,用于包含网页中所有元素的标签,天然就是所有元素的父元素。
<body style="font-family: STKaiti, KaiTi">
<h1>登鹳雀楼</h1>
<div style="font-size: 0.9em; color: gray">
【作者】
<a href="https://baike.baidu.com/item/王之涣"
style="text-decoration: none">王之涣</a>
【朝代】唐
</div>
<!-- 此处省略部分代码 -->
</body>

body
是页面中所有元素的父元素,所以body
标签在一个网页中有且只能有一个。虽然我们在之前写的代码中,从来没有明确的写上body
标签,其实浏览器都会在渲染网页之前,自动的帮我们补上它。
尽管继承如此方便,但并不是所有的样式属性都会(默认)被继承,你可以通过尝试或查阅文档了解不同样式属性的继承性。
样式的覆盖
如果一个子元素不想全盘继承来自父元素的样式,子元素也可以明确的设定自己的样式,以覆盖override继承的效果。
比如说,我们想在其它内容依然保持楷体的情况下,只把文章标签这部分文字修改为宋体(MacOS:STSong,Windows:SimSun),便可以直接在元素的style
中直接设定新的字体。
<body style="font-family: STKaiti, KaiTi">
<!-- 此处省略部分代码 -->
<div style="font-size: 0.9em; font-family: STSong, SimSun">
标签:
<a href="#" style="text-decoration: none; background-color: lightgray">写景</a>
<a href="#" style="text-decoration: none; background-color: lightgray">登楼</a>
<a href="#" style="text-decoration: none; background-color: lightgray">唐诗三百首</a>
<a href="#" style="text-decoration: none; background-color: lightgray">哲理</a>
<a href="#" style="text-decoration: none; background-color: lightgray">黄河</a>
<a href="#" style="text-decoration: none; background-color: lightgray">场景</a>
<a href="#" style="text-decoration: none; background-color: lightgray">励志</a>
<a href="#" style="text-decoration: none; background-color: lightgray">景色</a>
<a href="#" style="text-decoration: none; background-color: lightgray">山水</a>
<a href="#" style="text-decoration: none; background-color: lightgray">数字</a>
</div>
<!-- 此处省略部分代码 -->
</body>

这个覆盖的效果也可以解释开篇的问题,为什么a
元素中的文字依然保持了蓝色:
像a
、b
、i
等标签有自带的样式效果,相当于在style
属性中设定了样式。在作为子元素时,它们的自带样式的覆盖了来自父元素的继承。
样式的层叠
如果父元素设定了多个样式属性,子元素只对其中的一些进行了覆盖,剩余的那些依然可以保持继承性,并不会全面的否定。
再来到页面中作者和朝代这里看一下,父元素div
同时设定了字体大小font-size
和颜色color
。
<div style="font-size: 0.9em; color: gray">
【作者】
<a href="https://baike.baidu.com/item/王之涣"
style="text-decoration: none">王之涣</a>
【朝代】唐
</div>

子元素a
自带颜色为蓝色的样式属性,于是颜色效果就被覆盖了。然而,a
并不自带字体大小样式属性,所以父元素中的font-size
对子元素a
依然生效。
网页中的样式效果就像这样,有一些继承,有一些被覆盖遮挡,有一些露了出来,层峦叠嶂,于是给网页中的设定样式的这些代码,被起了一个非常形象的名字——层叠样式表CSS(Cascading Style Sheets)。

CSS也是W3C所推荐的网页样式标准,至今已经发展到到了第三代,即CSS3。
style标签
CSS在网页中扮演了非常重要的角色,但是像我们之前一样,把样式代码和内容代码混在一起写,非常不利于阅读和维护。
于是便有了一个专门用来给页面元素设定样式的style
标签,可以把样式代码,也就是CSS,单独抽出来存放和编写,就像这样:
<style>
a {
text-decoration: none;
color: lightskyblue;
}
</style>
在这段代码中,大括号前的a
是一个选择器,它选中了页面里全部的a
元素。
选择器可以选中页面中的一些元素,并告诉浏览器,要对它所选中的元素进行样式设定,而要设定的样式属性,正是大括号里的代码所决定的。
选择器的类型有很多,用于准确选中具备某些特点的元素,我们将在下一节课更加详细的展开关于选择器的内容。
大括号里的CSS代码的写法,比较简单,与我们之前在元素的style
属性里所写的方法完全一样。为了增强可读性,建议将每个样式属性单独写成一行。
所以上面的代码的整体含义是:将页面中所有a
元素的下划线去除,并将它们的颜色设定为浅天蓝色。
但还有一个问题,style
标签该写在哪里?
style
标签里的代码只是一些样式,并不会也无法直接在页面上显示出什么内容,它是对页面的一些整体性描述或设置。这类的内容,被称作的元信息Meta-information。

元信息与别的元素非常的不同,它不存在于页面的主要结构中,好像写在哪里都有点怪怪的。
为了解决这个问题,W3C定义了一个与上面小节介绍过的body
标签相对应的标签head
。head
是网页中所有元信息的父元素,所以style
可以放到head
标签内。
<head>
<style>
a {
text-decoration: none;
color: lightskyblue;
}
</style>
</head>
<body style="font-family: STKaiti, KaiTi">
<!-- 此处省略部分代码 -->
</body>
有了在style
标签里定义的样式之后,我们原本在每个a
元素中写的text-decoration: none
就不再需要了。最终的代码类似于这样:
<head>
<style>
a {
text-decoration: none;
color: lightskyblue;
}
</style>
</head>
<body style="font-family: STKaiti, KaiTi">
<h1>登鹳雀楼</h1>
<div style="font-size: 0.9em; color: gray">
【作者】
<a href="https://baike.baidu.com/item/王之涣">王之涣</a>
【朝代】唐
</div>
<hr>
<p>白日依山尽,黄河入海流。</p>
<p>欲穷千里目,更上一层楼。</p>
<div style="font-size: 0.9em; font-family: STSong, SimSun">
标签:
<a href="#" style="background-color: lightgray">写景</a>
<a href="#" style="background-color: lightgray">登楼</a>
<a href="#" style="background-color: lightgray">唐诗三百首</a>
<a href="#" style="background-color: lightgray">哲理</a>
<a href="#" style="background-color: lightgray">黄河</a>
<a href="#" style="background-color: lightgray">场景</a>
<a href="#" style="background-color: lightgray">励志</a>
<a href="#" style="background-color: lightgray">景色</a>
<a href="#" style="background-color: lightgray">山水</a>
<a href="#" style="background-color: lightgray">数字</a>
</div>
<p>
<img src="assets/王之涣.jpg" alt="王之涣">
</p>
</body>

我将本课程所有的代码托管在gitee
上了,你可以点击这个链接,或到gitee.com
上搜索弦五 网页开发入门,查看和获取本课程的全部代码。