内容简介
如果你是网页设计师或应用开发者,对复杂的页面样式、改进可访问性以及节省时间和精力感兴趣,决不能错过这本书。这一修订版全面阐述了 CSS 的实现方式,还深入分析了最新的 CSS 规范。
CSS 是一门不断发展的语言,用于描述 Web 内容在屏幕、打印机、语音合成器、屏幕阅读器和聊天窗口上的表现。各种物联网设备,不论屏幕尺寸大小,只要有浏览器,就用得到 CSS,这其中包括手机、计算机、视频游戏、电视、手表、自助服务终端和汽车控制台。本书两位作者 Eric Meyer 和 Estelle Weyl 向您展示了如何通过布局、过渡和动画、边框、背景、文本属性,以及许多其他工具和技术来改善用户体验、加快开发速度、避免潜在的错误,并为您的应用程序增光添色。
作者简介
Eric A. Meyer 是国际公认的 HTML、CSS 和 Web 标准领域的专家,是 Complex Spiral Consulting 公司的创始人,是微格式运动的发起人之一,还是设计领域系列会议 An Event Apart 的创始人之一。他是本书前一版和其他多本关于 CSS 和设计的图书的作者。
他的个人网站为 meyerweb.com。
Estelle Weyl 是开放 Web 布道师和社区工程师,从 1999 年起就开始开发符合标准且具有可访问性的网站。她的博客地址是 standardista.com,这里的文章讨论一切与前端有关的话题,包括 CSS3、HTML5、JavaScript 性能、可访问性和移动 Web 开发。她喜欢躺在家中的沙发上编程,也经常游历世界,在各种会议上演讲。
目录
前言
第 1 章 CSS 和文档
第 2 章 选择符
第 3 章 特指度和层叠
第 4 章 值和单位
第 5 章 字体
第 6 章 文本属性
第 7 章 视觉格式化基础
第 8 章 内边距、边框、轮廓和外边距
第 9 章 颜色、背景和渐变
第 10 章 浮动及其形状
第 11 章 定位
第 12 章 弹性盒布局
第 13 章 栅格布局
第 14 章 CSS 中的表格布局
第 15 章 列表和生成的内容
第 16 章 变形
第 17 章 过渡
第 18 章 动画
第 19 章 滤镜、混合、裁剪和遮罩
第 20 章 针对特定媒体的样式
附录 A 支持动画的属性
附录 B 基本属性参考
附录 C 颜色对照表
原文摘要
第 1 章 CSS 和文档
层叠样式表 (Cascading Style Sheet. CSS) 是一个强大的工具,能影响一个或一组文档的表现, CSS几乎触及Web的每个角落,甚至很多非Web环境也能见到它的身影。例如,基于 Gecko的浏览器使用CSS影响窗体自身的表现,很多RSS客户端允许使用CSS定制订阅源和订阅源中的文章 ,而且有些即时通信客户端使用CSS装饰聊天窗口。JavaScript框架甚至是 JavaScript自身使用的句法中处处可见CSS的身影。
1.1 Web样式简介
1994年,正值Web开始广泛流行开来, CSS的第一个提案发布了,到1996年年末CSS1完成。此后, 刚组建的CSS工作组开始着手制定CSS2, 而各浏览则相互协作,努力实现CSS1,CSS2规范于1998年年初定案。随后CSS工作组立即投身CSS3的制定工作,以及CSS2的修订工作(制定 CSS2.1 ) 。与以往不同的是, CSS3 由多个(理论上)独立的模块构成,而不是单独一个臃肿的规范,XHTML规范受此启发,也采用了这种模块式机制。CSS3分成多个模块的根本原因是各模块可以独立演进,尤其是重要的(或受众广的) 模块可以按照 W3C 的规划向前推进,而不必受其他模块拖累。
1.2 元素
元素 (element) 是文档结构的根基,HTML中常用的元素有 p、 table、span、 a 和 div 等,文档中的每个元素都对文档的表现起一定作用。
1.2.1 置换元素和非置换元素
置换元素(replaced element):指用来置换元素内容的部分不由文档内容直接表示,在HTML中最常见的置换元素要数img,它的内容由文档之外的图像文件替换。
<img src = "muzijiang.gif">
上面这段标记只包含一个元素名和一个属性。如不指向外部内容(这里通过 src 属性指定一个图像) ,这个元素什么也表示不了。如果指向的图像文件存在,文档会把那个图像显示出来;否则,浏览器什么也不显示,或者显示"图像损坏"占位图。
input 元素类似,根据类型的不同,会替换成单选按钮、复选框或文本输入框。
非置换元素(nonreplaced element):HTML元素大部分是非置换元素(nonreplaced element),即元素的内容由用户代理(通常是浏览器)在元素自身生成的框中显示。如hi there是非置换元素, 用户代理会显示 "hi there" 文本。段落、标题、单元格、列表,以及 HTML中其他几乎所有元素都是非置换元素。
1.2.2 元素的显示方式
除了置换元素和非置换元素之外,CSS还把元素分为块级和行内两种基本类型。除此之外,还有其他显示类型,不过这两种是最常见的。
块级元素:(默认)生成一个填满父级元素内容区域的框,旁边不能有其他元素。也就是说,块级元素在元素框的前后都"断行"。HTML中最常见的块级元素是p和div。置换元素可以是块级元素,但往往不是。
列表项目是一种特殊的块级元素,它的表现与其他块级元素没有区别,此外还会在元素框旁生成一个记号(无序列表通常是圆点,有序列表通常是数字)。除了多出的这个记号以外,列表项目与其他块级元素之间没有任何区别。
行内元素:在一行文本生成元素框,不打断所在的行。HTML中最常见的行内元素是a,此外还有strong和em。这类元素不在自身所在元素框的前后"断行",因此可以出现在另一个元素的内容中,且不影响所在的元素。
⚠️ 注意:HTML中块级元素和行内元素的重要区别:在HTML中,块级元素不能出现在行内元素中。但是CSS并不限制它们的显示方式,相互之前可以嵌套。
<body>
<p>This is a paragraph with <em>an in1ine e1ement</em> within it.</p>
</body>
这里有两个块级元素 (body和p) 及一个行内元素 (em) 。根据 HTML规范,em可以放在 p 里。而反过来却不行。一 般地,HTML层次结构要求,行内元素可以放在块级元素中,反之则不行。
与此不同,CSS没有这种限制,在不改变标记的前提下,我们可以像下面这样改变它们的显示方式
p{display:inline}
em{display:block}
这会导致行内框中出现一个块级框,这完全是有效的,不违背任何CSS规则。然而,如果在 HTML中调换元素之间的嵌套关系,就会出问题。
<em>
<p>This is a paragraph improperly enclosed by an inline element.</p>
</em>
不管通过CSS如何改变显示方式,这都不是有效的 HTML。
1.3 把CSS应用到HTML上
HTML文档内部有一定的结构,这种结构正是HTML和CSS之间固有关系的一部分。
<html><head>
<title>hello world</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="sheetl.css" media="all">
<style type="text/css">/* These are my styles */@import url(sheet2.css);
</style>
</head>
<body>
<h1>Wafflesl</h1>
<p sty1e="co1or: gray;">my name is muzijiang!</p>
</body>
</html>
1.3.1 link标签
<link rel="stylesheet" type="text/css" href="sheetl.css" media="all">
<style type="text/css">
/* These are my styles */
@import url(sheet2.css);
</style>
它的基本作用是把其他文档与当前文档关联起来,CSS使用它链接应用到文档上的样式表。通过link标签链接的样式表不是HTML文档的一部分,但却供文档使用,我们称这样的样式表为外部样式表(external stylesheet),因为样式表在HTML文档外部。
为了正确加载外部样式表,link标签必须放在head元素中,不能放在其他元素中Web浏览器遇到link标签时,会查找并加载指定的样式表 ,使用样式表中的样式渲染HTML文档。
外部样式表中是一系列规则,存储在单独的文件中。注意,样式表中不能有HTML或其他标记语言,只能包含样式规则。外部样式表保存为纯文本文件,扩展名通常是.css,例如 sheet1.css。
通过@limport 声明加载了另一个外部样式表 sheet2.css。@import声明必须放在所在样式表的开头,此外别无限制。
属性
rel是"relation"(关系)的简称,这里指定的关系是sytlesheet。
type属性的值始终为text/css,说明通过link标签加载的数据类型。这样web浏览器才知道加载的样式表是css样式表,然后确定如何处理加载的数据,以后可能会出现其他样式语言,因此最好声明使用的是哪种语言。
href属性的值是样式表带URL,可以是绝对地址,也可以是相对地址,具体由需求而定。
media属性,它的值是一个或多个媒体描述符(media descriptor)指明媒体的类型和具体的功能,多个媒体描述符以逗号分开。
⚠️ 注意:一个文档可以关联多个样式表,如果是这样,最初显示文档时只会使用 rel 属性的值为 stylesheet 的 link 标签链接的样式表。
<link rel="sty1esheet" type="text/css" href="basic.css">
<link rel="sty1esheet" type="text/css" href="splash.css">
1.3.2 style元素
style 元素也是一种写入样式表的方式,直拨写在文档中。style 元素应该始终设定type属性,对 css 文挡来说,正确的值是"text/css" ,这与link 元素是一样的。style 元素始终以 开头,后跟一个或多个样式,然后以 标签结尾,style 元素也有 media 属性,与通过 link 元素链接的样式表功能一样。
开始和结束 style 标签之间的样式称为文档样式表 (document stylesheet) 或嵌入式样式表 (embedded stylesheet, 因为这种样式表内嵌在文档中) 。style元素可以直接包含应用文铛上的样式,也可以通过 @import 指令引人外部样式表。
<style type="text/css">
...
</style>
1.3.3 @import指令
下面来看可以出现在style标签中内容,首先是链接的外部样式中也有的@import指令;与link一样,web浏览器遇到@import指令时会加载外部样式表,使用其中的样式渲染HTML文档。区别在于@import指令在style元素内部,而且必须放在其他CSS规则的前面,否则不会起作用。
<style type="text/css">
@import url(sheet2.css); /* @import放在开头*/
h1{color:gray}
</style>
与link一样, 一个文档中可以有多个@import语句,区别在于 @import指令导入的每个样式表都会使用,无法制定候选样式表,如下:三个外部样式表都会加载,而且其中的所有样式都会用于显示文档。
@import url(sheet2.css);
@import url(blueworld.css);
@import url(zany.css);
与link类似,@import指令也可以显示导入的样式表应用于何种媒体,方法是在样式表的URL后面提供媒体描述符。
@import url(sheet2.css) all;
@import url(blueworld.css) screen;
@import url(zany.css) projection,print;
如果一个外部样式表需要用到另一个外部样式表中的样式,@import指令的作用就体现出来了。我们知道,外部样式表不能包含任何文档标记,也就是不能使用link元素,但是可以使用@import指令。
@import url(http://example.org/library/layout.css);
@import url(basic-text.css);
@import url(printer.css) print;
body{color:red};
h1{color:blue};
上面的样式写法我们可能不会这么使用,此例即使用了绝对URL,也用到了相对URL,这一点与link元素一样。但需要注意,CSS要求样式表中的@import指令必须在所有样式规则前面。
1.3.4 HTTP链接
为文档关联CSS还有一种鲜为人知的方式:使用HTTP首部。在Apache中,若想使用这种方式, 可以在.htaccess文件中引入css文件。例如:
Header add Link "</ui/testing.css>;rel=stylesheet;type=text/css"
这样设置之后,支持这种方式的浏览器在加载受此.htaccess文件管理的文档时便会使用指定的样式表,就像通过link元素链接的样式表一样。此外,还可以在服务器的 httpd.conf文件中添加等效的规则,这样做可能更高效;
<Directory /path/to/ /public/html/directory>Header add link '</ui/testing.css>;rel=stylesheet;type=text/css'
</Directory>
在支持这种方式的浏览器中,这样做的效果与前面一样,唯一的区别是设置所在的文件不同。截至 2017 年年末,广泛支持HTTP 链接样式表的浏览器有 Firefox 系列和 Opera。 因此,这种方式最常在使用这些浏览器中的某一款做开发时使用。鉴于此,在测试服务器中使用 HTTP链接便可以把开发中的网站与线上公开的网站区分开。如果出于特殊的原因 ,想隐藏一些样式, 不让 WebKit 和 lnternet Explorer 系列使用,也可以使用这种方式。
1.3.5 行内样式
如果只想为单个元素提供少量样式,不值得动用嵌入式样式表或外部样式表,可以利用HTML元素的style属性设置行内样式。
<p style="color:gray">my name is muzijiang!</p>
除了body元素之外的标签(如head或title),所有HTML标签都能设定style属性。
⚠️注意,style属性的值只能是一系列规则声明,而不能包含整个样式表。因此,不能在style属性中使用@import指令,也不能有完整的规则。
通常不建议使用style属性,而且,除了HTML,XML很少使用这个属性。倘若使用style属性,CSS的很多重要优点都不复存在了,例如集中管理样式,控制整个文档或网站中所有文档的外观。在很多方面,行内样式都不比font标签好多少,不过却提供了一定的灵活性。
1.4 样式表中的内容
1.4.1 标记
样式表中不能有标记,这一点看似理所当然,但总是有人在这上面栽跟头,不过HTML注释标记例外,由于历史原因,style元素中可以有HTML注释。
<style type='text/css">
<!--
hl {color: maroon;}
body {background: yellow;}
-->
</style>
1.4.2 规则的结构
一个规则由两个基本部分构成:选择符(selector)和声明块(declaration block),声明块由一个或多个声明组成,而一个声明包含一个属性(property)和对应的值(value)。一个样式表由一系列规则构成。
1.4.3 厂商前缀
有时你会发现,CSS中有些内容的前面有个标注,例如-o-border-image,这叫厂商前缀(vendor prefix),浏览器厂商通过它标记实验性或专属(或二者兼具)的属性、值或其他内容。
从上面可以看出,厂商前缀的一般格式是一个英文破折号,一个标注和一个英文破折号。不过也有少量前缀不采用这个格式,开头没有破折号。厂商前缀出现的目的是浏览器厂商为了测试新特性,这么做能保证兼容性,不必担心被过时的行为限制,导致与其他浏览器不兼容。
1.4.4 处理空白
CSS对规则之间的空白基本没有严格要求,而且对规则内部的空白大多也没有严格要求,不过有些例外。一般来说,CSS对待空白的方式跟HTML差不多,解析时,连续的空白会合并成一个空白,因此,虚构的rainbow规则可以写成下面这几种格式:
rainbow: infrared red orange yellow green b1ue;
rainbow:
infrared red orange yellow green b1ue;rainbow:
infrared
red
orange
yellow
green
b1ue
;
当然,除此之外还有其他分隔方式,唯一要求是,要使用空白分隔,可以是空格、制表符或换行符,可以是单个空白,也可以任意数量随意组合。同样,规则之间的空白也可以随意使用,下面是无数中编写方式中的五种:
html{color:black;}
body{bakcground:white;}
p{
color:gray;}
h2{
color:silver;
}
ol
{
color
:
silver
;
}
从第一个规则中可以看出,多数空白可以省略。其实,简化后的CSS通常是这样的,即把多余的空白都删掉。前两个规则之后的三个规则使用的空白量一个比一个多,最后一个规则几乎把所有可以分开的内容都写在单独的一行里。这些写法都是有效的,可以从中选一个自己觉得合理的,即易于阅读的,然后沿用下去。最常见的是使用空白分隔值中的多个关键字,多个关键字必须使用空白分开。
1.4.5 CSS注释
CSS支持注释,与C/C++注释非常相似,CSS注释也放在/* 和 */之间。
/* 这是一个CSS注释 */
与C++一样,CSS注释可以分成多行
/* 边是一个CSS注释,可以分成多行,完全没有问题 */
⚠️注意:CSS注释不能嵌套。下面是错误写法:
/* 这是一个注释,其中还有
一个注释,这是错的,
/* 另-个注释 */
回到第一个注释 */
在CSS中,注释只能使用/* */编写。因此,如果想把注释与规则放在同 一行,一定要注意如何放置。例如 ,下面是正确的方式 :
h1{color: gray;} /* 这个CSS注释有好几行 */
h2{color: silver;} /* 而它放在样式旁边 */
p{color: white;} /* 因此每一行都要 */
pre{color: gray;} /* 放在注释标记里 */
如果各行没有结束标记,那么样式表的多数内容将变成注释的一部分,从而失去作用。在下面这个实例中,只有第一个规则(h1{color: gray;}) 会应用到文档上,余下的规则变成了注释的一部分,被浏览器的渲染引擎忽略。
h1{color: gray;} /* 这个CSS注释有好几行
h2{color: silver;} 但是各行没有放在注释标注里。
p{color: white;} 因此最后三个样式
pre{color: gray;} 变成了注释的一部分 */
1.5 媒体查询
通过媒体查询(media query)定义浏览器在何种媒体环境中使用指定的样式表,过去,实现这一机制的方法是通过link元素或style元素的media属性设定媒体类型,或者为@import或@media指令提供媒体描述符。媒体查询更进一步,允许创作人员通过媒体描述符根据指定媒体类型的特性选择样式表。
1.5.1 用法
媒体查询可以在下述几个地方使用:
- link元素的media属性。
- style元素的media属性。
- @import声明的媒体描述符部分。
- @media声明的媒体描述符部分。
媒体查询可以是简单的媒体查询,也可以是复杂的媒体类型和特性的组合。
1.5.2 简单的媒体查询
针对下面这个例子,在所有媒体中,h1元素的颜色都是红褐色,但是,在投影媒体中body元素会有一个黄色背景。
h1{ color: marmoon;}
@media projection{
body{background:yellow;}
}
一个样式表中可以有任意多个@media块,而且每一个都有自己的一套媒体描述符。如果愿意,可以把所有规则都放在一个@media块里,就像下面这样:
@media all{
h1{color:marmoon;}
body{background:yellow;}
}
然而,这与去掉首尾两行的效果一模一样,完全没必要。
1.5.3 媒体类型
媒体查询最基本的形式媒体类型,由CSS2引入。媒体类型就是指明不同媒体的标注:
- all:用于所有展示媒体
- print:为有视力的用户打印文档时使用,也在预览打印效果时使用。
- screen: 在屏幕媒体上展示文档时使用。在桌面计算机上运行的所有web浏览器都是屏幕媒体用户代理。
多个媒体类型使用逗号分隔罗列。下面四种方式都能把一个样式表(或一个规则块)同时应用到屏幕媒体和印刷媒体上:
<link type="text/css" href="home.css" media="screen,print">
<style type="text/css" media="screen,print">...</style>
@import url(home.css) screen,print;
@media screen,print{...}
1.5.4 媒体描述符
对于在link元素或@import声明中设定过媒体类型的人来说,一定不会对媒体查询的位置感到陌生。下面两种方式都能把指定的外部样式表应用到彩打上:
<link href="home.css" type="text/css" media="print and (color)" rel="stylesheet">
@import url(home.css) print and (color);
能使用媒体查询类型的地方都能使用媒体查询,继续以彩打为例,这意味着可以通过一个逗号分隔的列表列出多个查询:
<link href="print-color.css" type="text/css" media="print and (color),screen and (color-depth:8)" rel="stylesheet">
@import url(print-color.css) print and (color),screen and (color-depth:8);
只要其中一个媒体查询的条件得到满足,就会应用指定的样式表。对前面的@import声明来说,使用彩色打印机打印文档,或者在色深足够的环境中渲染文档时会使用print-color.css。如果使用的是黑白打印机,两个查询的条件都不满足,因此print-color.css不会应用到文档上。在屏幕等媒体中渲染文档时也是如此。
一个媒体描述符包含一个媒体类型和一个或多个媒体特性列表,其中特性描述符要放在圆括号中。如果没有媒体类型,那就应用到所有媒体上,因此下面两个实例是等效的。
@media all and(min-resolution:96dpi){...}
@media (min-resolution:96dpi){...}
多个特性描述符使用逻辑关键字and连接。媒体查询中可使用的逻辑关键字有两个:
and
连接的两个或多个媒体特性必须同时满足条件,整个查询得到的结果才是真值。
not
对整个查询取反,假如所有条件都为真,那样式表不会应用到文档上。注意:not关键字只能在媒体查询的开头使用。(color)and not (min-device-width:800px),这样是无效的,如果真这样写,媒体查询将被忽略。还要注意,太旧的浏览器不支持媒体查询,因此会跳过媒体描述符以not开头的样式表。
only
在不支持媒体查询的旧浏览器中隐藏样式表,例如,如果想在所有媒体中应用一个样式表,但是只有在支持媒体查询的浏览器中应用,可以这样写:@import url(new.css) only all。在支持媒体查询的浏览器中,only关键字被忽略,样式表会应用到文档上。而在不支持媒体查询的浏览器中,媒体类型为only all,而这是无效的,因此不会应用样式表。注意,only关键字只能用在媒体查询中的开头。
1.5.5 媒体特性描述符和值的类型
1.6 特性查询
2015-2015年间,CSS新增了一个功能:根据用户代理是否支持特定的CSS属性及其值来应用一段样式,这个功能称为特性查询(feature query)。
特性查询在结构上与媒体查询很像。假设我们想在用户代理支持color属性时(显然是支持的)为元素设定颜色,可以这样写:
@supports(color:black){
body{color:black;}
h1{color:purple;}
h2{color:gray;}
}
上述代码的意思其实是,"如果你能识别并处理color: black 这样的属性和值组合,那就应用这段样式;否则,跳过这段样式。"如果用户代理不支持@supports,整段样式都会跳过。
特性查询是渐进增强样式的完美方式。比如说你想在浮动布局之外增加删格布局,可以保留现有的布局方式,在样式表中添加下面的这段样式:
@supports (display:grid){
section#main{display:grid;}
/*去掉旧布局的样式*/
/*删格布局的样式*/
}
这段样式在支持删格布局的浏览器中应用,它会覆盖旧的页面布局,然后应用通过删格实现的新布局。不支持删格布局的旧浏览器很可能也不支持@supports,因此会跳过整段样式,就像没有出现过一样。
特性查询可以嵌套,其实还可以嵌套在媒体查询中,而且反过来嵌套也可以。若想使用弹性盒布局编写针对屏幕和印刷媒体的样式,可以把媒体查询块放在@supports(display:flex)块里:
@supports (display:flex){
@media screen{ /* 针对屏幕媒体的弹性盒样式 */ }
@media print{ /* 针对印刷媒体的弹性盒样式 */ }
}
反过来,也可以在实现响应式设计的媒体查询块中添加@supports()块
@media screen and (max-width:30em){
@supports (display:flex){ /* 针对小屏的弹性盒样式 */ }
}
@media screen and (min-width:30em){
@supports (display:flex){ /* 针对大屏的弹性盒样式 */ }
}
与媒体查询一样,特性查询也支持使用逻辑运算符。假如想在用户代理同时支持删格布局和CSS形状时应用一段样式,可以这样写:
@supports (display:grid) and (shape-outside:circle()){ /* 删格和形状样式*/ }
下述和下述写法是等效的
@supports (display:grid){
@supports (shape-outside:circle()){ /* 删格和形状样式*/ }
}
除了and之外,还有其他的运算符可用,CSS形状体现了or的用处,因为很长一段时间以来,Webkit只支持通过带厂商前缀的属性绘制形状。因此,如果想绘制形状,可以使用这样的特性查询:
@supports (shape-outside:circle()) or
(-webkit-shape-outside:circle()){
/ * 绘制形状的样式 * /
}
带厂商前缀的形状属性和不带厂商前缀的形状属性最好同时使用,但是上例这样做既能兼容Webkit以后的版本,也能支持其他无需使用厂商前缀的浏览器。
有时,我们想使用的属性与测试的属性不同,还以删格布局为例,你可能想在支持删格时修改布局元素的外边距等。下面是简化的版本:
div#main{overflow:hidden;}
div.column{float:left;margin-right:1em;}
div.column:last-child{margin-righht:0;}
@supports (display:grid){
div#main{display:grid;grid-gap:1em 0;overflow:visible}
div#main div.column{margin:0;}
}
此外,还可以使用取反运算符。例如,下述样式在不支持删格布局时应用:
@supports not (display:grid){ /* 不支持删格时使用的样式 */ }
一个特性查询中可以使用多个逻辑运算符,但是为了保证条理清晰,要使用括号。假如我们想在支持颜色的同时还支持删格或弹性盒布局中的一个时应用一段样式,可以这样写:
@supports (color:black)and ((display:flex) or (display:grid)){ /* 相关的样式 */ }
第 2 章 选择符
2.1 样式的基本规则
CSS的一个核心优势是可以为文档中某种类型的元素全部应用相同的规则。假如我们想让所有的h2元素都显示为灰色,以前,我们只能编辑HTML,在每个h2元素中插入...标签,就算使用style属性,也省不了多少时间,你要为每个h2元素设定style="color:gray;"属性,这两种方式如下所示:
<h2><font color="gray">My name is mengZiJiang</font></h2>
<h2 style="color:gray;">My name is mengZiJiang</h2>
如果文档中有大量h2元素 ,这将是一个漫长乏味的过程。更糟的是,如果后来决定h2元素应该显示成绿色,而不是灰色,就必须重来一次,手动修改所有标签。CSS样式便于修改和编辑,而且能应用到指定的所有文本元素上。
2.1.1 元素选择符
元素选择符(element selector)通常是HTML元素,但也有例外。文档的CSS文件中,可能有下面这些元素选择符:
quote{color:gray;}
bib{color:red;}
booktitle{color:purple;}
myElement{color:red;}
也就是说,文档中的元素是最基本的选择符。在XML中,什么都可以作为选择符,因为XML允许创建新标记语言,所以什么都可以作为元素名称。然而,为HTML文档编写样式时,选择符一般是HTML预定义的某个元素,例如p、h3、em、a,甚至是html自身,例如:
html{color:black;}
h1{color:gray;}
h2{color:sliver;}
直接为元素定义全局样式后,可以把样式从一个元素身上移到另一个元素身上。
html{color:black;}
p{color:gray;}
h2{color:silver;}
2.1.2 声明和关键字
声明块中有一个或多个声明。声明的格式是固定的,先是属性,然后是冒号,后面再跟上值和分号。冒号和分号后面可以有零个或多个空白。值几乎都是一个关键字或以空格分隔的多个关键字。如果声明中的属性或值有误,整个规则都将被忽略。
CSS关键字通常以空格分隔。在CSS2.1中,有个特例:font属性的值有一处要使用斜线(/) 把两个关键字隔开。
h2{font:1arge/150% sans-serif;}
这个斜线把设定元素字号和行高的两个关键字分开。font声明只有这一个地方允许出现斜线,其他关键字都以空格分隔。
除此之外,其他一些属性的值中也可以使用斜线:
- background
- border-image
- border-radius
- grid
- grid-area
- grid-column
- grid-row
- grid-template
- mask-border
还有一些关键字以逗号分隔。声明多个背景图像,过渡属性和阴影时,相互之间以逗号分隔。此外,函数的参数,例如线性渐变和变形函数,以逗号分隔,如下例所示:
.box{
box-shadow:inset -1px -1px white,3px 3px 3px rgba(0,0,0,0.2);
background-image:url(myimage.png),linear-gradient(180deg,#FFF 0%,#000 100%);
transform:translate(100px,200px);
}
a:hover{transition:color,background-color 200ms ease-in 50ms;}
2.2 群组
如果想把同一个样式应用到多个元素上,可以使用多个选择符,或者把多个样式应用到一个元素或一组元素上。
2.2.1 群组选择符
群组可以在很大程度上压缩同类样式,这样得到的样式表更短。
body,table,th,td,h1,h2,h3,h4,p,pre,strong,em,b,i{color:gray;}
通用选择符
CSS2引入了一个新的选择符,名为通用选择符(universal selector), 写作星号(*), *这个选择符匹配所有元素,很像是通配符。
*{color:red;}
通用选择符虽然便利,但是它的特指度是0-0-0,而且由于目标是一切元素,可能出现一些意想不到的后果。
2.2.2 群组声明
一个规则可以有多个选择符,同理,也可以有多个声明。如果想让所有h1元素的颜色为紫色,字体为Helvetica,字号为18像素,且背景为浅绿色。
h1{font:18px Helvetica;}
h1{color:purple;}
h1{background:aqua;}
但是这样做效率低,可以把声明写在一起。
h1{font:18px Helvetica;color:purple;background:aqua;}
严格来说,一个规则中的最后一个声明的结尾可以不带分号,但一般建议带上,首先,这样做能让你养成带分号的习惯,毕竟缺少分号是导致渲染错误最常见的根源。其次,如果想在后面加一个声明,不用担心忘记补上分号。最后,如果使用Sass这样的预处理器,所有声明通常都要求在结尾加上分号。为了避免种种问题,编写规则时一定要加上分号。
2.2.3 二者结合
选择符和声明都可以写在一起。二者结合,只需几个声明便能定义十分复杂的样式,如果想为所有标题赋予一些复杂的样式,而且想让全部标题都使用相同的样式,可以如下:
h1,h2,h3,h4,h5,h6{color:gray;background:white;padding:0.5em;border:1px solid black;font-family:Charcoal,sans-serif;}}
这里,我们使用的是群组选择符,因此规则右侧的样式将应用于列出的所有标题 , 此外, 声明也是多个写在 一 起的,所以列出的样式将应用于左侧的所有选择符上。
2.2.4 在旧浏览器中使用新元素
HTML在更新的过程中加入了一些新元素。有些浏览器在这些新元素出现之前就已存在,因此可能无法识别新元素。例如,在Internet Explorer 9之前版本中无法选择不支持的元素。解决方法是在DOM中创建元素,让浏览器知道元素的存在。
例如,Internet Explorer 8 不识别
元素,使用下述 JavaScript 可以让Internet Explorer 8知道 main的存在:document.createElement('main');
运行这段代码后 ,旧版 Internet Explorer将认识到元素的存在,从而允许选择并为之赋予样式。
2.3 类选择符和ID选择符
从某种意义上讲,元素选择符很不错,但是有时候我们想指代得更明确一些,除了直接使用文档中的元素之外,还可以使用类选择符和ID选择符,这样便能以一种独立于元素的方式赋予样式。这两种选择符可以独立使用,也可以和元素选择符结合在一起使用。
2.3.1 类选择符
应用样式而不关心所涉及的元素,最常使用类选择符。要修改文档的标记,让类选择符起作用,修改方式是设定class属性,为了把类选择符定义的样式应用到元素上,必须为class属性赋予适当的值。
<p class="warning">my name is mengZiJiang</p>
为了把类选择符定义的样式应用到元素上,必须为class属性赋予适当的值,在CSS中,选择类的句法是在class属性的值前面加上点号(.)。除了单独选择类之外,还可以结合元素选择符
.warning{font-weight:bold;}p.warning{font-weight:bold;}
2.3.2 多个类
根据HTML规则,class属性的值可以是多个词,词之间使用空格分隔,词的顺序无关紧要。
<p class="urgent warning"></p>
<p class="warning urgent"></p>
假如你想让class属性的值为waring的元素显示为粗体,值为urgent的元素显示为斜体,而同时拥有二者的元素具有银色背景,样式可以这样写:
.waring{font-weight;}
.urgent{font-style:italic;}
.waring.urgent{background:silver;}
把两个类选择符串在一起,选择的是同时具有两个类名的元素,而且对类名对顺序没有要求。如果多个串联的类选择符包含class属性中没有的词,将无法匹配。
<p class="urgent warning help"></p>
2.3.3 ID选择符
ID选择符在某些方面类似于类选择符,不过二者之间有些重要区别。首先,ID选择符的开头不是点号,而是个散列字元(#),也叫#号、哈希符合、哈希记号或三连棋棋盘。ID选择符还有一个地方与类选择符相似,ID选择符不关心所用的元素。有时,你可能知道文档中有某个ID值,但是不知道它在哪个元素上,此时,可以直接使用ID选择符。
<p id="mostImportant">my name is mengZiJiang</p>
#mostImportant{color:red;background:yellow;}
下面的这些元素不能同时出现在一个文档中,因为他们的ID值是一样的;
<h1 id="mostImportant"></h1>
<em id="mostImportant"></em>
<ul id="mostImportant"></ul>
2.3.4 在类选择符和ID选择符之间选择
类可以赋予任意个元素,而ID在一个HTML文档中,一个ID能且只能使用一次。因此,如果文档中有个元素的id属性为lead-para,其他元素的id属性就不能再设为这个值。
与类选择符不同,ID选择符不能串在一起使用,因为ID属性的值不能是以空格分隔的列表。
类选择符和ID选择符之间的另一个区别是,用户代理判断该把哪个样式应用到元素上时,ID选择符的权重更高。
此外还要注意,类选择符和ID选择符可能是区分大小写的,这取决于文档语言。根据HTML规范,类和ID的值是区分大小写的,因此类选择符和ID选择符的大小写必须与文档中的一致。
2.4 属性选择符
不管是类选择符还是ID选择符,我们选择的其实都是属性的值。CSS2引入了属性选择符(attribute selector),根据属性及其值选择元素,属性选择符大致可以分为四类:简单属性选择符、精准属性值选择符,部分匹配属性值选择符和起始值属性选择符。
2.4.1 简单属性选择符
如果想选择具有某个属性的元素,而不管属性的值是什么,可以使用简单属性选择符。下面带class的会受样式控制。
<h1 class="name">Hello</h1>
<h1>World</h1>
<h1 class="age">20</h1>
/* CSS */
h1[class]{color:red;}
这种选择符在XML文档中特别有用,因为XML语言中的元素和属性都是根据目的而选用的。在HTML文档中,可以充分利用这一功能。例如,可以为所有具有alt属性的图像编写样式,突出显示格式正确的图像:
img[alt]{border:5px solid red;}
如果想把具有title属性的元素(在多数浏览器中,当鼠标悬停在这样的元素上时,会显示“提示框”),加粗显示,可以这么写:
*[title]{font-weight:bold;}
类似地,还可以基于多个属性选择。为此,要把多个属性选择符串在一起。例如,若想让同时具有href和title属性的HTML超链接显示为粗体,可以这样写:
a[href][title]{font-weight:bold;}
对下面的标记来说,第一个链接会显示为粗体,而第二个和第三个链接都不会显示为粗体:
<a href="http://www.w3.org/" title="W3C Home">W3C</a>
<a href="http://www.w3.org/">W3C</a>
<a title="Not a link">W3C</a>
2.4.2 根据精准的属性值选择
此外,还可以进一步缩小范围,只选择属性为特定值的元素。比如说我们想把所指向web服务器上某个文档的超链接显示为粗体,可以这么写:
a[href="http://www.css.org/about.html"]{font-weight:bold;}
这个规则把href属性的值为 "www.css.org/about.html" 的a元素显示为粗体。任何变化,都将会无法匹配。可以为任何元素指定任何属性和值的组合。然而,如果属性和值的组合在文档中未出现,那么选择符不匹配任何元素。同样,XML语言也很适合使用这种方式应用样式。
假设你只想选择moons属性的值为one的planet元素,写法如下,对下面的标记片段来说,这个样式将把第二个元素的文本设为粗体,而第一个和第三个元素不受影响:
<planet>Venus</planet>
<planet moons="one">Earth</planet><planet moons="two">Mars</planet>
与选择属性时一样,可以把多个属性和值选择符串在一起。例如,若想把href属性的值为www.w3.org/ ,和title属性的值为W3C Home的HTML超链接显示为两倍字号,可以这样写:
a[href="http://www.w3.org/"][title="W3C Home"]{font-size:200%:}
下面的操作将把第一个链接的文字字号加倍,而第二个和第三个链接不受影响,也说明了这个形式要求属性的值与指定的值完全一致。属性的值由空格分隔的多个词时要小心,以防匹配出错。
<a href="http://www.w3.org/" title="W3C Home">W3C</a>
<a href="http://www.webstandards.org/" title="web standards">Standards Info</a>
<a href="http://www.example.org/" title="W3C Home">W3C</a>
2.4.3 根据部分属性值选择
有时,我们想根据属性值的一部分选择元素,而不是完整的值。CSS为这种情况提供了多种选择,以不同的方式匹配属性值的子串。
一种特别的属性选择符
*[lang|= "en"]{color:red;}
上面这个规则选择lang属性的值为en或者以en-开头的元素。因此,对下述示例来说,前三个元素会被选中,而后两个不会:
<h1 lang="en">Hello!</h1>
<p lang="en-us">Greetings</p>
<div lang="en-au">day</div>
<p lang="fr">Bonjour</p>
<h4 lang="cy-en">Jrooana</h4>
一般来说,[att |= "val"] 形式可用于选择任何属性及其值。假设一个HTML文档中有一系列插图,而插图的文件名是figure-1.gif 和 figure-3.jpg 这样的,使用下述选择符可以匹配所有插图:
img[src|="figure"]{color:red;}
实际开发一个CSS框架或模式库,没必要提供"btn btn-small btn-arrow btn-active" 这样冗长的类,可以声明"btn-small-arrow-active",然后使用下述规则选择具有这个类的元素,这种属性选择符最常用于匹配语言名。
*[class |= "btn"]{border-radius:5px;}
<button class="btn-small-arrow-active">Click Me</button>
匹配以空格分隔的一组词中的一个
对值可以为一组以空格分隔的属性来说,可以根据其中有没有某个词来选择元素HTML中的class属性就是这样,它的值可以是一个或多个词。
<p class="urgent warning">my name is MengZiJiang!</p>
若想选择class属性的值包含warning的元素,可以使用下述属性选择符:
p[class~="warning"]{color:red;}
⚠️注意,选择符中有个波浪号(~),根据一组以空格分隔的词中是否有某个词选择时,不能忘了这个符号,如果没有波浪号,就变成前面说的精确值匹配属性选择符了。这个选择符的作用和点号加类名写法一样。也就是说,对HTML文档来说,p.warning 和 p[class ~= "warning"]是等效的。
<span class="barren rocky">Mercury</span>
<span class="cloudy barren">Venus</span><span class="life-bearing cloudy">Earth</span>
若想要选择class属性中包含barren这个词的所有元素,可以按照如下写,这与span.barren{font-style:italic}得到的结果一样。
span[class ~= "barren"]{font-style:italic;}
那么为什么还要有这样一种属性选择符呢?因为除了class属性之外还可以根据其他属性选择。
匹配属性值的子串
有时,我们想根据部分属性值选择元素,但是属性的值不是以空格分隔的一组词。此时,可以使用[att *= "val"] 形式匹配出现在属性值内部任何位置的子串。