PHP-MySQL-和-JavaScript-学习指南第六版-七-

36 阅读49分钟

PHP、MySQL 和 JavaScript 学习指南第六版(七)

原文:zh.annas-archive.org/md5/4aa97a1e8046991cb9f8d5f0f234943f

译者:飞龙

协议:CC BY-NC-SA 4.0

第十九章:CSS 简介

使用层叠样式表(CSS),你可以对网页应用样式,使其看起来完全符合你的期望。这是因为 CSS 与文档对象模型(DOM)相关联,我在第十四章中有所解释。

借助 CSS 及其与 DOM 的集成,你可以快速轻松地重新设计任何元素。例如,如果你不喜欢<h1><h2>和其他标题标签的默认外观,可以分配新的样式以覆盖用于设置字体系列和大小,以及是否应设置粗体或斜体等许多其他属性的默认设置。

你可以通过在页面头部的<head></head>标签之间插入所需的语句来为网页添加样式。所以,要更改<h1>标签的样式,你可以使用以下代码(稍后我将解释语法):

<style>
  h1 { color:red; font-size:3em; font-family:Arial; }
</style>

在 HTML 页面中,这可能看起来像示例 19-1(见图 19-1),与本章中的所有示例一样,使用标准的 HTML5DOCTYPE声明。

示例 19-1. 一个简单的 HTML 页面
<!DOCTYPE html>
<html>
  <head>
    <title>Hello World</title>
    <style>
      h1 { color:red; font-size:3em; font-family:Arial; }
    </style>
  </head>
  <body>
    <h1>Hello there</h1>
  </body>
</html>

在插图中显示原始样式的标签样式

图 19-1. 在插图中显示原始样式的标签样式

导入样式表

当你希望为整个站点设置样式,而不仅仅是单个页面时,更好的管理样式表的方法是将它们完全移出网页并放入单独的文件中,然后导入你需要的样式表。这样可以让你为不同的布局(如网页和打印)应用不同的样式表,而不必更改 HTML。

有几种不同的方法可以实现这一点。首先是使用 CSS 的@import指令,就像这样:

<style>
  @import url('styles.css');
</style>

这个语句告诉浏览器获取一个名为styles.css的样式表。@import命令非常灵活,因为你可以将它放在一个样式表中,所以样式表可以引入其他样式表,依此类推。只要确保你的任何外部样式表中没有<style></style>标签,否则它们将不起作用。

从 HTML 中导入 CSS

你也可以使用 HTML 的<link>标签包含样式表,就像这样:

<link rel='stylesheet' href='styles.css'>

这与@import指令具有完全相同的效果,唯一的区别是<link>是一个仅限于 HTML 的标签,不是有效的样式指令,因此无法从一个样式表中使用它来引入另一个样式表,也无法放置在一对<style>...</style>标签内。

就像你可以在 CSS 中使用多个@import指令来包含多个外部样式表一样,你也可以在 HTML 中使用尽可能多的<link>元素。

嵌入式样式设置

当然,你也可以在当前页面的 HTML 中直接插入样式声明来逐个设置或覆盖某些样式,例如这样(结果是标签内部的斜体蓝色文本):

<div style='font-style:italic; color:blue;'>Hello there</div>

但这应该仅在非常特殊的情况下使用,因为它打破了内容和表现的分离,因此维护起来非常麻烦。

使用 ID

在 HTML 中,更好的方法是为元素分配一个 ID,就像这样:

<div id='welcome'>Hello there</div>

这表示具有 ID 为welcome<div>元素的内容应用在定义为welcome样式设置中的样式上。这个匹配的 CSS 语句可能如下所示:

#welcome { font-style:italic; color:blue; }
注意

注意使用#符号,指定只有名为welcome的 ID 的元素才会应用此样式。

使用类

id元素的值在网页中必须是唯一的,因为这是它作为标识符的依据。如果你想将相同的样式应用于多个元素,你不必为每个元素分配不同的 ID,因为你可以指定一个类来管理它们,就像这样:

<div class='welcome'>Hello</div>

这表示这个元素的内容(以及使用该类的任何其他元素)应用了在welcome类中定义的样式。一旦应用了类,你可以使用以下规则,无论是在页面头部还是在外部样式表中,来设置类的样式:

.welcome { font-style:italic; color:blue; }

而不是#符号,该符号保留用于 ID,类的语句则以.(句点)开头。

使用分号

在 CSS 中,分号用于分隔同一行上的多个 CSS 语句。但是,如果规则中只有一个语句(或者在 HTML 标签内的内联样式设置中),则可以省略分号,就像在一组中的最后一个语句那样。

然而,为了避免难以发现的 CSS 错误,你可能更喜欢在每个 CSS 设置后始终使用分号。这样,你可以复制和粘贴它们,并且可以修改属性,而不必担心在不必要的地方删除分号或者在必要的地方添加分号。

CSS 规则

CSS 规则中的每个语句都以选择器开始,这是将应用规则的项目。例如,在这个赋值中,h1是被赋予比默认字体大小大 240%的选择器:

h1 { font-size:240%; }

font-size是一个属性。为选择器的font-size属性提供240%的值确保了所有<h1>...</h1>标签对的内容将以比默认大小大 240%的字体大小显示。所有规则中的更改都必须在跟随选择器的{}符号内进行。在font-size:240%;中,冒号:前面的部分是属性,而其余部分是应用于它的值。

最后,使用一个;(分号)来结束语句。在这种情况下,因为font-size是规则中的最后一个属性,所以分号是不必要的(但是如果后面还有其他赋值,则是必需的)。

多重赋值

可以通过几种不同的方式创建多个样式声明。首先,可以将它们连接在同一行上,就像这样:

h1 { font-size:240%; color:blue; }

这添加了第二个分配,将所有<h1>标题的颜色更改为蓝色。您还可以像下面这样每行放置一个分配:

h1 { font-size:240%;
color:blue; }

或者您可以稍微分开分配,使它们在冒号下面彼此对齐成列,像这样,这可能是现在首选的方法:

h1 {
  font-size:240%;
  color    :blue;
}

这样,您可以轻松地看到每个新规则集从哪里开始,因为选择器总是位于第一列,后面跟随的分配都整齐地对齐,所有属性值从相同的水平偏移开始。在上述示例中,最后的分号是不必要的,但是如果您想把这些语句组合成一行,只需将所有分号放在正确的位置即可。

您可以指定相同的选择器任意次数,CSS 将合并所有属性。因此,前面的示例也可以指定如下:

h1 { font-size: 240%; }
h1 { color    : blue; }
注意

在布局 CSS 时没有一种正确或错误的方式,但我建议您至少尝试使每个 CSS 块在视觉布局上保持一致,以便其他人能够一目了然。

如果您指定了相同的选择器和属性两次会怎么样?

h1 { color : red; }
h1 { color : blue; }

指定相同选择器的相同属性,最后指定的值将生效——在这种情况下是蓝色。在单个文件中,对同一选择器重复相同属性是没有意义的,但在现实的网页中,当应用多个样式表时经常发生这种重复。这是 CSS 的一个宝贵特性,也是“层叠”一词的来源之一。

使用注释

对您的 CSS 规则进行注释是一个好主意,即使只描述主要的语句组,而不是所有或大多数语句。可以通过在/*...*/标签对之间放置注释来实现,如下所示:

/* This is a CSS comment */

您可以扩展注释到多行,如下所示:

/*
 A multi-
 line
 comment
*/
注意

使用多行注释时,请注意不能在其中嵌套单行(或其他任何)注释。这样做可能会导致不可预测的错误。

样式类型

样式类型有多种,从浏览器设置的默认样式(以及您可能在浏览器中应用的用户样式,用于覆盖其默认样式),到内联或嵌入式样式,再到外部样式表。每种类型定义的样式具有从低到高的优先级层次。

我们将更详细地讨论层叠样式表中的“层叠”部分,详细解释见“CSS 层叠”。但在深入细节之前,先简要介绍一下会有所帮助。

默认样式

网页浏览器应用的样式优先级最低。这些样式是作为备用样式创建的,用于在网页没有任何样式时使用,旨在提供一组通用的样式,以在大多数情况下显示得相当不错。

在 CSS 出现之前,这些是文档中唯一的样式,并且只有少数样式可以由网页更改(如字体、颜色和一些元素大小的参数)。

用户样式

用户样式具有下一个最高的优先级。它们被大多数现代浏览器支持,但每个浏览器的实现方式都有所不同,因此如今为你创建自己喜欢的浏览样式最简单的方式是使用诸如 Stylish 的插件。

如果你想为浏览创建自己的默认样式,Stylish 是一个方便的工具。只需搜索“stylish 扩展”来在你的浏览器中安装它,如 图 19-2 所示。

图 19-2. Stylish 是一种你可以根据自己的喜好为网页添加样式的方式

如果已分配了用户样式,并且已定义为浏览器默认值,则它将覆盖浏览器的默认设置。任何未在用户样式表中定义的样式将保留它们在浏览器中设置的默认值。

外部样式表

下一种类型的样式是外部样式表中定义的。这些设置会覆盖用户或浏览器分配的任何样式。外部样式表是创建你的样式的推荐方式,因为你可以为不同的用途创建不同的样式表,比如通用的网页使用、在较小屏幕上的移动浏览器查看、打印等等。当你创建网页时,只需为每种媒体应用需要的样式表即可。

内部样式

接下来是内部样式,你可以在 <style>...</style> 标签内创建,并且优先于之前所有的样式类型。不过,这时候你开始打破样式与内容之间的分离,因为同时加载的任何外部样式表的优先级会更低。

内联样式

最后,内联样式是直接将属性分配给元素的方式。它们拥有任何样式类型中的最高优先级,并且像这样使用:

<a href="http://google.com" style="color:green;">Visit Google</a>

在这个例子中,指定的链接将显示为绿色,而不管任何默认或其他样式表应用的颜色设置,无论是直接应用于此链接还是通用应用于所有链接。

注意

当你使用这种类型的样式时,你正在打破布局与内容之间的分离;因此,建议仅在有很好的理由时这样做。

CSS 选择器

访问一个或多个元素的方法称为选择,执行此操作的 CSS 规则的一部分称为选择器。正如你所预期的那样,选择器有多种变体。

类型选择器

类型选择器用于 HTML 元素类型,如 <p><i>。例如,以下规则将确保所有 <p>...</p> 标签内的文本完全右对齐:

p { text-align:justify; }

后代选择器

后代选择器允许你将样式应用到包含在其他元素内的元素上。例如,以下规则将所有<p>...</p>标签中的<b>...</b>标签内的文本设为红色,但前提是这些标签出现在<p>...</p>标签内(像这样:<p><b>Hello</b> there</p>):

p b { color:red; }

后代选择器可以无限嵌套,所以下面的规则也是有效的,它将无序列表中列表元素内的粗体文本设为蓝色:

ul li b { color:blue; }

作为一个实际的例子,假设你想要在嵌套在另一个有序列表中的有序列表中使用不同的编号系统。你可以通过以下方式实现,它将用小写字母(从a开始)替换默认的数字编号(从1开始):

<!DOCTYPE html>
<html>
  <head>
    <style>
      `ol` `ol` `{` `list-style-type``:``lower-alpha``;` `}`
    </style>
  </head>
  <body>
    <ol>
      <li>One</li>
      <li>Two</li>
      <li>Three <ol>
          <li>One</li>
          <li>Two</li>
          <li>Three</li>
        </ol>
      </li>
    </ol>
  </body>
</html>

将这段 HTML 加载到网络浏览器中的结果如下,你可以看到第二个元素列表显示不同:

1\. One
2\. Two
3\. Three
  a. One
  b. Two
  c. Three

子选择器

子选择器类似于后代选择器,但在应用样式时更为严格,仅选择直接是另一个元素的子元素的那些元素。例如,以下代码使用后代选择器,将段落内的任何粗体文本都改为红色,即使粗体文本本身位于斜体文本部分中(像这样<p><i><b>Hello</b> there</i></p>):

p b { color:red; }

在这种情况下,单词Hello显示为红色。然而,当不需要这种更一般的行为时,可以使用子选择器来缩小选择器的范围。例如,以下规则插入了一个大于号(>)以创建子选择器,仅当元素是段落的直接子元素且不位于另一个元素内时,将粗体文本设为红色:

p > b { color:red; }

现在Hello不会改变颜色,因为<b>不是<p>的直接子元素。

举个实际的例子,假设你希望仅将直接位于<ol>元素下的<li>元素加粗。你可以按照以下方法实现,其中直接位于<ul>元素下的<li>元素不会加粗:

<!DOCTYPE html>
<html>
  <head>
    <style>
      `ol` `>` `li` `{` `font-weight``:``bold``;` `}`
    </style>
  </head>
  <body>
    <ol>
      <li>One</li>
      <li>Two</li>
      <li>Three</li>
    </ol>
    <ul>
      <li>One</li>
      <li>Two</li>
      <li>Three</li>
    </ul>
  </body>
</html>

将这段 HTML 加载到浏览器中的结果将如下所示:

1\. One
2\. Two
3\. Three

 • One
 • Two
 • Three

ID 选择器

如果给一个元素赋予 ID 名称(像这样<div id='mydiv'>),你可以通过以下方式直接从 CSS 中访问它,将元素内所有文本改为斜体:

#mydiv { font-style:italic; }

每个 ID 在文档中只能使用一次,因此只会将第一个找到的出现位置按照 CSS 规则的新属性值进行更改。但在 CSS 中,可以直接引用具有相同名称的任何 ID,只要它们出现在不同的元素类型中,像这样:

<div id='myid'>Hello</div> <span id='myid'>Hello</span>

因为 ID 通常仅适用于唯一的元素,所以下面的规则将仅为第一个出现的myid应用下划线:

#myid { text-decoration:underline; }

然而,你可以确保 CSS 将规则应用于两者的方法如下:

span#myid { text-decoration:underline; }
div#myid  { text-decoration:underline; }

或者更简洁地写成这样(参见“通过组选择”):

span#myid, div#myid { text-decoration:underline; }
注意

我不建议使用这种选择形式,因为它增加了对 JavaScript 使用的障碍。任何还必须访问这些元素的 JavaScript 也不能轻松地这样做,因为常用的getElementById函数将只返回第一个出现的元素。要引用任何其他实例,程序必须搜索文档中所有元素的整个列表——这是一个更棘手的任务。因此,通常最好始终使用唯一的 ID 名称。

类选择器

当您希望在页面中的多个元素之间共享相同的样式时,可以为它们分配相同的类名(如此:<span class='myclass'>)。然后创建一个单一规则一次性修改所有这些元素,如以下规则,为使用该类的所有元素创建一个 10 像素的左边距偏移量:

.myclass { margin-left:10px; }

在现代浏览器中,您可以让 HTML 元素使用多个类,类名之间用空格分隔,例如:<span class='class1 class2 class3'>

您可以通过指定应用该类的元素类型来缩小类的作用范围。例如,以下规则仅适用于使用类main的段落:

p.main { text-indent:30px; }

在这个示例中,只有使用类main(如此:<p class="main">)的段落会接收新的属性值。任何其他尝试使用该类的元素类型(例如<div class="main">)都不会受到这个规则的影响。

属性选择器

许多 HTML 标签支持属性,使用这种类型的选择器可以避免使用 ID 和类来引用它们。例如,您可以直接以以下方式引用属性,这样可以将所有具有type="submit"属性的元素设置为 100 像素的宽度:

[type="submit"] { width:100px; }

如果您希望将选择器的范围缩小到仅限于带有该属性类型的<form>输入元素,则可以改用以下规则:

form input[type="submit"] { width:100px; }
注意

属性选择器也适用于 ID 和类,因此,例如,[class~="classname"]的工作方式与类选择器.classname完全相同(只是前者具有更高的优先级)。同样,[id="idname"]等同于使用 ID 选择器#idname。因此,带有#.前缀的类和 ID 选择器可以视为带有更高优先级的属性选择器的速记。~=运算符匹配属性,即使它是一组以空格分隔的属性之一。

通用选择器

通配符*或通用选择器匹配任何元素,因此以下规则将通过给所有元素添加绿色边框来彻底弄乱文档:

* { border:1px solid green; }

因此,很少会单独使用*,但作为复合规则的一部分,它可以非常强大。例如,以下规则将适用与前述规则相同的样式,但仅适用于作为具有 ID boxout的元素的子元素的所有段落,并且只要它们不是直接子元素:

#boxout * p {border:1px solid green; }

让我们看看这里发生了什么。在#boxout后面的第一个选择器是一个*符号,因此它指的是boxout对象中的任何元素。然后,以下p选择器通过将选择器更改为仅适用于由*选择器返回的元素的段落(由p定义)来缩小选择焦点。因此,此 CSS 规则执行以下操作(其中我可以互换使用术语对象元素):

  1. 找到具有 ID boxout 的对象。

  2. 找到第 1 步返回的对象的所有子元素。

  3. 在第 2 步返回的对象中找到所有 p 子元素,并且由于这是组中的最终选择器,还要找到第 2 步返回的对象的所有 p 子及子子元素(等等)。

  4. {} 字符之间的样式应用于第 3 步返回的对象。

这样做的结果是,绿色边框仅应用于主元素的子子代(或曾孙代等等)中的段落。

通过组选择

使用 CSS,您可以通过逗号分隔选择器一次性将规则应用于多个元素、类或任何其他类型的选择器。例如,以下规则将在所有段落、具有 ID idname 的元素以及使用类 classname 的所有元素下方放置一个虚线橙色线条:

p, #idname, .classname { border-bottom:1px dotted orange; }

图 19-3 显示了使用的各种选择器及其附带的规则。

一些 HTML 及其使用的 CSS 规则

图 19-3. 一些 HTML 及其使用的 CSS 规则

CSS 层叠

如前所述,CSS 属性中最基本的之一就是它们会层叠 — 因此称为层叠样式表。但这意味着什么呢?

层叠是一种用于解决浏览器支持的各种样式表之间潜在冲突并按照创建者、创建样式的方法和所选属性类型优先顺序应用它们的方法。

样式表创建者

所有现代浏览器都支持三种主要类型的样式表。按优先级从高到低的顺序,它们如下:

  1. 由文档作者创建的样式

  2. 由用户创建的样式

  3. 由浏览器创建的样式

这三组样式表按相反顺序处理。首先,将默认值应用于文档中的网络浏览器。如果没有这些默认值,不使用样式表的网页将看起来很糟糕。它们包括字体、大小和颜色;元素间距;表边框和间距;以及用户期望的所有其他合理标准。

接下来,如果用户已创建任何用于替代标准样式的样式,则会应用这些样式,取代可能冲突的浏览器默认样式。

最后,将应用由当前文档作者创建的任何样式,以替换已由浏览器默认或用户创建的样式。

样式表方法

样式表可以通过三种不同方法创建。从高到低的优先顺序如下:

  1. 作为内联样式

  2. 在嵌入式样式表中

  3. 在外部样式表中

同样,样式表创建的这些方法按照优先顺序的相反顺序应用。因此,首先处理所有外部样式表,并将其样式应用于文档。

其次,处理任何嵌入样式(在 <style>...</style> 标签内),并优先处理与外部规则冲突的样式,并将其覆盖。

最后,将直接应用于元素的任何样式(例如 <div style="...">...</div>)作为内联样式具有最高优先级,并覆盖所有先前分配的属性。

样式表选择器

有三种不同的选择元素进行样式设置的方法。按照优先顺序从高到低,它们如下:

  1. 按单个 ID 或属性选择器引用

  2. 按类分组引用

  3. 按元素标签引用(例如 <p><b>

根据规则影响的元素数量和类型处理选择器,这与解决冲突的前两种方法略有不同。这是因为规则不必同时仅适用于一种选择器类型,并且可能引用多种不同的选择器。

因此,我们需要一种方法来确定可以包含任意选择器组合的规则的优先顺序。CSS 通过计算每个规则的特异性来实现这一点,按照其作用范围的从宽到窄的顺序对其进行排序。

计算特异性

我们通过基于前述编号列表中的选择器类型创建三部分数字来计算规则的特异性。这些复合数字起始形式为[0,0,0]。在处理规则时,每个引用 ID 的选择器会使第一个数字增加 1,因此复合数字会变为[1,0,0]

让我们看一下以下规则,它引用了七个选择器。其中三个是对 ID #heading#main#menu 的引用,因此复合数字变为[3,0,0]

#heading #main #menu .text .quote p span {
  // Rules go here;
}

然后,选择器中类的数量放置在复合数字的第二部分。在此示例中,有两个类 (.text.quote),因此复合数字变为[3,2,0]

最后,统计所有引用元素标签的选择器,并将此数字放置在复合数字的最后部分。在此示例中,有两个选择器 (pspan),因此最终复合数字为[3,2,2]

这是比较此规则特异性与其他规则所需的全部内容。在像这种情况下,复合数字中每种类型都不超过九个,可以直接转换为十进制数,本例中为 322。低于此数的规则优先级较低,高于此数的规则优先级更高。如果两个规则具有相同的值,则最近应用的规则胜出。

例如,假设我们还有以下规则:

#heading #main .text .quote .news p span {
  // Rules go here;
}

在这里,尽管还引用了七个元素,但现在只有两个 ID 引用,但三个类引用,这导致了复合数字[2,3,2]。由于 322 大于 232,前者的例子优先于后者。

使用不同的数字基数

当一个复合数字中有超过九个以上的类型时,你必须使用更高的数字基数。例如,你无法简单地将复合数字[11,7,19]连接起来转换为十进制。相反,你必须将数字转换为更高的基数,如 20 进制(或更高,如果任何类型超过 19 个)。

要做到这一点,请像这样将三个部分相乘并添加结果,从最右边的数字开始,从右向左工作:

         20 × 19 = 380
      20×20 ×  7 = 2800
   20×20×20 × 11 = 88000
Total in decimal = 91180

在左边,将20的值替换为你使用的基数。一旦一组规则的复合数字从此基数转换为十进制,就很容易确定每个数字的特异性和因此的优先级。

幸运的是,CSS 处理器会为你处理所有这些问题,但了解它的工作原理有助于你正确构建规则并理解它们将具有的优先级。

注意

如果所有这些优先级计算听起来相当复杂,你会高兴地知道,在大多数情况下,你通常可以通过这个简单的经验法则来解决:一般来说,要修改的元素越少,它们越具体,规则的优先级就越高。

有些规则比其他规则更平等

当两个或多个样式规则完全等效时,只有最近处理的规则会优先生效。然而,通过使用!important声明,你可以强制某个规则比其他等效规则具有更高的优先级,例如:

p { color:#ff0000 !important; }

当你这样做时,所有先前的等效设置都将被覆盖(甚至使用!important的设置),并且稍后处理的任何等效规则都将被忽略。因此,例如,以下两个规则中的第二个通常会优先生效,但由于在先前分配中使用了!important,第二个规则被忽略了:

p { color:#ff0000 !important; }
p { color:#ffff00 }
注意

用户样式表可以用于指定默认浏览器样式,并且它们可能使用!important声明,此时用户的样式设置将优先于当前网页中指定的相同属性。还需要注意,非!important的用户样式设置将被网页中任何!important样式所覆盖。

<div><span>元素之间的区别

<div><span>元素都是容器类型,但具有一些不同的特性。默认情况下,<div>元素具有无限的宽度(至少到浏览器边缘),你可以通过为其中一个应用边框来查看,例如:

<div style="border:1px solid green;">Hello</div>

然而,<span> 元素的宽度仅限于其包含的文本。因此,以下 HTML 行仅在单词 Hello 周围创建边框,不会延伸到浏览器的右侧边缘:

<span style="border:1px solid green;">Hello</span>

此外,<span> 元素随文本或其他对象的换行或流动而跟随,并且因此可以具有复杂的边框。例如,在 示例 19-2 中,我使用 CSS 将所有 <div> 元素的背景设为黄色,将所有 <span> 元素设为青色,并为两者添加了边框,然后创建了几个示例 <span><div> 部分。

示例 19-2. <div><span> 示例
<!DOCTYPE html>
<html>
  <head>
    <title>Div and span example</title>
    <style>
      div, span { border          :1px solid black; }
      div       { background-color:yellow;          }
      span      { background-color:cyan;            }
    </style>
  </head>
  <body>
    <div>This text is within a div tag</div>
    This isn't. <div>And this is again.</div><br>

    <span>This text is inside a span tag.</span>
    This isn't. <span>And this is again.</span><br><br>

    <div>This is a larger amount of text in a div that wraps around
    to the next line of the browser</div><br>

    <span>This is a larger amount of text in a span that wraps around
    to the next line of the browser</span>
  </body>
</html>

图 19-4 显示了此示例在 Web 浏览器中的样子。尽管在打印的书中只显示为灰色,但该图清楚地展示了 <div> 元素如何延伸到浏览器窗口的右侧边缘,并强制下面的内容出现在第一个可用位置的起始处。

不同宽度的各种元素

图 19-4. 不同宽度元素的各种类型

图中还显示了 <span> 元素如何保持独立,并且仅占用足够容纳其内容的空间,而不会强制下面的内容出现在它们下面。

此外,在图中的最后两个示例中,您可以看到当 <div> 元素在屏幕边缘换行时,它们保持矩形形状,而 <span> 元素只是随着包含的文本(或其他内容)流动(或换行)。

注意

由于 <div> 元素只能是矩形的,它们更适合用于包含像图片、盒子、引用等对象,而 <span> 标签最适合用于容纳文本或其他按行内顺序排列的属性,其应从左到右(或某些语言中从右到左)流动。

测量

CSS 支持多种测量单位,可以精确地调整网页到特定的数值或相对尺寸。我通常使用的有像素、点、ems 和百分比,但这里是完整列表:

像素

像素的大小根据用户屏幕的尺寸和像素深度而变化。一个像素等于屏幕上单个点的宽度/高度,因此该测量单位最适合屏幕而不是印刷。例如:

.classname { margin:5px; }

一点相当于一英寸的 1/72 大小。该测量单位来自于印刷设计背景,最适合于该媒介,但也常用于屏幕显示。例如:

.classname { font-size:14pt; }

英寸

一英寸等于 72 点,是最适合印刷的测量单位。例如:

.classname { width:3in; }

厘米

厘米是另一种最适合印刷的度量单位。一厘米略大于 28 点。例如:

.classname { height:2cm; }

毫米

毫米是厘米的十分之一(或接近 3 点)。毫米是另一种最适合印刷的度量单位。例如:

.classname { font-size:5mm; }

Picas

点(Pica)是另一种印刷排版测量单位,相当于 12 点。例如:

.classname { font-size:1pc; }

Ems

一个 em 等于当前字体大小,因此在 CSS 中它是描述相对尺寸的更有用的测量单位之一。例如:

.classname { font-size:2em; }

Exs

Ex 是与当前字体大小相关的,它相当于小写字母 x 的高度。这是一种较少使用的度量单位,最常用作帮助设置将包含一些文本的框的宽度的良好近似值。例如:

.classname { width:20ex; }

百分比

这个单位与 em 相关,因为它在字体上的倍数是 100(当用于字体时)。而 1 em 等于当前字体大小,相同大小的百分比是 100。当不涉及字体时,此单位相对于正在访问的属性的容器的大小。例如:

.classname { height:120%; }

图 19-5 显示依次使用这些测量类型来显示几乎相同大小的文本。

几乎相同大小的不同测量

图 19-5. 几乎相同大小的不同测量

字体和排版

你可以使用 CSS 更改四个主要的字体属性:font-familyfont-stylefont-sizefont-weight。通过它们,你可以微调网页和/或打印时文本的显示方式。

字体系列

font-family 属性指定要使用的字体。你可以按照优先级从左到右列出各种字体,这样当用户没有安装首选字体时,样式可以优雅地回退。例如,要设置段落的默认字体,你可以使用类似这样的 CSS 规则:

p { font-family:Verdana, Arial, Helvetica, sans-serif; }

如果一个字体名称由两个或更多单词组成,你必须用引号将名称括起来,像这样:

p { font-family:"Times New Roman", Georgia, serif; }

因为它们几乎可以在所有的网页浏览器和操作系统中使用,所以在网页上使用的最安全的字体系列包括 Arial、Helvetica、Times New Roman、Times、Courier New 和 Courier。Verdana、Georgia、Comic Sans MS、Trebuchet MS、Arial Black 和 Impact 字体适用于 Mac 和 PC,但可能未安装在其他操作系统(如 Linux)上。其他常见但较不安全的字体包括 Palatino、Garamond、Bookman 和 Avant Garde。如果你使用了其中一种较不安全的字体,请确保在你的 CSS 中提供一个或多个更安全的字体作为备用,以便在没有你首选字体的浏览器上,你的网页能够优雅地降级显示。

图 19-6 显示这两组 CSS 规则的应用。

选择字体系列

图 19-6. 选择字体系列

字形

使用font-style属性,您可以选择以普通、斜体或倾斜方式显示字体。以下规则创建了三个类(normalitalicoblique),可以应用于元素以创建这些效果:

.normal  { font-style:normal;  }
.italic  { font-style:italic;  }
.oblique { font-style:oblique; }

字号

正如在测量部分中所述,你可以以多种方式更改字体的大小。但这些归结为两种主要类型:固定大小和相对大小。固定设置如下规则,将默认段落字体大小设置为 14 点:

p { font-size:14pt; }

或者,您可能希望使用当前默认的字体大小来为各种类型的文本设置样式,比如标题。在以下规则中,定义了一些标题的相对大小,例如,<h4>标签比默认大小大 20%,每个更大的尺寸比上一个大 40%:

h1 { font-size:240%; }
h2 { font-size:200%; }
h3 { font-size:160%; }
h4 { font-size:120%; }

图 19-7 展示了正在使用的一些字体大小的选择。

设置四个标题大小和默认段落大小

图 19-7. 设置四个标题大小和默认段落大小

字重

使用font-weight属性,您可以选择以何种粗细显示字体。它支持许多值,但您可能主要使用的是normalbold,如下所示:

.bold { font-weight:bold; }

管理文本样式

无论使用哪种字体,你都可以通过修改其装饰、间距和对齐方式进一步修改文本的显示方式。文本和字体属性之间存在交叉,比如斜体或粗体文字通过font-stylefont-weight属性实现,而下划线等则需要text-decoration属性。

装饰

使用text-decoration属性,您可以对文本应用效果,如underlineline-throughoverlineblink。以下规则创建了一个名为over的新类,将横线应用于文本(横线、下划线和删除线的粗细将与字体相匹配):

.over { text-decoration:overline; }

在图 19-8 中,你可以看到一些字体样式、粗细和装饰的选择。

可用样式和装饰规则的示例

图 19-8. 可用样式和装饰规则的示例

间距

许多不同的属性允许你修改行、词和字母的间距。例如,以下规则通过修改line-height属性使段落行距增加 25%,将word-spacing属性设置为 30 像素,并将letter-spacing设置为 3 像素:

p {
  line-height   :125%;
  word-spacing  :30px;
  letter-spacing:3px;
}

你可以选择使用百分比值和word-spacingletter-spacing来减少或增加字体应用的默认空间量,使用小于或大于 100%的值,这对比例和非比例字体都适用。

对齐

在 CSS 中有四种文本对齐方式:leftrightcenterjustify。在下面的规则中,默认段落文本设置为完全对齐:

p { text-align:justify; }

转换

有四种属性可用于转换文本:nonecapitalizeuppercaselowercase。以下规则创建一个名为upper的类,当使用时将确保所有文本以大写显示:

.upper { text-transform:uppercase; }

缩进

使用text-indent属性,您可以按指定量缩进文本块的第一行。下面的规则将每个段落的第一行缩进 20 像素,尽管也可以应用不同的测量单位或百分比增加:

p { text-indent:20px; }

在图 19-9 中,以下规则已应用于文本部分:

p {          line-height   :150%;
             word-spacing  :10px;
             letter-spacing:1px;
}
.justify   { text-align    :justify;   }
.uppercase { text-transform:uppercase; }
.indent    { text-indent   :20px;      }

应用了缩进、大写和间距规则

图 19-9. 应用了缩进、大写和间距规则

CSS 颜色

您可以通过使用colorbackground-color属性(或通过向background属性提供单个参数)将颜色应用于文本和对象的前景和背景。指定的颜色可以是命名颜色之一(如redblue)、由十六进制 RGB 三元组创建的颜色(如#ff0000#0000ff)或使用rgbCSS 函数创建的颜色。

根据W3C 标准组织定义的标准 16 种颜色名称分别为aquablackbluefuchsiagraygreenlimemaroonnavyolivepurpleredsilvertealwhiteyellow。下面的规则使用其中一种名称设置具有 IDobject的对象的背景颜色:

#object { background-color:silver; }

在此规则中,所有<div>元素中文本的前景色设置为黄色(因为在计算机显示器上,十六进制级别ff红色,加上ff绿色,再加上00蓝色创建黄色):

div { color:#ffff00; }

或者,如果您不想使用十六进制,可以使用rgb函数指定颜色三元组,如下规则,将当前文档的背景颜色更改为水绿色:

body { background-color:rgb(0, 255, 255); }
注意

如果您不喜欢使用每种颜色 256 级范围,也可以在rgb函数中使用百分比,范围从0100,从最低(0)到最高(100)的主色彩量。例如:rgb(58%, 95%, 74%)。您还可以使用浮点值进行更精细的颜色控制,如:rgb(23.4%, 67.6%, 15.5%)

短颜色字符串

还有一种十六进制数字串的简写形式,每个颜色只使用每个 2 字节对中的第一个。例如,不使用颜色#fe4692,而使用#f49,省略每对中的第二个十六进制数字,相当于颜色值为#ff4499

这几乎产生相同的颜色,在不需要精确颜色时非常有用。6 位数和 3 位数字符串的区别在于前者支持 1600 万种不同的颜色,而后者仅支持 4000 种。

无论何时需要使用#883366这样的颜色,这直接等同于#836(因为较短版本的重复数字被隐含),你可以使用任意一种字符串来创建完全相同的颜色。

渐变

可选择应用渐变来替代实心背景颜色,从给定的初始颜色自动流向你选择的最终颜色。最好与简单的颜色规则结合使用,这样不支持渐变的浏览器至少会显示实心颜色。

示例 19-3 使用规则显示橙色渐变(或在不支持的浏览器上显示纯橙色),如图 19-10 的中间部分所示。

示例 19-3. 创建线性渐变
<!DOCTYPE html>
<html>
  <head>
    <title>Creating a linear gradient</title>
    <style>
      .orangegrad {
        background:orange;
        background:linear-gradient(top, #fb0, #f50);
    </style>
  </head>
  <body>
    <div class='orangegrad'>Black text<br>
    on an orange<br>linear gradient</div>
  </body>
</html>

A solid background color, a linear gradient, and a radial gradient

图 19-10. 一个实心背景颜色、线性渐变和径向渐变

要创建渐变,选择从topbottomleftrightcenter(或任意组合,如top leftcenter right)开始的位置,输入所需的起始和结束颜色,然后应用linear-gradientradial-gradient规则,确保为所有目标浏览器提供规则。

你还可以通过提供被称为停止颜色的中间参数来使用不仅仅是起始和结束颜色。例如,如果提供了五个参数,则每个参数将控制区域的五分之一颜色变化,由其在参数列表中的位置确定。

除了渐变,你还可以将透明度应用到 CSS 对象中,详细说明在第 20 章。

定位元素

网页内的元素按其在文档中的放置位置排列,但你可以通过将元素的position属性从默认的static更改为absoluterelativestickyfixed之一来移动它们。

绝对定位

绝对定位元素从文档中移除后,其它可用的元素将流入其释放出的空间。然后,你可以使用toprightbottomleft属性在文档中任意位置放置对象。

例如,要将 ID 为object的对象移动到文档开始位置下方 100 像素并距左边 200 像素的绝对位置,你可以向其应用以下规则(还可以使用 CSS 支持的任何其他测量单位):

#object {
  position:absolute;
  top     :100px;
  left    :200px;
}

该对象将位于其重叠的其他元素的顶部或后面,具体取决于分配给 z-index 属性的值(仅适用于定位元素)。元素的默认 z-index 值为 auto,浏览器会自动为您解决。或者,您可以给属性一个整数值(可能是负数),如下所示:

#object {
  position  :absolute;
  top       :100px;
  left      :200px;
  z-index   :100;
}

然后,对象按照从最低到最高 z-index 级别的顺序显示,具有较高值的显示在较低值之上。html 元素的默认 z-index 值为 0;所有其他默认值为 auto

相对定位

同样,您可以将对象相对于其在正常文档流中将占据的位置移动。因此,例如,要将 object 向下移动 10 像素并向右移动 10 像素以超出其正常位置,您将使用以下规则:

#object {
  position:relative;
  top     :10px;
  left    :10px;
}

固定定位

最终的 position 属性设置允许您将对象移动到绝对位置,但仅限于当前浏览器视口。然后,当文档滚动时,对象仍然保持在其放置的确切位置,主文档在其下滚动 - 这是创建码头栏和其他类似设备的绝佳方式。要将对象固定到浏览器窗口的左上角,请使用以下规则:

#object {
  position:fixed;
  top     :0px;
  left    :0px;
}

例子 19-4 展示了在页面上应用不同定位值到对象的方法。

例子 19-4. 应用不同的定位值
<!DOCTYPE html>
<html>
  <head>
    <title>Positioning</title>
    <style>
      #container {
        position  :absolute;
        top       :50px;
        left      :0px;
      }
      #object1 {
        position  :absolute;
        background:pink;
        width     :100px;
        height    :100px;
        top       :0px;
        left      :0px;
      }
      #object2 {
        position  :relative;
        background:lightgreen;
        width     :100px;
        height    :100px;
        top       :0px;
        left      :110px;
      }
      #object3 {
        position  :fixed;
        background:yellow;
        width     :100px;
        height    :100px;
        top       :50px;
        left      :220px;
      }
    </style>
  </head>
  <body>
    <br><br><br><br><br>
    <div id='container'>
      <div id='object1'>Absolute Positioning</div>
      <div id='object2'>Relative Positioning</div>
      <div id='object3'>Fixed Positioning</div>
    </div>
  </body>
</html>

在 图 19-11 中,例子 19-4 已加载到浏览器中,并且浏览器窗口已减小到宽度和高度,因此您必须向下滚动才能查看整个网页。

使用不同的定位值

图 19-11. 使用不同的定位值

当这样做时,可以立即看出具有固定定位的元素(object3)即使通过滚动也保持在原位。您还可以看到容器元素(名为 container)具有绝对定位,并且正好位于向下 50 像素,水平偏移为 0 像素,以便 object1(在 container 内具有绝对定位)出现在该位置。与此同时,object2 具有相对定位,因此与 container 的左边距相差 110 像素,与 object1 对齐。

在该图中,object3,即使出现在 HTML 的 container 元素中,也具有固定定位,因此实际上与其他对象完全独立,不受 container 边界的限制。它最初设置为与 object1object2 对齐,但与其他对象一起滚动到页面上方时保持不变,现在看起来偏离了它们下方的偏移位置。

伪类

一些选择器和类仅在样式表中使用,并且在 HTML 中没有任何匹配的标签或属性。它们的任务是使用除了名称、属性或内容之外的特征对元素进行分类,即无法从文档树中推断出的特征。这些包括伪类,如linkvisited。还有伪元素用于进行选择,这些选择可能包括部分元素,例如first-linefirst-letter

伪类和伪元素由:(冒号)字符分隔。例如,要创建一个名为bigfirst的类以强调元素的第一个字母,您可以使用如下规则:

.bigfirst:first-letter {
  font-size:400%;
  float    :left;
}

bigfirst类应用于元素时,第一个字母将显示为大号,其余文本以正常大小显示,并整齐地围绕它流动(由于float属性),就像第一个字母是图像或其他对象一样。伪类包括hoverlinkactivevisited,它们大多用于应用于锚元素,如以下规则,将所有链接的默认颜色设置为蓝色,已访问的链接颜色设置为浅蓝色:

a:link    { color:blue;      }
a:visited { color:lightblue; }

以下规则非常有趣,因为它们使用了hover伪类,因此只有当鼠标指针悬停在元素上时才应用。在这个例子中,它们将链接更改为白色文本和红色背景,提供了一种通常只能通过使用 JavaScript 代码实现的动态效果:

a:hover {
  color     :white;
  background:red;
}

在这里,我使用了background属性和单个参数,而不是较长的background-color属性。

active伪类也是动态的,它在鼠标按钮按下和释放之间的时间内对链接进行更改,例如下面的规则,将链接颜色更改为深蓝色:

a:active { color:darkblue; }

另一个有趣的动态伪类是focus,它只有在用户通过键盘或鼠标选择元素时才应用。以下规则使用通用选择器,始终在当前聚焦对象周围放置一条中灰色的虚线 2 像素边框:

*:focus { border:2px dotted #888888; }
注意

这个讨论适用于传统的网页开发,不适用于移动/触摸设备的开发。我们将在第二十三章中更专注于这个话题,讨论 jQuery Mobile。

示例 19-5 显示了两个链接和一个输入字段,如图 19-12 所示。第一个链接因在此浏览器中已访问过而显示为灰色,但第二个链接尚未访问,并显示为蓝色。已按下 Tab 键,并且输入的焦点现在是输入字段,因此其背景已更改为黄色。单击任一链接时,它将显示为紫色,并在悬停时显示为红色。

示例 19-5. 链接和焦点伪类
<!DOCTYPE html>
<html>
  <head>
    <title>Pseudoclasses</title>
    <style>
      a:link    { color:blue; }
      a:visited { color:gray; }
      a:hover   { color:red; }
      a:active  { color:purple; }
      *:focus   { background:yellow; }
    </style>
  </head>
  <body>
    <a href='http://google.com'>Link to Google'</a><br>
    <a href='nowhere'>Link to nowhere'</a><br>
    <input type='text'>
  </body>
</html>

应用于一组元素的伪类

图 19-12. 应用于一组元素的伪类

还有其他伪类可用;有关更多信息,请参阅HTML Dog“伪类”教程

速记规则

为节省空间,相关 CSS 属性组可以合并为单个速记分配。例如,我已经多次使用了创建边框的速记,例如前一节中的focus规则中使用的速记:

*:focus { border:2px dotted #ff8800; }

这实际上是以下规则集的速记连接:

*:focus {
  border-width:2px;
  border-style:dotted;
  border-color:#ff8800;
}

使用速记规则时,只需应用到您希望更改值的点即可。因此,您可以使用以下内容仅设置边框的宽度和样式,选择不设置其颜色:

*:focus { border:2px dotted; }
注意

属性在速记规则中的放置顺序可能很重要,误放可能会导致意外结果。由于本章节无法详细说明所有属性,如果您希望使用速记 CSS,请查阅 CSS 手册或搜索引擎获取默认属性及其应用顺序的信息。

框模型和布局

影响页面布局的 CSS 属性围绕框模型展开,这是围绕元素的一组嵌套属性。几乎所有元素都具有(或可以具有)这些属性,包括文档主体,您可以(例如)通过以下规则删除其边距:

body { margin:0px; }

对象的框模型从外部开始,从对象的边距开始。边框位于其内部,边框和内部内容之间有填充,最后是对象的内容。

一旦掌握了框模型,您将能够专业地布局页面,因为这些属性本身将构成页面样式的大部分。

设置边距

边距是框模型的最外层。它将元素彼此分开,使用起来非常聪明。例如,假设您给多个元素设置了默认边距为每个元素周围的 10 像素。这是您希望在下面放置两个元素之间出现的空间量,但如果它们每个都有 10 像素的边距,那么结果不是 20 像素的间隙吗?

实际上,CSS 克服了这个潜在问题:当具有定义边距的两个元素直接相邻时,仅使用两个边距中较大的一个来分隔它们。如果两个边距的宽度相同,则只使用其中一个宽度。这样,您更有可能得到想要的结果。但是请注意,绝对定位或内联元素的边距不会以这种方式折叠。

元素的外边距可以通过margin属性一次性更改,或者通过margin-leftmargin-topmargin-rightmargin-bottom单独设置。设置margin属性时,可以提供一个、两个、三个或四个参数,其效果如下规则所述:

/* Set all margins to 1 pixel */
margin:1px;

/* Set top and bottom to 1 pixel, and left and right to 2 */
margin:1px 2px;

/* Set top to 1 pixel, left and right to 2, and bottom to 3 */
margin:1px 2px 3px;

/* Set top to 1 pixel, right to 2, bottom to 3, and left to 4 */
margin:1px 2px 3px 4px;

在示例 19-6 中,一个应用于放置在table元素内的正方形元素的margin属性规则(加粗显示)被应用。图 19-13 展示了这个示例加载到浏览器中的情况。表格没有给定尺寸,所以它将尽可能紧密地围绕内部<div>元素包裹。因此,它上方有 10 像素的外边距,右侧有 20 像素的外边距,下方有 30 像素的外边距,左侧有 40 像素的外边距。

示例 19-6. 外边距如何应用
<!DOCTYPE html>
<html>
  <head>
    <title>CSS Margins</title>
    <style>
      #object1 {
        background  :lightgreen;
        border-style:solid;
        border-width:1px;
        font-family :"Courier New";
        font-size   :9px;
        width       :100px;
        height      :100px;
        padding     :5px;
        `margin`      `:``10px` `20px` `30px` `40px``;`
      }
      table {
        padding     :0;
        border      :1px solid black;
        background  :cyan;
      }
    </style>
  </head>
  <body>
    <table>
      <tr>
        <td>
          <div id='object1'>margin:<br>10px 20px 30px 40px;</div>
        </td>
      </tr>
    </table>
  </body>
</html>

外部表格根据边距宽度扩展

图 19-13. 外部表格根据边距宽度扩展

应用边框

盒子模型的边框级别类似于外边距,不同之处在于没有折叠效果。随着我们进入盒子模型,它是下一个级别。用于修改边框的主要属性包括borderborder-leftborder-topborder-rightborder-bottom,每个属性还可以添加其他后缀子属性,如-color-style-width

用于margin属性的四种访问单个属性设置的方法也适用于border-width属性,因此以下所有规则均有效:

/* All borders */
border-width:1px;

/* Top/bottom and left/right */
border-width:1px 5px;

/* Top, left/right, and bottom */
border-width:1px 5px 10px;

/* Top, right, bottom, and left */
border-width:1px 5px 10px 15px;

图 19-14 展示了依次应用这些规则到一组正方形元素的情况。在第一个元素中,可以清楚地看到所有边框都有 1 像素的宽度。然而,第二个元素的顶部和底部边框宽度为 1 像素,而其侧边边框各为 5 像素。第三个元素的顶部边框宽度为 1 像素,其侧边为 5 像素宽,底部为 10 像素宽。第四个元素的顶部边框宽度为 1 像素,右侧边框宽度为 5 像素,底部边框宽度为 10 像素,左侧边框宽度为 15 像素。

应用长格式和简写边框规则值

图 19-14. 应用长格式和简写边框规则值

在前述元素下的最后一个元素不使用简写规则,而是分别设置每个边框宽度。正如你所见,要达到相同的效果需要输入更多内容。

调整填充

盒子模型的最深层(除了元素内容之外)是内边距,它应用在任何边框和/或外边距的内部。用于修改内边距的主要属性包括paddingpadding-leftpadding-toppadding-rightpadding-bottom

用于marginborder属性的四种访问单个属性设置的方法也适用于padding属性,因此以下所有规则均有效:

/* All padding */
padding:1px;

/* Top/bottom and left/right */
padding:1px 2px;

/* Top, left/right, and bottom */
padding:1px 2px 3px;

/* Top, right, bottom, and left */
padding:1px 2px 3px 4px;

图 19-15 显示了对某个表格单元格内的一些文本应用了填充规则(在 示例 19-7 中以粗体显示),该单元格由规则 display:table-cell; 定义,使包围的 <div> 元素显示为表格单元格,未给定尺寸,因此它将尽可能紧密地环绕文本。因此,内部元素上方有 10 像素的填充,右侧有 20 像素,下方有 30 像素,左侧有 40 像素。

示例 19-7. 应用填充
<!DOCTYPE html>
<html>
  <head>
    <title>CSS Padding</title>
    <style>
      #object1 {
        border-style:solid;
        border-width:1px;
        background  :orange;
        color       :darkred;
        font-family :Arial;
        font-size   :12px;
        text-align  :justify;
        display     :table-cell;
        width       :148px;
        `padding`     `:``10px` `20px` `30px` `40px``;` `}`
    </style>
  </head>
  <body>
    <div id='object1'>To be, or not to be that is the question:
    Whether 'tis Nobler in the mind to suffer
    The Slings and Arrows of outrageous Fortune,
    Or to take Arms against a Sea of troubles,
    And by opposing end them.</div>
  </body>
</html>

对对象应用不同的填充值

图 19-15. 对对象应用不同的填充值

对象内容

最后,在盒模型的深层级中心,存在一个可以在本章讨论的所有方式中进行样式设置的元素。如您所知,这个元素可以(通常会)包含进一步的子元素,反过来可能包含子-子元素,依此类推,每个都有自己的样式和盒模型设置。

问题

  1. 用于将一个样式表导入另一个样式表(或某些 HTML 的 <style> 部分)的指令是哪个?

  2. 您可以使用什么 HTML 标签来将样式表导入文档中?

  3. 哪个 HTML 标签属性用于直接将样式嵌入元素?

  4. CSS ID 和 CSS 类之间有什么区别?

  5. CSS 规则中用于前缀 (a) ID 和 (b) 类名的字符是哪些?

  6. 在 CSS 规则中,分号的作用是什么?

  7. 如何向样式表添加注释?

  8. CSS 中用于表示任何元素的字符是哪个?

  9. 如何在 CSS 中选择一组不同的元素和/或元素类型?

  10. 给定具有相等优先级的一对 CSS 规则,如何使其中一个比另一个具有更高的优先级?

参见 “第十九章答案”,以获取这些问题的答案。

第二十章:使用 CSS3 实现高级 CSS

CSS 的第一个实现是在 1996 年起草,并于 1999 年发布;自 2001 年以来,所有浏览器版本都支持它。这个版本的标准(CSS1)在 2008 年进行了修订。1998 年,开发人员开始起草第二个规范(CSS2);其标准在 2007 年完成,并在 2009 年进行了修订。

CSS3 规范的开发始于 2001 年,一些功能于 2009 年提出,最新的推荐截至 2020 年仍在进行中。

CSS4 已由 CSS 工作组提出,尽管这并非一个重大进步。相反,它只是 CSS 的一部分——选择器的发展,其内容超出了本书的范围,因为到我写这篇文章时,2021 年仍在进行推荐。如果你感兴趣,可以访问 drafts.csswg.org 上的资源

幸运的是,CSS 工作组定期发布它认为稳定的 CSS 模块的快照。迄今为止,已发布了四份最佳实践文件,最近的一份是2020 年。这是了解 CSS 当前状况的最佳途径。

在本章中,我将带你了解主要浏览器已采纳的最重要的 CSS3 特性,其中许多提供了此前只能通过 JavaScript 实现的功能。

我建议尽可能使用 CSS3 实现动态特性,而不是 JavaScript。CSS 提供的特性使文档属性成为文档本身的一部分,而不是通过 JavaScript 添加的附加部分。这样设计更加清晰。

注意

必须指出的是,CSS 包含非常多的内容,各浏览器对各种功能的实现方式也有所不同(甚至可能完全不同)。因此,我建议在您希望确保所创建的 CSS 在所有浏览器中正常工作时,首先查看Can I use... 网站。该网站记录了各种功能在各浏览器中的支持情况,因此它始终比这本书更加及时更新,而 CSS 在这段时间内也可能有很大变化。

属性选择器

在前一章中,我详细介绍了各种 CSS 属性选择器,现在我将快速回顾一下。选择器在 CSS 中用于匹配 HTML 元素,共有 10 种不同类型,如表 20-1 所示。

表 20-1. CSS 选择器、伪类和伪元素

选择器类型示例
通用选择器* { color:#555; }
类型选择器.classname { color:blue; }
类选择器.classname { color:blue; }
ID 选择器#id { background:cyan; }
后代选择器span em { color:green; }
子选择器div > em { background:lime; }
相邻兄弟选择器i + b { color:gray; }
属性选择器a[href='info.htm'] { color:red; }
伪类a:hover { font-weight:bold; }
伪元素P::first-letter { font-size:300%; }

CSS3 设计师们决定这些选择器中的大多数工作方式良好,但进行了三项增强,使您可以更轻松地基于属性内容匹配元素。以下各节详细讨论这些增强功能。

匹配字符串的部分

在 CSS2 中,您可以使用诸如 a[href='info.htm'] 的选择器来匹配 href 属性中出现的字符串 info.htm,但无法仅匹配字符串的 部分。CSS3 提供了三个新运算符:^$*。如果其中一个直接位于 = 符号之前,则可以分别匹配字符串的开头、结尾或任何部分。

运算符 ^=

此运算符匹配字符串的开头。例如,以下内容将匹配任何href属性其值以字符串http://website开头的情况:

a[href^='http://website']

因此,以下元素将匹配:

<a href='http://website.com'>

但这并不会:

<a href='http://mywebsite.com'>

运算符 $=

要仅匹配字符串的结尾,可以使用类似以下选择器,将匹配任何img标签其src属性以.png结尾的情况:

img[src$='.png']

例如,以下内容将匹配:

<img src='photo.png'>

但这并不会:

<img src='snapshot.jpg'>

运算符 *=

要匹配属性中任何位置的任何子字符串,可以使用类似以下选择器,它找到页面上任何链接并在其中任何位置包含字符串google的情况:

a[href*='google']

例如,HTML 片段 <a href='http://google.com'> 将会匹配,而片段 <a href='http://gmail.com'> 则不会。

属性 box-sizing

W3C 盒模型指定对象的宽度和高度应仅引用元素内容的尺寸,而忽略任何填充或边框。但一些网页设计师希望指定引用整个元素(包括任何填充和边框)的尺寸。

为了提供此功能,CSS3 允许您使用 box-sizing 属性选择希望使用的盒模型。例如,要使用包括填充和边框在内的对象总宽度和高度,请使用此声明:

box-sizing:border-box;

或者,要使对象的宽度和高度仅引用其内容,请使用此声明(默认情况):

box-sizing:content-box;

CSS3 背景

CSS3 提供了两个新属性:background-clipbackground-origin。它们之间,您可以指定背景应从元素内的何处开始,并如何剪切背景,以使其不显示在不需要的盒模型部分。

要实现这一点,这两个属性都支持以下值:

<dfn class="keep-together">border-box</dfn>

指的是边框的外边缘

<dfn class="keep-together">padding-box</dfn>

指的是填充区域的外边缘

<dfn class="keep-together">content-box</dfn>

指的是内容区域的外边缘

属性 background-clip

background-clip属性指定了如果背景出现在元素的边框或填充区域内,则应该被忽略(剪切)。例如,以下声明指定背景可以显示在元素的所有部分,直到边框的外缘:

background-clip:border-box;

要防止背景出现在元素的边框区域内,可以将其限制为仅出现在其填充区域外缘内的元素部分,如下所示:

background-clip:padding-box;

或者要限制背景仅显示在元素的内容区域内,请使用以下声明:

background-clip:content-box;

图 20-1 显示了在 Safari 网页浏览器中显示的三行元素,第一行使用了background-clip属性的border-box值,第二行使用了padding-box,第三行使用了content-box

CSS3 背景属性的不同组合方式

图 20-1. CSS3 背景属性的不同组合方式

在第一行,内部框(已加载到元素左上角的图像文件,不重复显示)可以在元素的任何位置显示。您还可以清楚地看到它显示在第一个框的边框区域,因为边框已设置为点状。

在第二行,背景图像和背景阴影均不显示在边框区域,因为它们已被剪切到了具有background-clip属性值为padding-box的填充区域内。

然后,在第三行,背景阴影和图像均已被剪切,仅在每个元素的内部内容区域内显示(显示在浅色虚线框内),使用了background-clip属性值为content-box

background-origin 属性

使用background-origin属性,您可以通过指定图像的左上角应从哪里开始来控制背景图像的位置。例如,以下声明指定背景图像的原点应位于边框外缘的左上角:

background-origin:border-box;

要将图像的原点设置为填充区域的左上外角,请使用以下声明:

background-origin:padding-box;

要将图像的原点设置为元素内部内容区域的左上角,请使用以下声明:

background-origin:content-box;

再次查看图 20-1,您可以看到在每一行中,第一个框使用了background-origin属性的border-box值,第二个框使用了padding-box,第三个框使用了content-box。因此,在每一行中,较小的内部框显示在第一个框的边框的左上角,第二个框的填充的左上角,以及第三个框的内容的左上角。

注意

请注意,关于内部框的起源,行之间唯一的差异在于,在第 2 行和第 3 行中,内部框被裁剪到填充和内容区域,因此在这些区域之外,框的任何部分都不会显示。

属性 background-size

就像在 <img> 标签中使用图像时可以指定宽度和高度一样,您现在也可以在所有浏览器的最新版本中为背景图像指定宽度和/或高度。

您可以如下应用此属性(其中 ww 是宽度,hh 是高度):

background-size:*`ww`*px *`hh`*px;

如果您愿意,您可以只使用一个参数,然后两个维度都将设置为该值。此外,如果将此属性应用于块级元素(如 <div>)(而不是内联元素,如 <span>),则可以将宽度和/或高度指定为百分比,而不是固定值。

使用 auto

如果您希望仅缩放背景图像的一个维度,并使另一个维度自动缩放以保持相同的比例,您可以像这样使用值 auto

background-size:100px auto;

这将宽度设置为 100 像素,并将高度设置为与宽度增加或减少的比例值。

注意

不同的浏览器可能需要不同版本的各种背景属性名称,请在使用它们时参考Can I use... website,以确保您应用于目标浏览器所需的所有版本。

多重背景

使用 CSS3 您可以将多个背景附加到一个元素,每个背景都可以使用先前讨论的 CSS3 背景属性。图 20-2 显示了一个示例;八个不同的图像被分配到背景中,以创建证书边框的四个角和四条边。

要在单个 CSS 声明中显示多个背景图像,请用逗号分隔它们。示例 20-1 展示了用于创建 图 20-2 背景的 HTML 和 CSS。

示例 20-1. 在背景中使用多个图像
<!DOCTYPE html>
<html> <!-- backgroundimages.html -->
  <head>
    <title>CSS3 Multiple Backgrounds Example</title>
    <style>
      .border {
        font-family:'Times New Roman';
        font-style :italic;
        font-size  :170%;
        text-align :center;
        padding    :60px;
        width      :350px;
        height     :500px;
        background :url('b1.gif') top    left  no-repeat,
                    url('b2.gif') top    right no-repeat,
                    url('b3.gif') bottom left  no-repeat,
                    url('b4.gif') bottom right no-repeat,
                    url('ba.gif') top          repeat-x,
                    url('bb.gif') left         repeat-y,
                    url('bc.gif') right        repeat-y,
                    url('bd.gif') bottom       repeat-x
      }
    </style>
  </head>
  <body>
    <div class='border'>
      <h1>Employee of the month</h1>
      <h2>Awarded To:</h2>
      <h3>__________________</h3>
      <h2>Date:</h2>
      <h3>___/___/_____</h3>
    </div>
  </body>
</html>

图 20-2. 使用多个图像创建的背景

查看 CSS 部分,您会看到 background 声明的前四行将角落图像放置在元素的四个角上,最后四行则放置边缘图像,因为背景图像的优先顺序从顶部到底部。换句话说,在它们重叠的地方,额外的背景图像将出现在已放置图像的后面。如果 GIF 图像的顺序相反,重复的边缘图像将显示在角落的顶部,这将是不正确的。

注意

使用此 CSS,您可以将包含元素调整为任何尺寸,边框将始终正确调整大小以适应,这比使用表格或多个元素实现相同效果要简单得多。

CSS3 边框

CSS3 还为边框的呈现方式带来了更大的灵活性,允许您独立更改所有四个边框边缘的颜色,显示边缘和角落的图像,为应用圆角边框提供半径值,并将盒子阴影放置在元素下方。

border-color 属性

有两种方法可以将颜色应用到边框上。首先,您可以将单一颜色传递给属性,如下所示:

border-color:#888;

此属性将元素的所有边框设置为中灰色。您还可以像这样单独设置边框颜色,这会将边框颜色设置为各种灰色色调:

border-top-color   :#000;
border-left-color  :#444;
border-right-color :#888;
border-bottom-color:#ccc;

或者您可以使用单个声明来分别设置所有颜色,如下所示:

border-color:#f00 #0f0 #880 #00f;

此声明将顶部边框颜色设置为#f00,右侧设置为#0f0,底部设置为#880,左侧设置为#00f(分别为红色、绿色、橙色和蓝色)。您还可以使用颜色名称作为参数。

border-radius 属性

在 CSS3 之前,有才华的 Web 开发人员为了实现圆角边框而进行了许多微调和修复,通常使用<table><div>标签。

但是现在,在元素上添加圆角边框真的很简单,并且在所有主要浏览器的最新版本中均可正常工作,如图 20-3 所示,显示了以不同方式显示的 10 像素边框。 示例 20-2 显示了此 HTML。

示例 20-2. border-radius 属性
<!DOCTYPE html>
<html> <!-- borderradius.html -->
  <head>
    <title>CSS3 Border Radius Examples</title>
    <style>
      .box {
        margin-bottom:10px;
        font-family  :'Courier New', monospace;
        font-size    :12pt;
        text-align   :center;
        padding      :10px;
        width        :380px;
        height       :75px;
        border       :10px solid #006;
      }
      .b1 {
        border-radius        :40px;
      }
      .b2 {
        border-radius        :40px 40px 20px 20px;
      }
      .b3 {
         border-top-left-radius           :20px;
        border-top-right-radius           :40px;
        border-bottom-left-radius         :60px;
        border-bottom-right-radius        :80px;
      }
      .b4 {
        border-top-left-radius            :40px 20px;
        border-top-right-radius           :40px 20px;
        border-bottom-left-radius         :20px 40px;
        border-bottom-right-radius        :20px 40px;
      }
    </style>
  </head>
  <body>
    <div class='box b1'>
      border-radius:40px;
    </div>

    <div class='box b2'>
      border-radius:40px 40px 20px 20px;
    </div>

    <div class='box b3'>
      border-top-left-radius &nbsp;&nbsp;&nbsp;:20px;<br>
      border-top-right-radius &nbsp;&nbsp;:40px;<br>
      border-bottom-left-radius :60px;<br>
      border-bottom-right-radius:80px;
    </div>

    <div class='box b4'>
      border-top-left-radius &nbsp;&nbsp;&nbsp;:40px 20px;<br>
      border-top-right-radius &nbsp;&nbsp;:40px 20px;<br>
      border-bottom-left-radius :20px 40px;<br>
      border-bottom-right-radius:20px 40px;
    </div>
  </body>
</html>

混合和匹配各种边界半径属性

图 20-3. 混合和匹配各种边界半径属性

因此,例如,要创建半径为 20 像素的圆角边框,您只需使用以下声明:

border-radius:20px;

您可以为每个角落单独指定半径,如下所示(顺时针方向从左上角开始应用):

border-radius:10px 20px 30px 40px;

如果您愿意,也可以单独处理元素的每个角落,如下所示:

border-top-left-radius    :20px;
border-top-right-radius   :40px;
border-bottom-left-radius :60px;
border-bottom-right-radius:80px;

而且,当引用单独的角落时,您可以提供两个参数来选择不同的垂直和水平半径(产生更有趣和微妙的边框),如下所示:

border-top-left-radius    :40px 20px;
border-top-right-radius   :40px 20px;
border-bottom-left-radius :20px 40px;
border-bottom-right-radius:20px 40px;

第一个参数是水平半径,第二个是垂直半径。

盒子阴影

要应用盒子阴影,请指定从对象到水平和垂直偏移量,要添加的阴影模糊量以及要使用的颜色,如下所示:

box-shadow:15px 15px 10px #888;

15px的两个实例指定了元素从垂直和水平方向的偏移量,这些值可以是负数、零或正数。10px指定了模糊量,较小的值会导致较少的模糊效果,#888是阴影的颜色,可以是任何有效的颜色值。此声明的结果可在图 20-4 中看到。

元素下方显示的盒子阴影

图 20-4. 元素下方显示的盒子阴影

元素溢出

在 CSS2 中,可以通过将overflow属性设置为hiddenvisiblescrollauto来指示当一个元素过大以至于无法完全包含在其父元素内时该如何处理。但是在 CSS3 中,您现在还可以将这些值分别应用于水平或垂直方向,就像这些示例声明一样:

overflow-x:hidden;
overflow-x:visible;
overflow-y:auto;
overflow-y:scroll;

多列布局

网页开发者最常要求的功能之一是多列布局,在 CSS3 中这终于实现了。现在,通过指定列数,以及(可选地)选择它们之间的间距和分隔线的类型,即可轻松实现文本在多列中的流动,如图 20-5 所示(由示例 20-3 创建)。

多列中的流动文本

图 20-5. 多列中的流动文本
示例 20-3. 使用 CSS 创建多列
<!DOCTYPE html>
<html> <!-- multiplecolumns.html -->
  <head>
    <title>Multiple Columns</title>
    <style>
      .columns {
        text-align          :justify;
        font-size           :16pt;
         column-count       :3;
        column-gap          :1em;
        column-rule         :1px solid black;
      }
    </style>
  </head>
  <body>
    <div class='columns'>
      Now is the winter of our discontent
      Made glorious summer by this sun of York;
      And all the clouds that lour'd upon our house
      In the deep bosom of the ocean buried.
      Now are our brows bound with victorious wreaths;
      Our bruised arms hung up for monuments;
      Our stern alarums changed to merry meetings,
      Our dreadful marches to delightful measures.
      Grim-visaged war hath smooth'd his wrinkled front;
      And now, instead of mounting barded steeds
      To fright the souls of fearful adversaries,
      He capers nimbly in a lady's chamber
      To the lascivious pleasing of a lute.
    </div>
  </body>
</html>

.columns类中,前两行仅告诉浏览器将文本右对齐,并将其设置为16pt的字体大小。这些声明对于多列布局并不需要,但它们改善了文本显示效果。其余的行设置了元素,使得文本可以在其中通过三列流动,列与列之间有1em的间隔,并在每个间隔的中间有一个单像素的边框。

颜色和不透明度

CSS3 极大地扩展了定义颜色的方式,现在您还可以使用 CSS 函数以常见格式 RGB(红、绿、蓝)、RGBA(红、绿、蓝和 alpha)、HSL(色调、饱和度和亮度)和 HSLA(色调、饱和度、亮度和 alpha)应用颜色。alpha 值指定了颜色的透明度,使底层元素可以显示出来。

HSL 颜色

要使用hsl函数定义颜色,必须首先从色轮上选择一个介于0359之间的色调值。任何更高的颜色数值都会简单地回到开始,因此值0是红色,值360720也是红色。

在色轮中,红色、绿色和蓝色的主要颜色之间相隔 120 度,因此纯红色是0,绿色是120,蓝色是240。这些值之间的数字代表不同比例的主要颜色混合的不同色调。

接下来,您需要饱和度级别,这是一个介于 0 和 100%之间的值。这指定了颜色将显示多么淡或多么鲜艳。饱和度值从轮盘的中心开始,以中灰色(饱和度为 0%)开始,然后随着向外边缘进展而变得越来越鲜艳(饱和度为 100%)。

剩下的就是您决定颜色亮度的方式,通过选择介于 0 和 100%之间的亮度值。亮度值为50%给出最完整、最明亮的颜色;减少该值(最少为0%)会使颜色变暗,直到显示为黑色;增加该值(最多为100%)会使颜色变亮,直到显示为白色。您可以将此想象为将黑色或白色的级别混合到颜色中。

因此,例如,要选择具有标准百分比亮度的完全饱和的黄色,您可以使用以下声明:

color:hsl(60, 100%, 50%);

或者,对于较深的蓝色,您可以使用以下声明:

color:hsl(240, 100%, 40%);

您还可以在期望颜色的任何属性(如background-color等)上使用此(和所有其他 CSS 颜色函数)。

HSLA 颜色

为了进一步控制颜色的显示方式,您可以使用hsla函数,为颜色提供第四个(alpha)级别,这是一个介于01之间的浮点值。值0指定颜色完全透明,而1表示完全不透明。

这是您如何选择具有标准亮度和 30%不透明度的完全饱和的黄色:

color:hsla(60, 100%, 50%, 0.3);

或者,对于具有 82%不透明度的完全饱和但较浅的蓝色,您可以使用以下声明:

color:hsla(240, 100%, 60%, 0.82);

RGB 颜色

您可能更熟悉选择颜色的 RGB 系统,因为它类似于#nnnnnn#nnn颜色格式。例如,要将黄色应用于属性,您可以使用以下任一声明(第一个支持 1600 万种颜色,第二个支持 4000 种颜色):

color:#ffff00;
color:#ff0;

您还可以使用 CSS 的rgb函数来实现相同的结果,但使用十进制数字而不是十六进制(其中 255 十进制是 ff 十六进制):

color:rgb(255, 255, 0);

但比这更好的是,您甚至不必再考虑最多 256 个数量级,因为您可以指定百分比值,就像这样:

color:rgb(100%, 100%, 0);

实际上,您现在可以通过简单地考虑其主要颜色来非常接近所需的颜色。例如,绿色和蓝色制成青色,因此,要创建接近青色但含有比绿色更多蓝色的颜色,您可以在 0%红色、40%绿色和 60%蓝色进行良好的初步猜测,并尝试以下声明:

color:rgb(0%, 40%, 60%);

RGBA 颜色

hsla函数一样,rgba函数支持第四个 alpha 参数,因此,例如,您可以通过以下声明以 40%的不透明度应用先前的类青色:

color:rgba(0%, 40%, 60%, 0.4);

不透明度属性

opacity属性提供与hslargba函数相同的 Alpha 控制,但允许您单独修改对象的不透明度(或透明度,如果您更喜欢)。

要使用它,请将如下声明应用到元素上(在此示例中将不透明度设置为 25%,即 75%透明):

opacity:0.25;

文本效果

通过 CSS3 现在可以为文本应用多种新效果,包括文本阴影、文本重叠和单词换行。

text-shadow 属性

text-shadow属性类似于box-shadow属性,并接受相同的一组参数:水平和垂直偏移量、模糊量以及要使用的颜色。例如,以下声明使阴影在水平和垂直方向上各偏移 3 像素,并以深灰色显示阴影,模糊量为 4 像素:

text-shadow:3px 3px 4px #444;

此声明的结果看起来像图 20-6,并在所有主要浏览器的最新版本中均有效(但不适用于 IE 9 或更低版本)。

为文本应用阴影

图 20-6. 为文本应用阴影

text-overflow 属性

使用任何 CSS 溢出属性的hidden值时,您还可以使用text-overflow属性,在截断之前放置一个省略号(三个点),以指示某些文本已被截断,如下所示:

text-overflow:ellipsis;

如果没有此属性,则截断文本“To be, or not to be. That is the question.”的结果将如图 20-7 所示;但是,应用了该声明后,结果就像图 20-8 一样。

文本被自动截断

图 20-7. 文本被自动截断

文字未被切断,而是使用省略号逐渐消失

图 20-8. 文字未被切断,而是使用省略号逐渐消失

为使其起作用,需要三件事:

  • 元素应具有不可见的overflow属性,例如overflow:hidden

  • 元素必须设置white-space:nowrap属性以约束文本。

  • 元素的宽度必须小于文本的宽度以进行截断。

word-wrap 属性

当您有一个非常长的单词宽度大于包含它的元素时,它将溢出或被截断。但作为使用text-overflow属性和截断文本的替代方案,您可以使用word-wrap属性并将值设置为break-word来换行长行,如下所示:

word-wrap:break-word;

例如,在图 20-9 中,单词Honorificabilitudinitatibus过于宽度超出了包含框(其右边缘在字母ta之间显示为实线垂直线),因为未应用溢出属性,它已超出了其边界。

单词过于宽度超出其容器并溢出

图 20-9. 字对容器来说太宽,溢出了

但在 图 20-10 中,该元素的 word-wrap 属性被赋予了 break-word 的值,因此这个词已经整齐地换行到了下一行。

现在的字在右边缘换行

图 20-10. 现在的字换行在右边缘

Web 字体

CSS3 Web 字体的使用大大增加了网页设计师可用的排版选择,允许从网络上加载并显示字体,而不仅限于用户的计算机。为了实现这一点,可以通过使用@font-face来声明 web 字体,像这样:

@font-face
{
  font-family:FontName;
  src:url('FontName.otf');
}

url 函数需要一个包含字体路径或 URL 的值。在大多数浏览器上,你可以使用 TrueType (.ttf) 或 OpenType (.otf) 字体,但是 Internet Explorer 限制你只能使用转换为嵌入式 OpenType (.eot) 的 TrueType 字体。

要告诉浏览器字体的类型,可以使用format函数,例如对于 OpenType 字体:

@font-face
{
  font-family:FontName;
  src:url('FontName.otf') format('opentype');
}

或者对于 TrueType 字体:

@font-face
{
  font-family:FontName;
  src:url('FontName.ttf') format('truetype');
}

然而,因为 Internet Explorer 只接受 EOT 字体,它会忽略包含format函数的@font-face声明。

Google Web 字体

使用 Web 字体的一个非常棒的方式之一是从 Google 的服务器免费加载它们。要了解更多信息,请访问 Google 字体网站,见图 20-11,在那里你可以获取超过一千种字体。

图 20-11. Google 的一些 Web 字体

为了演示使用其中一种字体的简易性,这里展示如何在 HTML 中加载 Google 字体(在此例中为 Lobster),以用于 <h1> 标题:

<!DOCTYPE html>
<html>
  <head>
    <style>
      h1 { font-family:'Lobster', arial, serif; }
    </style>
    <link href='http://fonts.googleapis.com/css?family=Lobster'
      rel='stylesheet'>
  </head>
  <body>
    <h1>Hello</h1>
  </body>
</html>

当你从该网站选择字体时,Google 提供了 <link> 标签,可以复制并粘贴到你网页的 <head> 中。

变换

使用变换,你可以在任意三个维度中进行倾斜、旋转、拉伸和挤压元素。这使得通过摆脱<div>等元素的统一矩形布局,很容易创建出色的效果,因为现在它们可以以多种角度和形式展示。

要执行变换,使用 transform 属性。你可以对 transform 属性应用各种属性,从值 none 开始,它将对象重置为非变换状态:

transform:none;

你可以将以下一个或多个函数提供给 transform 属性:

matrix

通过应用值矩阵对其应用矩阵来变换对象

translate

移动元素的原点

scale

缩放对象

rotate

旋转对象

skew

倾斜对象

唯一可能让您费解的是 skew。使用此功能时,一个坐标相对于坐标平面或轴的距离在一个方向上被位移。因此,例如,当被倾斜时,矩形被转换为平行四边形。

这些函数也有单一版本,如 translateXscaleY 等。

例如,要将元素顺时针旋转 45 度,可以应用以下声明:

transform:rotate(45deg);

同时,您可以放大此对象,例如以下声明,将其宽度放大 1.5 倍,高度放大 2 倍,然后执行旋转。图 20-12 显示了应用变换前后的对象:

transform:scale(1.5, 2) rotate(45deg);

一个在变换前后的对象

图 20-12. 变换前后的对象

3D 变换

您还可以通过使用以下 CSS3 3D 变换功能来在三维空间中变换对象:

perspective

释放元素,使其脱离二维空间,并创建一个可以移动的第三维度。必须与 3D CSS 函数一起使用。

transform-origin

利用透视,设置所有线条汇聚到一个单一点的位置。

translate3d

将元素移动到其三维空间中的另一个位置。

scale3d

重新调整一个或多个维度。

rotate3d

将元素绕 x、y 和 z 轴之一旋转。

图 20-13 显示了如何使用类似以下的 CSS3 3D 变换规则将二维对象旋转至三维空间。

transform:perspective(200px) rotateX(10deg) rotateY(20deg) rotateZ(30deg);

一个在三维空间中旋转的图形

图 20-13. 在三维空间中旋转的图形

过渡

也出现在所有主要浏览器的最新版本中(包括 Internet Explorer 10,但不包括更低版本)的一个动态新功能称为 过渡。这些指定了在元素变换时要发生的动画效果,浏览器将自动处理所有中间帧。

要设置转换,需要提供四个属性,如下所示:

transition-property       :*`property`*;
transition-duration       :*`time`*;
transition-delay          :*`time`*;
transition-timing-function:*`type`*;

要过渡的属性

过渡具有诸如 heightborder-color 的属性。在名为 transition-property 的 CSS 属性中指定要更改的属性。(这里我使用 property 一词,用于描述 CSS 属性及其设置的过渡属性。)您可以通过逗号分隔它们来包含多个属性,如下所示:

transition-property:width, height, opacity;

或者,如果您希望对元素的所有内容(包括颜色)进行过渡,可以使用值 all,如下所示:

transition-property:all;

过渡持续时间

transition-duration属性需要一个大于等于 0 秒的值,如以下所示,指定过渡应该花费 1.25 秒完成:

transition-duration:1.25s;

过渡延迟

如果给transition-delay属性赋予大于 0 秒的值(默认值),它将在元素初始显示和过渡开始之间引入延迟。以下代码在 0.1 秒延迟后开始过渡:

transition-delay:0.1s;

如果transition-delay属性的值小于 0 秒(也就是负值),过渡将在属性变更时执行,但看起来似乎是从指定的偏移开始执行,过渡中途进行。

过渡时间

transition-timing函数属性需要以下一个值:

ease

缓慢开始,变快,然后缓慢结束。

linear

常速过渡。

ease-in

缓慢开始,然后快速进行直至完成。

ease-out

快速开始,保持快速进行直至接近结束,然后缓慢结束。

ease-in-out

缓慢开始,快速进行,然后缓慢结束。

使用任何包含“ease”一词的值,确保过渡看起来非常流畅和自然,不像某种线性过渡似乎更加机械。如果这些对你来说还不够丰富,你也可以使用cubic-bezier函数自定义自己的过渡效果。

例如,以下是用于创建前述五种过渡类型的声明,演示如何轻松创建自定义过渡:

transition-timing-function:cubic-bezier(0.25, 0.1, 0.25, 1);
transition-timing-function:cubic-bezier(0,    0,   1,    1);
transition-timing-function:cubic-bezier(0.42, 0,   1,    1);
transition-timing-function:cubic-bezier(0,    0,   0.58, 1);
transition-timing-function:cubic-bezier(0.42, 0,   0.58, 1);

简写语法

你可能会发现使用此属性的简写版本更容易,并在单个声明中包含所有值,如以下示例所示,它将以线性方式过渡所有属性,在 0.3 秒内完成,初始(可选)延迟为 0.2 秒:

transition:all .3s linear .2s;

这样做将为您节省输入许多非常相似声明的麻烦,特别是如果您支持所有主要浏览器前缀。

示例 20-4 展示了如何同时使用过渡和变换。CSS 创建了一个方形的橙色元素,里面有一些文本,并且使用hover伪类指定,当鼠标经过该对象时,它应该旋转 180 度,并从橙色变为黄色(见图 20-14)。

示例 20-4. 悬停效果的过渡
<!DOCTYPE html>
<html>
  <head>
    <title>Transitioning on hover</title>
    <style>
      #square {
        position          :absolute;
        top               :50px;
        left              :50px;
        width             :100px;
        height            :100px;
        padding           :2px;
        text-align        :center;
        border-width      :1px;
        border-style      :solid;
        background        :orange;
        transition        :all .8s ease-in-out;
      }
      #square:hover {
        background        :yellow;
        transform         :rotate(180deg);
      }
    </style>
  </head>
  <body>
    <div id='square'>
      Square shape<br>
      created using<br>
      a simple div<br>
      element with<br>
      a 1px border
    </div>
  </body>
</html>

当鼠标悬停时,对象旋转并改变颜色

图 20-14. 当鼠标悬停时,对象旋转并改变颜色

示例代码通过提供浏览器特定版本的声明来适配所有浏览器。在所有最新的浏览器(包括 IE 10 或更高版本)中,当鼠标悬停时,对象将顺时针旋转,同时从橙色渐变到黄色。

CSS 过渡很智能,当它们被取消时,它们会平滑地返回到它们的原始值。因此,如果你在过渡完成之前将鼠标移开,它将立即反转并过渡回其初始状态。

问题

  1. CSS3 属性选择器操作符 ^=, $=, 和 *= 分别做什么?

  2. 你使用什么属性来指定背景图像的大小?

  3. 你可以用哪个属性指定边框的半径?

  4. 如何在多列上流动文本?

  5. 列出四个用于指定 CSS 颜色的函数。

  6. 如何创建一个灰色阴影,位于某些文本下方右下角偏移 5 像素,模糊程度为 3 像素?

  7. 如何用省略号表示文本被截断?

  8. 如何在网页中引入 Google Web 字体?

  9. 你会使用什么 CSS 声明来将对象旋转 90 度?

  10. 如何设置对象的过渡效果,以便当其任何属性发生变化时,变化将在半秒钟内以线性方式立即过渡?

参见“第二十章答案” 在附录 A 中查看这些问题的答案。