CSS权威指南(第四版)笔记(第一章:css和文档)

884 阅读12分钟

第一章:css和文档

层叠样式表 (Cascading Style Sheets,缩写为 CSS),是一种 样式表 语言,用来描述 HTMLXML(包括如 SVGMathMLXHTML 之类的 XML 分支语言)文档的呈现。CSS 描述了在屏幕、纸质、音频等其它媒体上的元素应该如何被渲染的问题。

Web样式简介(CSS背景与发展)

Web早期,浏览器为用户提供了各种样式的定制功能,但是文档编写人员却不能制定样式。CSS就是在这样的背景下诞生的(当时已经有过一些样式表语言的建议了,但CSS是第一个含有“层叠”主意的)。

CSS的目标是提供一个简单的声明式样式语言,而且具有一定的灵活性,能够为文档编写人员和用户提供等同的样式化功能。层叠样式表中的层叠是指样式可以结合起来使用,而且具有优先级,文档编写人员和用户都有话语权,但是最终决定权在用户手中。

1994年CSS发布第一个草案,1996年年末CSS1完成了。此后CSS工作组开始制定CSS2,而各浏览器则开始实现CSS1。单独来看,CSS每一部分都很简单,但把各部分放在一起就会变得异常复杂。而且早期实现有些先天不足,例如不同浏览器对盒模型(box model)的实现之间有差异尤其为人诟病。

1998年年初CSS2定案。随后CSS工作组开始制定CSS3,以及CSS2的修订工作(制定CSS2.1)。与以往不同的是,CSS3有多个(理论上的)独立的模块构成,而不是单独一个臃肿的规范。

CSS3分成多个模块的根本原因是各模块可以独立演进,尤其是重要的(或是受众广的)模块可以按照W3C的规划向前推进,而不必受其他模块拖累。

事实证明,这样做是对的。

但是这样做也有缺点,那就是CSS规范不能涵盖一切。所以我们没有办法指着某些文件说:这就是CSS3,而是应该分模块学习不同的特性

如果要看单独的完整规范,可以留意CSS工作组每年发布的Snapshot 文档

元素

元素(element)是文档结构的根基,文档中每个元素都对文档的表现起一定作用。

置换元素和非置换元素

对CSS来说,元素通常有两种形式:置换元素非置换元素

置换元素(replaced element)指用来置换元素内容的部分不由文档内容直接表示。

常见的置换元素有imginput等。

非置换元素(nonreplaced element)指元素内容由用户代理(通常为浏览器)在元素自身生成的框中显示。

大部分HTML元素都是非置换元素,比如pspan等。

元素的显示方式

除了置换元素和非置换元素,CSS还把元素分为块级行内两种基本类型。(这两种最常见,除此之外还有其他的显示类型)。

块级元素默认生成一个填满父级元素内容区域的框,旁边不能有其他元素。也就是说,块级元素在元素框前后都有断行。常见的块级元素有pdiv

列表项目是一种特殊的块级元素,它会在元素框旁边生成一个记号(无序列表通常是圆点,有序列表通常是数字),除此之外列表项目和其他块级元素并没有什么不同。

行内元素在一行文本内生成元素框,不打断所在的行。最常见的行内元素是a

在HTML中,块级元素不能出现在行内元素中。但是在CSS中没有这个限制,可以随便嵌套。

把CSS应用到HTML上

link标签

<link rel="stylesheet" type="text/css" href="sheet.css" media="all">

link标签的作用是把其他文档与当前文档关联起来

CSS使用link链接的样式表不是HTML文档的一部分,但却供文档使用。我们称这样的样式表为外部样式表(external stylesheet)。

为了正确的加载样式表,link标签必须放在head元素中,不能放在其他元素中。

属性

  1. rel是relation(关系)的简称,这里指定的是stylesheet。
  2. type属性的值为text/css,说明通过link标签加载的数据类型。(可省略不写,默认为text/css)。
  3. href的值是样式表的URL。可以是绝对地址,或者相对地址。
  4. media属性,它的值是一个或多个媒体描述符(media descriptor),可以省略。

候选样式表

候选样式表(alternate stylesheet)的定义方式是把rel属性的值设为alternate stylesheet。仅当用户自己选择,文档才会使用候选样式表渲染。

如果浏览器支持候选样式表,会使用link元素title属性的值生成候选样式表列表。

<link rel="stylesheet" type="text/css" href="sheet1.css" title="Default">
<link rel="stylesheet" type="text/css" href="sheet2.css" title="Big Text">
<link rel="stylesheet" type="text/css" href="sheet3.css" title="Crazy Colors">

浏览器默认使用第一个样式表(这里是名为Default的样式表)。此外用户还可以自己选择想使用的样式表(实际上这就是CSS开始崭露头角之时的方式)。

下图为Firefox提供的候选样式表选项

1565024877015.png

多数基于Gecko的浏览器,IE11支持候选样式表,基于Webkit的浏览器不支持候选样式表。

style 元素

style元素也是一种引入样式表的方式,直接写在文档中:

<style type="text/css">...</style>

开始与结束style标签之间的样式表称为文档样式表(document stylesheet)或嵌入样式表(embedded stylesheet)。style元素可以直接包含应用到文档上的样式,也可以通过@import 指令引入外部样式表。

@import 指令

与link标签一样,Web浏览器遇到@import 指令时会加载外部样式表。但是**@import 指令必须写在样式表的开头**,否则不起作用。

一个文档中可以有多个@import 指令,但是无法指定候选样式表可以指定媒体描述符

行内样式

如果只是为单个元素提供少量样式,可以利用HTML元素的style属性设置行内样式。

<p style="color: red;">这是一段红色的字</p>

除了body元素之外的标签,所有的HTML标签都能设置style属性。

style属性中不能使用@import 指令。

HTTP链接

为文档关联CSS还有一种鲜为人知的方式:使用HTTP首部

在支持HTTP链接样式表的浏览器中(比如Firefox系列),可以用此方式将开发版与线上部署版区分开。

样式表中的内容

标记

样式表中除了HTML注释外,不能有任何标记。

规则的结构

h1 {
    color: red;
    background: yellow;
}

一个样式表由一系列规则组成。一个规则由两个基本部分构成:选择符(selector)和声明块(declaration block)。声明块由一个或多个声明组成,而一个声明包含一个属性(property)和对应的(value)。

如上面的规则所示:选择符为h1。声明块为大括号内的内容。声明块里面有两个声明:字体颜色为红色,背景颜色为黄色。所以整个规则为:对于文档中的所有h1元素,显示为黄底红字。

厂商前缀

CSS有些内容的前面有个标注,例如-o-border-image,这就叫做厂商前缀,浏览器通过它标记实验性或专属的属性、值或其他内容。

下表为一些常见的厂商前缀

前缀 厂商
-epub- 国际数字出版论坛制定的ePub格式
-moz- 基于Mozilla的浏览器(如Firefox)
-ms- 微软IE浏览器
-o- 基于Opera的浏览器
-webkit- 基于Webkit的浏览器(如Safari和Chrome)

厂商前缀的一般格式为一个英文破折号、一个标注和一个英文破折号。不过也有少量前缀开头没有破折号。

处理空白

CSS对规则之间的空白基本没有严格要求,而且对规则内部的空白也没有严格要求,不过有些例外。

一般来说,CSS对待空白的方式跟HTML差不多:解析时,连续的空白会被合并为一个空白(不论空白是空格,制表符还是换行符,甚至是他们的组合)。

下面这几种编写方式效果一样

p{color:pink;}
p {color: pink;}
p {
    color: pink;}
p {
    color: pink;
}
p
{
    color
    :
        pink
        ;
}

CSS注释

CSS支持注释,注释内容放在 /* 和 */之间,可以换行但是注释不能嵌套

正确的注释:

/*这是一个正确的注释,
注释可以换行。*/

错误的注释:

/*这是一个错误的注释,
	/*CSS的注释不能嵌套*/
*/

媒体查询

文档编写人员通过媒体查询(media query)定义浏览器在何种媒体环境中使用指定的样式表。

用法

媒体查询可以在下述几个地方使用:

  • link元素的media属性
  • style属性的media属性
  • @import 声明的媒体描述符部分
  • @media 声明的媒体描述符部分

媒体查询可以是简单的媒体类型,也可以是复杂的媒体类型和特性的组合。

简单的媒体查询

这个例子中,在所以媒体中h1元素都是红褐色,但是在投影媒体中body元素会有一个黄色背景。

h1{
    color: red;
}
@media projection {
    body{
        background: yellow;
    }
}

一个样式表中可以有任意多个@media块,而且每个都有自己的一套媒体描述符。

媒体类型

媒体查询最基本的形式媒体类型,由CSS2引入。媒体类型就是指明不同媒体的标注:

  • all:用于所有展示的媒体。
  • print:为有视力的用户打印文档时使用,也在预览打印效果时使用。
  • screen:在屏幕媒体(比如电脑的显示器,Web浏览器)上展示文档时使用。

多个媒体类型使用逗号分隔,比如同时应用到屏幕媒体和印刷媒体上:

@media screen, print{
	...
}

媒体描述符

一个媒体描述符包含一个媒体类型和一个或多个媒体特征列表,其中特征描述符要放在圆括号中。如果没有媒体类型,那就应用到所有媒体上面。

以下两个语句是等效的:

@media all and (min-resolution: 96dpi){...}
@media (min-resolution: 96dpi){...}

一般情况下,媒体特性描述符的格式类似于CSS中的一对属性和值。两者间最大的区别是特性描述符可以不包含值。因此,任何彩色媒体都符合(color)指定的条件。任何色深为16位的彩色媒体都符合(color:16)指定的条件。其实,不指定值的时候是在做判断。比如说,(color)的意思是:这个媒体是彩色的吗?

媒体查询可用的逻辑关键字有两个:

  • and:连接的两个或多个媒体特性必须同时满足条件,整个查询结果才为真值。

    (color) and (orientation: lamdscape) and (min-device-width: 800px)
    /*
        表示当媒体环境是彩色的,横着放的,而且设备宽度至少是800px像素时,才会应用样式表。
    */
    
  • not:对整个查询取反。只能用在媒体查询开头。

    (color) and not (min-device-width: 800px)
    /*
        错误!
        not只能放在媒体查询开头,这样写会被忽略。
    */
    

媒体查询不支持OR关键字。不过,分隔多个媒体查询的逗号相当于OR。

此外还有一个only关键字,专门用来保证向后兼容。

only:在不支持媒体查询的旧浏览器中隐藏样式表。只能用在媒体查询开头。

@import url(new.css) only all;
/*
	在支持媒体查询的浏览器中,only会被忽略。
	在不支持媒体查询的浏览器中,媒体类型为only all,无效,这个媒体查询语句会被忽略。
*/

媒体特性描述符和值的类型

至2017年年底所有可用的描述符
width max-device-height min-color-index
min-width aspect-ratio max-color-index
max-width min-aspect-ratio monochrome
device-width max-aspect-ratio min-monochrome
min-device-width device-aspect-ratio max-monochrome
max-device-width min-device-aspect-ratio resolution
height max-device-aspect-ratio min-resolution
min-height color max-resolution
max-height min-color orientation
device-height max-color scan
min-device-height color-index grid

此外,还有两种新增的值:

  • ratio
  • resolution

特性查询

2015~2016年间,CSS新增了一个功能,根据用户代理是否支持特定的CSS属性及其值来应用一段样式。这个功能被称为特性查询。

@supports (color: blank) {
    body {color: blank;}
    h1 {color:pink;}
}

上述代码的意思是:如果可以识别并处理color: blank这样的属性和值的组合,那么就应用这段样式。否则忽视它。

特性查询是渐进增强的完美方式。

与媒体查询一样,特性查询支持使用逻辑运算符andornot

特性查询为什么既要写属性也要写值?比如测试是否支持栅格布局:

@supports (display) {
    /* 栅格样式 */
}

这样写肯定不行,因为支持display属性的不一定支持grid这个值。

注意:特性查询不是正确性查询,无法保证所有支持的浏览器的实现效果一样。