首页 前端知识 CSS3 动画高级教程(一)

CSS3 动画高级教程(一)

2024-09-01 00:09:51 前端知识 前端哥 656 230 我要收藏

原文:Pro CSS3 Animation

协议:CC BY-NC-SA 4.0

零、简介

欢迎来到专业 CSS3 动画。这本书教你如何使用 CSS 的全部力量,通过交互性和新鲜的视觉方法使你的网页内容生动起来。在接下来的章节中,您将学习如何使用最先进的行业标准来增加网站的视觉吸引力、可访问性和受欢迎程度。

这本书是给谁的

这本书是为至少有几年 web 开发经验的设计人员和编码人员设计的,他们希望快速提升自己的技能以适应新的 W3C 标准,或者希望以大胆的新方向探索 CSS 转换、过渡和动画。这不是一个介绍性的网页设计文本:这本书假设至少对 HTML、CSS 和 JavaScript 有基本的理解。由于 web 开发是一个多学科的过程,我还将讨论诸如可访问性和语义等读者应该熟悉的概念。

这本书的结构

我把这本书分成十章。第一章介绍了 CSS 动画的基本组件,而后面的章节将动画与其他 web 技术相结合。

第一章 介绍了 CSS3,详细介绍了它的语法和发展,并与以前的技术进行了对比。

第二章 涵盖了 CSS3 的变换和转场。

第三章 展示了如何对图像使用 CSS3 过渡,包括图库效果。

第四章 将过渡与按钮、菜单等站点用户交互元素集成在一起。

第五章 介绍 CSS 动画模块。

第六章 在各种网页内容上使用 CSS3 动画。

第七章 展示了如何将 CSS3 过渡和动画与可缩放矢量图形(SVG)和 CSS 滤镜相集成。

第八章 将响应式网页设计和 JavaScript 与 CSS 动画结合在一起。

第九章 将变换、过渡、动画带入第三维。

第十章 展望视觉效果的 web 标准的未来,以及今天可以用来简化 CSS web 动画的各种工具。

下载代码

本书中所示示例的代码可在 Apress 网站www.apress.com上获得。在该书的信息页面上的源代码/下载选项卡下可以找到一个链接。该选项卡位于页面相关标题部分的下方。

联系作者

如果您有任何问题或意见,或者发现了您认为我应该知道的错误,请随时通过电子邮件(dudley.storey@gmail.com)或 Twitter (@dudleystorey)与我联系。我欢迎你的想法和反馈。

一、CSS3 基础知识

近二十年来,级联样式表(CSS)标准一直被用来控制网页的显示。HTML 定义了*是什么:*标题、段落、地址、图片等等。CSS 描述了元素是如何呈现给用户的,包括颜色、边框和尺寸。CSS 包括很少有网页设计者考虑的表示控件,例如文本到语音转换服务对网页内容的发音方式。

CSS 的所有原始表示规则都是为静态内容设计的;即不随时间变化的 HTML 元素。直到最近,如果你想让一张图片在网页上淡入,只有几种网络技术可以使用,其中最流行的是 JavaScript 和 Flash 。然而,这些技术并不是完整的解决方案;它们有几个严重的缺点,我将在本章末尾讨论。

现在,我们有了 CSS3 变换、过渡和动画模块。这些是所有现代浏览器都支持的 CSS 语法的扩展,重叠,在某些情况下,取代了 JavaScript 和 Flash 的传统角色。虽然 CSS3 也有其局限性,但它是许多动态网页内容的发展方向。

要了解我们是如何走到这一步的,你需要知道我们去过哪里。这一介绍性章节将提供 CSS 开发过程的概述,以及 web 开发的现状,展望未来。

CSS 的开发

web 技术的独立发展有一段不稳定的历史:浏览器供应商有时推动技术向前发展,而其他技术实现通过采用不兼容的方法使 web 开发变得复杂。

万维网联盟(W3C) 的成立是为了尝试将 web 技术综合并标准化为一系列规范,这些规范得到了 Web 开发行业的广泛支持。W3C 可以被称为 web 开发的联合国:作为一个独立的标准机构,它可以评估不同的提议;为工业界、学术界、开发者和其他利益相关者之间的讨论创建论坛;谈判和解决分歧;并敲定每个人都同意遵循的最终规范。

CSS 标准是由 CSS 工作组(CSSWG) 开发的,它是 W3C 的一个子组。随着时间的推移,CSSWG 扩展了 CSS,对网页内容的更多方面提供了更好的控制。随着 CSS 2.1 接近它的最终完成状态,规范的进一步开发被分成多个模块。这些模块中的许多都是从“第三级”建议开始的,这导致开发人员使用无所不包的术语 CSS3 来描述 CSS2.1 之后的任何东西。从技术上来说,我在本书中关注的 web 技术——动画、变换和过渡——都是全新的第一级规范,因为它们在 CSS1 或 CSS2 中没有先例。在非常正式的讨论之外,web 开发行业将它们统称为 CSS3 ,我将在本书中继续这样称呼。

与此同时,浏览器开发者继续创新。我将在本书中讨论的许多 CSS 属性最初是由 Apple、Google 和 Mozilla 提出的,而不是 W3C 或 CSS 工作组。这导致了一个问题:开发人员希望他们的浏览器支持这些很酷的技术*今天,*而不必等待 W3C 推荐、讨论和最终批准的漫长过程。每个人都知道 90 年代浏览器战争的惨痛教训以及相关的技术冲突。浏览器如何支持他们公司提出的最新技术,同时明确这些新特性是实验性的,并且不与 W3C 随后可能出现的官方声明相冲突?

这个解决方案被证明是可行的,但是有争议:CSS 厂商前缀。

CSS 厂商前缀

为了允许浏览器开发人员对 CSS3 进行创新,web 开发社区同意每个浏览器都有自己独特的前缀,用于提议的或实验性的 CSS 属性(参见表 1-1 )。

表 1-1。独特的浏览器前缀

前缀浏览器
-moz--o-浏览器
-webkit--ms-Safari/Chrome/KonquerorInternet Explorer 9+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意此处显示的供应商前缀并不是唯一存在的,只是您在大多数情况下需要的前缀。供应商前缀的完整列表可在http://alrra.github.com/little-helpers/vendor-prefixes/)找到。

每个打算支持实验性 CSS 属性的浏览器都可以通过在其前面放置自己的供应商前缀来实现。请注意,这些属性在获得 W3C 的最终批准之前是不标准的。在那之前,它们对供应商和 W3C 本身的修改和解释都是开放的。由于考虑了不同的方法并制定了不同的标准,即使在同一个浏览器中,属性名及其值的指定方式也可能会快速变化。例如,直到 Safari 5.1/iOS 5.0 发布之前,Webkit 开发团队提出了以下在 CSS 中实现线性渐变的方法:

body { background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.11, rgb(167,9,246)),
color-stop(0.56, rgb(194,242,242)) );

其他浏览器以不同的方式实现渐变。例如,在 Firefox 中是这样做的:

body {
background-image: -moz-linear-gradient(bottom, rgb(167,9,246) 11%, rgb(194,242,242) 56%);
}

这两种方法在每个浏览器中产生相同的结果;争论的焦点是哪种编码方式更好。在渐变的情况下,W3C 采取了第三种方式,与 Firefox 的方法更接近:

body {
background-image: linear-gradient(to bottom, rgb(167,9,246) 11%, rgb(194,242,242) 56%);
}

然而*,*因为浏览器不能被强制追溯升级,所以仍然有必要包含早期的厂商前缀方法,以支持旧版本。在渐变的情况下,这包括基于 Webkit 的浏览器的两种方法,这两种方法切换到支持现在的标准方法,但暂时保留供应商前缀。

约定规定 W3C 方法(最终的、预期的标准)在声明中放在最后,供应商前缀的版本放在它的前面。所有浏览器的完整声明如下:

body {
background-image: -o-linear-gradient(bottom, rgb(167,9,246) 11%, rgb(194,242,242) 56%);
background-image: -moz-linear-gradient(bottom, rgb(167,9,246) 11%, rgb(194,242,242) 56%);
background-image: -webkit-linear-gradient(bottom, rgb(167,9,246) 11%, rgb(194,242,242) 56%);
background-image: -ms-linear-gradient(bottom, rgb(167,9,246) 11%, rgb(194,242,242) 56 %);
background-image: -webkit-gradient(linear, left bottom, left top,
color-stop(0.11, rgb(167,9,246)),
color-stop(0.56, rgb(194,242,242)) );
background-image: linear-gradient(to top, rgb(167,9,246) 11%, rgb(194,242,242) 56%);
}

由于浏览器只关注他们理解的 CSS,而忽略任何他们不理解的 CSS,Safari 和 Chrome 将读取适用于该浏览器版本的声明的-webkit 行并实现它。理解规范最终版本的更高版本的浏览器将读取最后一行。

浏览器完全有可能同时支持带前缀和不带前缀的 CSS 属性。声明中的外观规则是从左到右、从上到下读取的。在有冲突的情况下,在之后规定的规则优先于在*之前规定的规则。*将 W3C 标准放在声明的最后确保了如果浏览器支持它,它将总是优先。

虽然这段代码看起来有些令人生畏,但很明显其中有大量的重复。除了不赞成使用的 Webkit 方法之外,大多数 CSS 声明都可以通过复制和粘贴第一行并在副本前添加供应商前缀来轻松创建。还有自动生成厂商前缀代码的工具和技术,我将在第十章中讨论。

为了在特定的浏览器中获得对实验性 CSS 属性的支持,您必须在样式表中包含适当的供应商前缀和值。只有两个例外:

  • 浏览器允许前缀别名(将在下一节讨论)。
  • 浏览器遵循最终的 W3C 标准,不需要前缀。

令人欣慰的是,CSS 变换、过渡和动画的属性和值从模块开始就已经被广泛认同;在撰写本文时,所有当前的浏览器都以相同的方式实现代码,尽管带有供应商前缀。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 2012 年 6 月 6 日,W3C 最终确定了过渡、动画和转换的规范,并同意让所有浏览器厂商支持它们,而不使用厂商前缀。Internet Explorer 10 是第一个这样做的浏览器,预计其他浏览器将很快跟进。旧版本的浏览器仍然需要供应商前缀。

供应商前缀问题

虽然供应商前缀系统可以工作,但它确实有几个问题。异常和边缘情况可能很难跟踪和记忆。例如,在所有浏览器中实现段落断字的最佳当前解决方案如下:

p { −ms-word-break: break-all; word-break: break-all; word-break: break-word;
-moz-hyphens: auto; -webkit-hyphens: auto; hyphens: auto; hyphenate: auto;  }

正如您所看到的,前面的一些 CSS 声明使用了供应商前缀,但是属性名称和值最终与 W3C 建议不匹配,并且不同的浏览器使用其他属性。

此外,一些浏览器供应商倾向于保留他们的专有前缀,并且在标准达成一致后不弃用它们,要求开发人员维护遗留的带前缀的 CSS 代码。

最后,懒惰的开发人员倾向于只实现一个或两个供应商前缀,忽略了在他们自己的规范版本下提供同等支持的其他浏览器。例如,许多开发人员会在他们的样式表中包含-moz 和-webbkit 前缀属性,但忘记添加-ms 或-o。因此,一些浏览器——最明显的是 Opera 的最新版本——能够识别其他供应商前缀。在 Opera 的情况下,这意味着一些-webkit 前缀属性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意因为一个包含所有厂商前缀的完整 CSS 声明可能会很长,所以本书中的代码示例通常只使用最终的预期规范。如果你想在所有浏览器中获得完全的向后兼容性,在大多数情况下,你不应该将前缀属性局限于你在这里看到的例子。

CSS3 浏览器支持

带有供应商前缀的以下浏览器版本完全支持 CSS3 转换:

  • Internet Explorer 9 (IE10 不需要前缀)
  • Firefox 3.5 及以上版本
  • Chrome 4 及以上版本
  • Safari 3.1 及更高版本
  • Opera 10.5 及以上版本
  • iOS Safari 3.2 及以上版本
  • 歌剧移动 11
  • Android 2.1 及以上版本

带有供应商前缀的以下浏览器版本完全支持 CSS3 转换:

  • Firefox 4 及以上版本
  • Chrome 4 及以上版本
  • Safari 3.1 及更高版本
  • Opera 10.5 及以上版本
  • iOS Safari 3.2 及以上版本
  • Opera Mobile 10
  • Android 2.1 及以上版本

Internet Explorer 10 支持不带前缀的转换;其他浏览器的最新版本也会这样做。

带有供应商前缀的以下浏览器版本完全支持 CSS3 动画工作草案:

  • 火狐 5 及以上版本
  • Chrome 4 及以上版本
  • Safari 4 及以上版本
  • Opera 12 及以上
  • iOS Safari 3.2 及以上版本
  • Android 4.0 及以上(2.1 起部分支持)

同样,Internet Explorer 10 支持不带前缀的 CSS 动画。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示 www.caniuse.com是跟踪浏览器对 CSS3 支持的极好资源。

CSS3 动画 的局限性

虽然 CSS3 的变换、过渡和动画非常强大,但有几个属性是它们不能影响的,至少目前不能:

  • CSS3 不能控制滚动条或“滚动”整个文档
  • 渐变不能被动画化(尽管这可以通过 SVG 或 JavaScript 来实现)。

设计原则:渐进增强和优雅退化

CSS 和 JavaScript 共有的设计方法之一是优雅退化,也称为渐进增强。简单地说,这个想法是用 CSS 来增强一个网站,而不是让网站完全依赖于它。

当您开始制作动画内容时,这变得尤其重要。因为 CSS3 只在某些浏览器中受支持,所以在应用高级技术时,你应该总是问:“如果浏览器没有显示我试图实现的内容,网站还能使用吗?”

这对于一些人来说是有问题的,尤其是客户,他们坚持认为一个站点应该“在每个浏览器中看起来和执行起来完全一样”然而,在 iPhone 和响应式网页设计的时代,这不再是一个现实的期望。相反,您需要将向站点添加高级 CSS 视为一系列假设场景:

  • 如果你用 CSS3 在网页上制作图像幻灯片(如第六章所示),浏览器不支持,会发生什么?如果用户看到一个静态的占位符图像来代替幻灯片,这样可以吗?还是需要使用 JavaScript 作为退路?
  • 如果你用 CSS3 来增强一个站点的导航条的动画效果,一些用户看不到动画效果可以吗?没有导航条他们还能用吗?

本书中的各种示例和教程将展示实现向后兼容性的不同解决方案,因为没有一种实践或技术适用于所有情况。同时,我也会强调可访问性;也就是说,允许具有不同需求和能力的用户(例如盲人或使用键盘而不使用鼠标的网站访问者)访问您的作品。

为什么是 CSS3 而不是 JavaScript 或 Flash?

你可以在表 1-2 中找到使用 CSS3 而不是 JavaScript 或 Flash 的优缺点的综合列表。

表 1-2 。CSS3 与 JavaScript 和 Flash

CSS3
优势
建立在熟悉的基础上;使用既定的 CSS 语法。简单易懂。
浏览器中最快、最流畅的动画形式,帧速率高于 JavaScript。
操纵现有的 HTML 内容,增强搜索引擎优化。
闪光
优势
建立良好的图形用户界面来创建动画。
循环、变量和函数使 ActionScript (Flash 的脚本语言)比 CSS 更强大。
JavaScript
优势
支持良好,有许多框架。
通过 DOM 和 CSS 操作 HTML 元素,这是任何 web 开发人员都熟悉的。
循环、变量和函数使这门语言比 CSS 更强大。

其他技术

对于其他新的网络技术的角色存在一定程度的混淆,特别是在客户端,所以讨论 CSS3 动画不是什么是值得的。

  • CSS3 不是 HTML5 。虽然这两种技术往往被相提并论,但 CSS3 与 HTML5 无关。标记不是表示:CSS3 同样适用于 XHTML 或 HTML3.1。在本书中,您将使用 HTML5 作为您的标记,但不是必须的。

  • CSS3 不是画布。

    是一个 HTML5 元素,在网页上创建一个 JavaScript 可访问的“绘图区域”。表面的位置是由 CSS 定义的,但是其中的任何动画都是由 JavaScript 控制的。

  • CSS 3D 变换是 CSS 变换模块的一部分,不是动画。CSS 转换用于操纵 HTML 元素的视觉透视。这些变换可以被动画化,但是 CSS 3D 变换(在第九章中讨论)本身并不是动画。

WebGL 不是 CSS 动画。WebGL 是一个 JavaScript 3D API,它操纵

元素中的绘图。

摘要

在这一章中,你已经学习了 CSS 是如何被开发和标准化的,以及 W3C 在这个过程中的角色。初学 web 开发的人有时会将 W3C 视为一种良性的霸主,从高处制定标准;事实是,该组织及其各种工作组实际上是浏览器供应商创造的创新的集成者和标准化者。

虽然它们仍处于试验状态,但新的 CSS 属性在如何实现方面仍有待开发。为此,特定于每个浏览器的供应商前缀用于区分浏览器制造商对新 CSS 属性的解释。只有当 W3C 对属性进行了标准化,并且软件中内置了支持时,浏览器才会解释非前缀版本。

虽然 CSS3 动画、过渡和变换相对于 Flash 和 JavaScript 的传统 web 动画解决方案有许多显著的优势,但它们相对较新,限制了它们只能用于相当新的浏览器版本,尤其是在 Internet Explorer 和 Opera 的情况下。在开发过程中考虑回退技术是很重要的,这样使用旧浏览器或依赖屏幕阅读器等辅助设备的用户就不会错过您的站点内容。(同样重要的是将这些问题传达给客户和其他 web 开发人员,当他们试图谈论 web 动画时,可能会经常从外围或不相关的技术(如 HTML5)中进行选择。)

在下一章,我将介绍 CSS 转换的语法以及如何创建 CSS 转换,这是最简单的 CSS3 动画形式。虽然会有一点数学,我们将通过比较 CSS3 动画和真实世界的运动示例,包括迪士尼采用的经典动画技术,来丰富这一点。

二、CSS3 变换和过渡

虽然 CSS 动画可以用来改变 HTML 元素的几乎每一个方面(除了上一章列出的属性),但操纵网页表示的一些最强大的方法存在于 CSS Transforms 和 Transitions 模块中,这在 CSS3 中是全新的。

CSS 转换是最简单的动画形式:两种状态之间的移动。一旦你掌握了本章中描述的过渡的基本语法,你将能够将简单、有效的动画应用到图像(在第三章中描述)和用户界面元素(在第四章中描述),然后开始创建更复杂的关键帧动画(在第五章和更远的地方描述)。

CSS 变换

有四个主要的 CSS 翻译函数:translaterotatescaleskew。这些功能被组合在matrix转换功能中。您将把这些转换应用到一个标准的 web 页面布局中,这个页面布局是一个浮动在文本段落旁边的图像,如清单 2-1 所示。

清单 2-1 。 HTML5 代码为浮动图像

<!DOCTYPE html>
<html>
<head>
<title > Simple CSS3 Transformation</title>
</head>
<body>
<p> < img src = "dudley-storey-statuette.jpg" alt = "Student-made statuette of Dudley Storey" style = "width: 300px; height: 300px; float: left; margin: 0 2em 1.4em 0;" > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eu mi tellus. Vestibulum tortor erat, facilisis in auctor semper, pharetra quis mi...</p>
</body>
</html>

清单 2-1 中所示的代码将产生图 2-1 所示的布局。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-1。浮动有段落文本的图像

有了这个基础页面,就可以开始对图像元素应用变换了。

旋转

首先,你将通过旋转来变换图像(见清单 2-2 )。CSS3 旋转变换的值可以用度、梯度、转角或弧度来指定,使用正或负浮点值来创建顺时针或逆时针旋转。您必须包含供应商前缀以涵盖所有浏览器。

清单 2-2 。 内嵌 CSS 旋转图像

<img src = "dudley-storey-statuette.jpg" alt = "Statuette of Dudley Storey" style = "width: 300px; height: 300px; float: left; margin: 0 2em 1.4em 0; -moz-transform: rotate(7.5deg); -ms-transform: rotate(7.5deg); -o-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg); transform: rotate(7.5deg); ">

清单 2-2 中代码的结果如图图 2-2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-2。带有 CSS 旋转变换的浮动图像

虽然测量旋转角度是编写 CSS 转换时最常用的方法,但 CSS3 允许各种单位,如表 2-1 所示:

表 2-1。**CSS 角度数据类型可能的单位制

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用rotate : 浮动图像时,有一些事情需要注意

  • 页面上的其他 HTML 内容不受变换的影响:段落的布局不会随着图像的旋转而改变;进一步旋转图像会使其与文本重叠。(CSS 区域模块支持对变换做出反应的内容)。
  • 文档对象模型(DOM) 同样不受影响;转换后的元素(如offsetWidth)的属性值也将保持不变。
  • CSS 转换本质上在受影响的元素上强加了一种相对定位的状态;元素使用的原始空间将被保留。
  • 如果overflow属性的值是scrollauto,滚动条将根据需要出现,使您能够查看在可见区域之外转换的内容。
  • 旋转从元素的计算的中心开始,即transform-origin
  • 应用于元素的其他 CSS 外观规则,如box-shadow,在转换之前应用*,因此它们将随效果一起旋转。*
  • 将图像旋转 180 度不会翻转或镜像图像;这可以通过使用本章稍后讨论的scale变换或第九章讨论的 3D 旋转来实现。
  • 你可以旋转任何你想要的 HTML 内容,但是从设计的角度来看,不建议你旋转文本:这样做会降低可读性,并且会给你的读者带来痛苦。
  • 测量单位需要存在,即使旋转量为 0。在大多数 CSS 测量中,0 对于任何单位都是 0,(即width: 0作为width: 0px的替代)。)但旋转到 0°时,必须指定transform: rotate(0deg)transform: rotate(0)不起作用。

正如您所看到的,由于需要包含供应商前缀,转换的内联样式可能会很长。更常见的是单独创建转换,如嵌入或链接样式表中的classid(见清单 2-3 )。

清单 2-3 。 用于转换图像的嵌入式 CSS 样式表

<!DOCTYPE html>
<html>
<head>
<title > Simple CSS3 Transformation</title>
<style>
img.tilt {
width: 300px; height: 300px; float: left;
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
}
</style>
</head>
<body>
<p > <img src = "dudley-storey-statuette.jpg" alt = "Statuette of Dudley Storey" style = "margin: 0 2em 1.4em 0; class = "tilt" > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eu mi tellus. Vestibulum tortor erat, facilisis in auctor semper, pharetra quis mi...</p>
</body>
</html>

要旋转图像,就像它被钉在右上角一样,你必须将元素的transform-origin移动到那个位置,如清单 2-4 中的所示。

清单 2-4 。 从一个角落旋转一个图像

img.tilt {
width: 300px; height: 300px; float: left;
-moz-transform-origin: right top;
-o-transform-origin: right top; -ms-transform-origin: right top;
-webkit-transform-origin: right top; transform-origin: right top;
-moz-transform: rotate(−10deg); -o-transform: rotate(−10deg);
-ms-transform: rotate(−10deg); -webkit-transform: rotate(−10deg);
transform: rotate(−10deg);
}

清单 2-4 中的代码将产生如图图 2-3 所示的结果;注意,我不得不稍微改变图像的内嵌样式,为右边的空白提供更多的空间,以补偿图像的新角度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-3。带有段落文本的旋转浮动图像

transform-origin取值的方式与background-position和其他组合水平和垂直偏移的属性相同。这些值被指定为原点的水平位置,后跟相对于元素本身的垂直位置*。*这些值可以指定为关键字(topcenterbottomleftright)、数字或两者的组合。它们也可以在元素本身的区域之外(例如,在元素的上方或下方创建一个变换原点轴,如第三章中的“card fan”图像库示例所示)。

Webkit CSS3 转换锯齿问题

Chrome 和 Safari 的早期版本(直到版本 5.1)包含一个渲染 bug:当转换一些元素时,浏览器不会对旋转或倾斜的 HTML 内容的边缘进行反锯齿,从而导致图像边缘出现所谓的“锯齿”或“阶梯”,如图 2-4 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-4。缩放图像,显示使用 CSS 变换旋转的图像边缘的锯齿

有多种方法可以解决这个问题:

  • 在元素周围应用 1 像素的白色边框。
  • webkit-backface-visibility: hidden;应用到元素。
  • 向元素添加另一个转换,比如-webkit-transform: rotate(−10deg) translateZ(0);

然而,没有一种技术能在所有情况下都最好地解决呈现错误;每种技术的有效性取决于所呈现的元素的上下文。

标度

当应用于图像时,scale变换有点奇怪:考虑到改变图像的heightwidth会有几乎相同的视觉效果,它可能看起来没什么用。不同之处在于,scale可以应用于任何 HTML 元素的*:改变段落的width会重排文本内容,但改变其scale会使文本物理上变大或变小。*

scale的值是一个乘数:scale(2)应用于一个元素将使它看起来两倍宽和两倍高(换句话说,是正常大小的四倍),而scale (.5)将产生一个原始大小四分之一的图像。scale将在所有方向上均等地变换元素。您也可以将scale应用于顺序方向:X(水平)、Y(垂直)和 Z(深度)。

使用 scaleX 翻转图像

您可以使用scale CSS 转换来有效地镜像 HTML 元素(通常是图像,尽管原则上这种技术可以应用于任何元素)。如果scale1开始,如图 2-5 左侧所示,当您降低scale的值时,受影响的元素将变小,直到您达到 0,此时图像消失。如果将该值推入负值区域,图像将再次开始增长,但会出现水平翻转,如图 2-5 右侧所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-5。使用 scaleX()的小负值的影响

您可以使用scale快速翻转页面上的图像,而不是通过 Adobe PhotoShop 等应用处理它来生成新的副本。清单 2-5 展示了如何应用变换来反转亚伯拉罕·林肯的图像。

清单 2-5 。 使用内嵌变换样式翻转图像

<img src="lincoln.jpg" alt="Abraham Lincoln, 1863" style="width: 389px; height: 480px;
-moz-transform: scaleX(−1); -o-transform: scaleX(−1);  -ms-transform: scaleX(−1);
-webkit-transform: scaleX(−1); transform: scaleX(−1);">

图 2-6 显示了清单 2-5 中代码的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-6。亚伯拉罕·林肯的原始照片(左)使用 CSS3 缩放变换(右)翻转

使用像这样的 CSS 技术,您可以动态调整图像,而不必返回 PhotoShop 进行更改,然后保存文件并上传到网站,也不必修改任何 HTML 代码。

翻译

scale一样,translate修改器起初看起来可能有点多余:它使用相同的坐标系(视觉上,产生相同的结果)将topleftbottomright属性应用于相对定位的元素。然而,正如你将看到的,translate可以使 HTML 内容更容易动画化。

translate(x,y)使用正值或负值在水平和垂直方向移动元素。translateX()在水平面内移动元素,translateY()在垂直方向上移动元素。

例如,如果你想将图 2-4 中显示的小雕像图像向上4em并向右移动50px,你可以使用清单 2-6 中显示的代码。

清单 2-6 。 用于翻译图片的 CSS 代码

img.tilt {
width: 300px; height: 300px; float: left;
-moz-transform: translate(50px, -4em); -o-transform: translate(50px, -4em);
-ms-transform: translate(50px, -4em); -webkit-transform: translate(50px, -4em);
transform: translate(50px, -4em);
}

歪斜

skew应用到一个元素会水平或垂直地“剪切”它,这对于赋予一个元素额外的速度或运动感很有用。想象一下,拿一个矩形的对边(例如,上边和下边,或者左边和右边)向不同的方向拉,同时确保它们保持平行。

skew输入的值指的是其他侧将被设置的角度。例如,将图像向右“倾斜”是一种skewX变换。transform: skewX(21deg)将意味着图像的左右边缘将被设置为与垂直方向成 21 度(参见清单 2-7 )。将图像向左倾斜仍然使用skewX,但是使用负值:例如:skewX(−21deg),将设置相同的边缘从垂直方向负 21 度(即向左)。skewY将元素框的左侧右侧上下移动。

清单 2-7 。 倾斜图像的 CSS 代码

img.tilt {
width: 300px; height: 300px; float: left;
-moz-transform: skewX(21deg); -o-transform: skewX(21deg);
-ms-transform: skewX(21deg); -webkit-transform: skewX(21deg);
transform: skewX(21deg);
}

你可以在图 2-7 中看到列表 2-7 的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-7。倾斜 CSS 的矩形元素

在相应方向上平移元素时,水平和垂直倾斜与适当值的组合可以提供元素形成一个盒子的一边的印象,如清单 2-8 所示。

清单 2-8 。 CSS 代码将一幅图像转换成一个等角长方体的一边

img.tilt {
width: 300px; height: 300px; float: left;
-moz-transform: skewY(30deg); -o-transform: skewY(30deg);
-ms-transform: skewY(30deg);  -webkit-transform skewY(30deg);
transform: skewY(30deg);
}

将单独的变换组合在一起(例如,旋转和平移)可以为 CSS 提供更多的功能,并为动画提供更多的可能性。

组合变换

可以通过以下两种方式之一合并元素的转换:作为转换属性的空格分隔值,或作为矩阵属性的值。

要将转换合并为一个transform属性的空格分隔值,使用清单 2-9 中的代码。

清单 2-9 。 单个 CSS 声明中的多次变换

img.tilt { width: 300px; height: 300px; float: left;
-moz-transform: translate(50px, -4em) rotate(15deg);
-webkit-transform: translate(50px, -4em) rotate(15deg);
-o-transform: translate(50px, -4em) rotate(15deg);
-ms-transform: translate(50px, -4em) rotate(15deg);
transform: translate(50px, -4em) rotate(15deg); }

将转换合并为一个matrix属性的值的过程要复杂得多。矩阵变换稍微超出了本书的范围;使用工具生成代码是最简单的。Useragentman 矩阵构造集(www.useragentman.com/matrix/)和 CSS3 变换矩阵计算器(www.leeourand.com/test/transform/test/transform.html)提供了两种方法。矩阵变换的解释可以在 CSS Matrix Transform for The mathematical Challenged(www.useragentman.com/blog/2011/01/07/css3-matrix-transform-for-the-mathematically-challenged/)和 Opera Web Developer site (http://dev.opera.com/articles/view/understanding-the-css-transforms-matrix).找到,虽然它们的优点是更短和更有效,但是矩阵变换不是人类可读的,所以我不会在本书的例子中使用它们。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意编写单独的转换将而不是创建一个组合的转换。

img.tilt { width: 300px; height: 300px; float: left;
transform: translate(50px, -4em);
transform: rotate(15deg);
-webkit-transform: translate(50px, -4em);
-webkit-transform: rotate(15deg); }

使用上面的 CSS,浏览器将遵循最后一行适用的代码;也就是说,图像将被旋转,但不会被平移。

CSS 过渡

CSS 转换就是:从一种视觉状态到另一种视觉状态的转换,通常是由一些用户事件引发的,比如鼠标悬停在一个元素上。换句话说,转换是点对点的。如果你需要在多个状态和另一个状态之间制作动画,你会发现 CSS 关键帧更适合这项工作。(CSS 关键帧将在第五章中讨论。)

注意,对于本章中的例子,我将使用:hover来启动转换,但是从技术上来说对元素属性值的任何修改都会触发该属性的转换。

让我们回到第一个例子,为页面上的图像创建一个简单的旋转过渡。当用户将鼠标放在图像上时,您希望将元素旋转 7.5 度。你可以通过在.tilt选择器中添加一个:hover伪类来做到这一点(:hover可以应用于每个元素,而不仅仅是链接),如清单 2-10 所示。

**清单 2-10 。上的 CSS 变换悬停,无过渡

<style>
img.tilt:hover {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
}
</style>

清单 2-10 中显示的代码可以工作,但是如果你试着在浏览器中查看页面,你会发现鼠标经过时没有动画,只有一个状态和另一个状态之间的瞬间切换。您将通过使用transition属性在这些状态之间创建一个动画(参见清单 2-11 )。

清单 2-11 。 使用过渡平滑 CSS 变换

img.tilt:hover {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
-moz-transition: 2s all; -webkit-transition: 2s all;
-o-transition: 2s all; transition: 2s all;
}

在清单 2-11 中显示的代码要成功得多:当你将鼠标放在图像上时,你会看到它现在平滑地旋转到新的位置。用多个供应商前缀重复的语法也很容易理解。元素旋转超过两秒钟,在转换过程中它的所有属性都可以改变。注意,值的顺序无关紧要:您可以使用2s allall 2s

如果你在包含几分之一秒的时间段内制作元素动画,你可以将时间段指定为以秒为单位的浮点值,或者以毫秒(千分之一秒)为单位,如清单 2-12 所示。

清单 2-12 。 一个以秒为单位的 CSS 转场

img.tilt:hover {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
-moz-transition: 2.35s all; -webkit-transition: 2.35s all;
-o-transition: 2.35s all; transition: 2.35s all;
}

这也可以用清单 2-13 中的来表示。

清单 2-13 。?? 一个以毫秒为单位的 CSS 转场

img.tilt:hover {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
-moz-transition: 2350ms all;
-webkit-transition: 2350ms all; -o-transition: 2350ms all;
transition: 2350ms all;
}

虽然以毫秒为单位的动画计时允许更高的精度,但是上面的两个声明达到了相同的结果——使用毫秒并不能创建更平滑的动画序列。很少有动画需要精确到千分之一秒,以毫秒为单位指定时间通常需要更多的输入,所以我坚持使用更熟悉的秒格式(例如,即使值小于一秒:transition: .35s all)。你应该使用你觉得更舒服的系统。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意如果你已经用 JavaScript 制作了动画,注意这里的区别:CSS3 可以使用秒毫秒的浮点值来计时动画。JavaScript 专门使用毫秒,尽管许多用于创建动画的 JavaScript 框架可以使用以秒为单位的时间间隔。

还有一点需要改进。您会注意到,旋转元素后,将鼠标从图像上移开会立即将它恢复到初始状态。虽然这可能是您在某些情况下为网页元素寻求的视觉效果,但在大多数情况下,最好是显示元素返回到其初始方向,就像它到达其旋转状态一样平滑。

解决方案有点违反直觉:将 CSS 代码的transition部分从:hover声明移到图像的默认状态,只保留:hover声明上的transform(参见清单 2-14 )。

清单 2-14 。 创建与默认状态的平滑过渡

<style>
img.tilt {
width: 300px; height: 300px; float: left;
-moz-transition: 2s all; -webkit-transition: 2s all;
-o-transition: 2s all; transition: 2s all;
}
img.tilt:hover {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
}
</style>

想法很简单:将transition属性放在类声明中意味着任何从和返回到状态的转换都是有效的。前面的例子将转换放在了:hover声明上,这意味着它只在鼠标悬停时有效,在返回正常状态时无效。

您还会注意到,如果在图像区域来回移动鼠标,过渡会被打断;它的运动将平稳地逆转。您可以通过仅指定转换时间来进一步简化代码(参见清单 2-15 )。

***清单 2-15 。***CSS 变换中的定时旋转

img.tilt {
width: 300px; height: 300px; float: left;
-moz-transition: 2s;
-webkit-transition: 2s; -o-transition: 2s;
transition: 2s; }
img.tilt:hover {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
}

正如你所看到的,使用 CSS3 转场创建一个平滑简单的动画是很容易的。您可以修改 CSS 属性提供访问的元素外观的几乎每个方面并制作动画。到目前为止,我向您展示的转换一次只改变了元素的一个方面,并且总是以相同的方式进行。要创建更丰富的动画,您可以组合同一元素在不同时间和速度发生的多个属性转换。

延迟和组合过渡效果

转换事件可以通过添加一个transition-delay来延迟,或者作为一个单独的属性,或者附加到transform的值上:

-moz-transition: 2s 4s;
-webkit-transition: 2s 4s; -o-transition: 2s 4s; transition: 2s 4s;

请注意,延迟在动画开始时以及元素反转到其起始点时生效。光标停留在图像上四秒钟后,动画才会开始;一旦完全旋转,该元素将停留在原位四秒钟,然后返回到其默认方向。(另请注意,直到鼠标在图像上停留至少四秒钟,动画才会开始)。

你可以通过将多个 CSS 属性添加到:hover状态来同时激活它们(见清单 2-16 )。

清单 2-16 。?? 几个 CSS 属性同时过渡

<style>
img.tilt {
width: 300px; height: 300px; float: left;
-moz-transition: 2s;
-ms-transition: 2s;
-o-transition: 2s;
-webkit-transition: 2s;
transition: 2s;
}
img.tilt:hover {
-moz-transform: rotate(15deg);
-o-transform: rotate(15deg); -ms-transform: rotate(15deg);
-webkit-transform: rotate(15deg); transform: rotate(15deg);
opacity: .3;
}
</style>

属性可以在动画中被赋予单独的时间,方法是将transition-duration声明为具有逗号分隔值的单独属性。假设你想在悬停时将图像向右移动,同时淡出,但是淡出时间是移动时间的一半(见清单 2-17 )。

清单 2-17 。 多个属性的 CSS3 转换,每个属性有不同的计时

<style>
img.tilt {
width: 300px; height: 300px; float: left; position: relative;
-moz-transition-property: opacity, left;
-o-transition-property: opacity, left;
-webkit-transition-property: opacity, left;
transition-property: opacity, left;
-moz-transition-duration: 2s, 4s;
-o-transition-duration: 2s, 4s;
-webkit-transition-duration: 2s, 4s;
transition-duration: 2s, 4s;
}
img.tilt:hover {
opacity: .2; left: 60px;
}
</style>

我添加了position: relative,以便能够通过改变其left的值来移动元素,并通过清楚地声明要动画的属性来提高动画的效率。(显然,你不必为所有浏览器都支持的属性加上前缀,比如opacity。)您会注意到,在某些浏览器中,从左到右的动画可能不是特别流畅。让我们将动画属性改为translate,如清单 2-18 所示。

清单 2-18 。 一 CSS3 翻译过渡

<style>
img.tilt {
width: 300px; height: 300px; float: left;
-moz-transition-property: opacity, translateX;-o-transition-property: opacity, translateX;
-webkit-transition-property: opacity, translateX;
transition-property: opacity, translateX;
-moz-transition-duration: 2s, 4s;
-o-transition-duration: 2s, 4s;
-webkit-transition-duration: 2s, 4s;
transition-duration: 2s, 4s;
}
img.tilt:hover {
opacity: .2;
-webkit-transform: translateX(60px);
-moz-transform: translateX(60px); -ms-transform: translateX(60px);
-o-transform: translateX(60px); transform: translateX(60px);
}
</style>

你可能会发现运动现在更顺畅了;对于通过操纵absoluterelative定位来动画化 HTML 元素的移动来说,translate是一个很好的选择。

介绍缓动功能

请仔细观察您到目前为止创建的动画中鼠标悬停时图像的移动:它有一些特殊之处(延长动画的时间值可能有助于使其更加清晰)。图像的运动不是机械的,而是有机的:从默认位置开始,图像随着旋转而加速,在一段时间内达到恒定速度,然后在静止之前减速。

在动画中,这种运动被称为缓入/缓出。它是日常世界中物体的运动。例如,没有一辆车,无论多么强大,可以达到 0-60 秒的速度记录。每一个运动的物体都加速到一定的速度;在其行程结束时(除了极端情况,如汽车以最高速度撞上砖墙),物体将在停止前减速。

在 CSS3 动画中,缓和转场是默认的;没有必要声明你正在使用它们。如果你想让动画更有“机械”感,你可以从指定一个linear过渡开始(见清单 2-19 )。

清单 2-19 。 CSS 为线性旋转过渡

<style>
img.tilt {
width: 300px; height: 300px; float: left;
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
-moz-transition: 2s transform linear;
webkit-transition: 2s transform linear; -o-transition: 2s transform linear;
transition: 2s transform linear;
}
</style>

你会发现鼠标悬停时图像的运动更加机械。

过渡定时功能和贝塞尔曲线

linearease只是被称为计时函数 的两种形式,即描述一个物体以直线从 A 到达 B 的方式。这些定时函数可以用一种称为贝塞尔曲线的数学表达式来表示。

例如,如果你绘制了一个元素在线性条件下从 0 度到 15 度的转换过程中的运动,将时间分配给水平轴,将图像的角度分配给垂直轴,则线性动画的图形将看起来像图 2-8 。随着时间的推移,旋转的角度随着时间的流逝而增加,从而产生了恒定的运动速度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-8。线性动画图形:x 轴为时间,y 轴为距离/角度。注意这种直接关系

从声明中删除关键字linear会使动画返回到自然的放松状态,当绘制在相同的轴上时,看起来更像图 2-9。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-9。缓时功能:x 轴时间,y 轴距离

正如你所看到的,旋转的角度在放松的动画的第一瞬间变化很慢;在过渡的中间,变化率显著增加,达到一个“极限速度”,然后减速,直到序列到达其结尾。

有几个关键字可用作普通过渡运动的快捷方式(见表 2-2 )。

表 2-2。常用三次贝塞尔计时函数的关键字替代方法

关键字图表三次贝塞尔曲线描述
linear外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传0, 0, 1, 1瞬间启动和停止;在整个运动范围内速度恒定。
ease外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传0.25, 0.1, 0.25, 1启动迅速,加速迅速;缓慢过渡到终点停止。
ease-in外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传0.42, 0, 1, 1缓慢启动,加速爬升至突然停止。
ease-out外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传0, 0, 0.58, 1动画瞬间开始,运动在接近尾声时变慢。
ease-in-out外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传0.42, 0, 0.58, 1在动画过程中元素被缓和地放入和放出:一个缓慢平滑的开始,在过渡中间短暂地达到一个恒定的速度,然后减速到停止。

正如您所看到的,所有缓动曲线都有一个三次贝塞尔表达式形式的数学等价物:一个数字对,其中每组浮点数字描述坐标空间中的一个点,形成一条创建缓和曲线的线。(注意,不能移动或定义曲线任一端的终止点)。

对于渐入渐出曲线,这些点看起来像图 2-10 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-10。贝塞尔曲线渐出动画效果

用 CSS 表示,图 2-10 是这样的:

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

理解三次贝塞尔函数允许你为你的 CSS 动画创建几乎无限多种自定义缓动曲线。甚至可以给这些点负值或大于 1 的值来创建极端的缓和曲线,这可以在图 2-11 中看到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-11。使用负值和大于 1 的值的贝塞尔曲线,创建“推拉”动画效果

在 CSS 中,图 2-11 是这样的:

transition: all 2000ms cubic-bezier(0.280, -0.315, 0.685, 1.390);

使用这些值创建带有“弹簧”或“弹跳”的动画,也称为推拉动画。我将在第四章中探索这些动画的用途。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示停止(http://matthewlein.com/ceaser/)和三次(http://cssglue.com/cubic)是从图形操作的三次贝塞尔曲线生成 CSS 缓和代码的优秀工具。两者都包括一个测试服务,允许你看到变化的可视化结果。彼得·贝弗卢的资源(http://peter.sh/experiments/css3-transition-timing-functions/)也很有用,尤其是在可视化阶跃函数方面。

分步制作动画

也可以分步制作元素动画,而不是平滑过渡。(想象一下时钟上秒针的突然递增运动)。这些是通过steps函数和变量创建的。在这里,我将通过只显示标准属性、Firefox 和 Webkit 的 CSS3 代码来节省代码。

假设你有一个h1想要在鼠标悬停时制作动画(见清单 2-20 )。

*清单 2-20 。*中的过渡序列为一个标题的步骤

<style>
h1 {
 font-family: Futura; "Arial Black", Arial, sans-serif;
 text-align: center;
 }
h1:hover {
 -moz-transition: 4s all steps(3, end);
 -webkit-transition: 4s all steps(3, end);
 transition: 4s all steps(3, end);
 -moz-transform: translateX(400px);
 -webkit-transform: translateX(400px);
 transform: translateX(400px);
 }
</style>

清单 2-20 中的代码将在两秒钟的延迟后,在四秒钟内连续三次“跳跃”动画化所有的h1元素,每一步之间没有可见的运动。其他变化也是可能的,如表 2-3 所示。

表 2-3。CSS3 过渡的步长值

功能图表描述
steps(3)外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传x 步数的动画(图中显示了steps(3))。开始时暂停。相当于steps(x, end)
steps(3), end外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传元素仍在开始处,在结尾处暂停。
steps(x), start外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传动画即时开始,元素在结束时暂停。

在 CSS3 过渡中增加对移动设备的支持

到目前为止,您只在:hover上激活了变换。这是最常见的伪类,但不是唯一的,你会在第三章中看到。

:hover可能会给安装在移动设备上的浏览器带来两个问题:

  • 用户的指尖可能会模糊动画,尤其是在较小的屏幕上。
  • 一些设备不支持:hover(严格来说,这是有意义的,因为当前所有的移动平台都依赖于直接触摸)。相反,它们涵盖了与:focus.的简单用户交互

如果您选择使用:hover,您应该通过使用一个分组选择器来覆盖只有:focus的移动平台的可能性,如下面的代码所示:

img.tilt:hover, img.tilt:focus {
-moz-transform: rotate(7.5deg); -o-transform: rotate(7.5deg);
-ms-transform: rotate(7.5deg); -webkit-transform: rotate(7.5deg);
transform: rotate(7.5deg);
}

摘要

在本章中,你已经学习了 CSS3 变换 : scalerotateskewtranslate的语法,包括如何翻转图像和组合变换。我还讲述了最简单的动画形式 CSS3 转场的代码,向您展示了如何创建转场,如何修改它们的定时和延迟,以及启动它们的两种常用方法。

虽然也可以使用steps功能和关键字快捷键,但过渡的移动和定时通常是通过贝塞尔曲线控制的。

在下一章,我们将探索如何将这些动画技术应用于图像元素。

三、图像的 CSS3 过渡

CSS3 转场在网页上最常见的用途是,首先,为用户界面(UI)元素生成视觉效果(将在下一章讨论),其次,为图像创建简短的动画效果。在这一章中,你将使用转场模块的语法通过动画来增强图像及其标题。这些技术展示了在视觉上增强网页的简单方法,使图像内容和相关信息更具交互性,同时最小化屏幕“空间”:这是移动 web 开发时代的一个重要考虑因素。

简单图像交叉渐变效果

你将处理的第一个过渡将演示在后续练习中使用的许多基本概念:将大小完全相同的图像放置在彼此之上,并在:hover启动事件(参见图 3-1 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-1。使用过渡不透明度的交叉淡入淡出效果

有几种可能的方法可以达到图 3-1 所示的效果:

  • 选项 1 :将第一张图片指定为容器元素的 CSS background,第二张图片在元素本身内部。
  • 选项 2 :创建一个带有position: relative的容器元素来保存两个图像,第二个图像带有position: absolute
  • 选项 3 :将两幅图像都指定为背景,并在它们之间进行过渡。

这三种方法各有利弊。第一种和第三种方法可能创建速度更快,响应速度更快,但是不太容易使用。使用第一种方法还意味着对图像的任何更改都必须在不同的地方进行,因为一个图像将只存在于 CSS 中,而另一个图像将作为 HTML 元素存在。第二个选项可能需要更多的代码,但好处是将两张图片都保存为<img >元素,因此更容易访问。在撰写本文时,第三个选项在技术上超出了规范范围,但可能是最容易使用的。

我将使用由 Ton Rulkens (www.flickr.com/photos/47108884@N07/4595559479/)和 Peter Shanks (www.flickr.com/photos/botheredbybees/1954163161/)提供的照片来演示所有这三种方法,这些照片是经许可使用的。

两幅图像的大小必须完全相同。有几种方法可以实现这一点:

  • 在 Adobe PhotoShop 等应用中将图像裁剪为相同的尺寸(这是最明显的解决方案)。
  • 您可以通过 CSS 或 HTML 属性修改图像的widthheight,尽管这通常会导致视觉失真。
  • 您可以在div上设置一个widthheight,并使用overflow:hidden来修剪图像中落在该区域之外的部分。
  • 如果两个图像都被表示为代码中的元素,那么可以对每个图像使用相同的 CSS clip值。

选项 1:第一张图片作为 CSS 背景

这个选项的 HTML 非常简单,如清单 3-1 所示。

清单 3-1。 HTML 选项 1 创建两个分层图像

<div class=crossfade>
        <img src=jatropha-hybrid.jpg alt="Jatropha hybrid leaf">
</div>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意本书中展示的 HTML5 代码样本是“缩小的”语法,以节省空间。元素仅在需要时闭合,属性值仅在包含空格时加引号。

清单 3-2 中显示的 CSS 也非常简单。

清单 3-2。 CSS 为 HTML 选项 1 创建交叉渐变效果

div.crossfade { background: url(leaf-veins.jpg); background-size: cover; }
div.crossfade, div.crossfade img  { width: 418px; height: 500px;  }
div.crossfade img { transition: 3s opacity ease-out; }
div.crossfade img:hover { opacity: 0; }

选项 2:两个图像都作为 HTML 元素

或者,您可以将两个图像作为单独的图片堆叠在一个容器中;HTML 如清单 3-3 中的所示。

清单 3-3。 HTML 选项 2 创建分层图片

<div class=crossfade>
        <img src=leaf-veins.jpg alt="Red-veined leaf">
        <img src=jatropha.jpg alt="Jatropha hybrid leaf">
</div>

与其通过将一个类附加到第二个图像来使 HTML 变得复杂,不如使用第 n 个子伪选择器来改变它,如清单 3-4 所示。

清单 3-4。 CSS 为 HTML 选项 2 创建交叉渐变效果

div.crossfade { position: relative; }
div.crossfade, div.crossfade img { width: 418px; height: 500px; }
div.crossfade img:nth-child(2) { position:absolute; left:0; top:0; transition: 3s opacity ease-out; }
div.crossfade img:nth-child(2):hover { opacity: 0; }

选项 3:两幅图像都作为背景

虽然最容易编码,但这个选项也是最大胆的:它超出了当前的规范(而且,在撰写本文时,仅在 Chrome 中受支持)。在这种情况下,包含的 div 完全没有内容,一切都是通过 CSS 实现的,如清单 3-5 所示。

清单 3-5。 CSS 创建图像交叉淡入淡出效果(选项 3)

div.crossfade { width: 418px; height: 500px; transition: 3s background-image ease-out;
background-image: url(leaf-veins.jpg); }
div.crossfade:hover { background-image: url(jatropha.jpg);  }

如果你愿意进一步推进你的代码,另一种方法是对 CSS4 cross-fade属性使用相同的空div,如清单 3-6 所示。

清单 3-6。【CSS4】交叉淡入淡出用于创建图像过渡

div.crossfade { width: 418px; height: 500px;
background-image: -webkit-cross-fade(url(jatropha.jpg), url(leaf-veins.jpg),0);
transition: 2s background-image linear; }
div.crossfade:hover { background-image: -webkit-cross-fade(url(jatropha.jpg), url(leaf-veins.jpg),100); }

顾名思义,cross-fade是一种更有效的方法,但目前实际应用有限;cross-fade不是通过过渡opacity来伪造溶解效果,而是用适当的算法来处理图像。

CSS4?你在说什么,威利斯?

随着 CSS3 在浏览器中成为主流,W3C 的注意力已经转移到 CSS 开发的下一个阶段,其中包括新的选择器以及图像和渐变的外观规则。浏览器支持(在撰写本文时)是有限的和试验性的,但正在增长。

与本节最相关的是 CSS4 图像值和替换的内容模块,您可以在http://dev.w3.org/csswg/css4-img/阅读其概述。还有一个用于背景和边框(http://dev.w3.org/csswg/css4-background/)以及文本(http://dev.w3.org/csswg/css4-text/)的模块。

几乎不可避免的是,在不久的将来,“CSS4”这个术语将会像今天的“CSS3”一样被广泛误解和误用,正如我在第一章中所讨论的。

用 CSS3 增强的简单图库

对于第二个例子,您将使用 HTML 创建一个图像缩略图图库,并使用 CSS3 过渡增强图库中大图像的显示(参见图 3-2 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-2。一个简单的图库

你至少需要三对图像。每一对将由一个缩略图和一个相同图像的全尺寸版本组成。大版可以是你希望的任何尺寸,只要合理;我建议缩略图的大小大约为 150 x 150 像素。为了保持文件组织的清晰,请遵循命名约定。例如,如果全尺寸图像是x,jpg,则将成对的缩略图命名为x_thumb.jpg,两者都存储在 images 文件夹中。

HTML 标记

你的目标是尽可能保持图库中使用的 HTML 简洁明了。为此,您将使用定义列表作为标记的基础。定义列表包含成对的元素:一个(定义术语)用于您的缩略图,另一个(定义声明)用于它匹配的大图像。

在相对于文件夹的标记中组装内容,页面的 HTML 看起来类似于清单 3-7 (使用前一个练习中的图片,以及 Paul Bica 的另一张照片(www.flickr.com/photos/dexxus/4137841698/)

清单 3-7 。 HTML5 为一个简单的图库

<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<title> CSS3 Gallery</title>
<style>
        body { background: #234; }
</style>
</head>
<body> 
  <dl id=gallery>
        <dt><img src=jatropha_thumb.jpg alt="Jatropha Leaf Thumbnail">
        <dd><img src=jatropha.jpg alt="Jatropha Leaf Large">
        <dt><img src=leaf-veins_thumb.jpg alt="Leaf Veins Thumbnail">
        <dd><img src=leaf-veins.jpg alt="Leaf Veins">
        <dt><img src=cascada_thumb.jpg alt="Cascada Thumbnail">
        <dd><img src=cascada.jpg alt="Cascada Large">
</dl> 
</body>
</html>

初始 CSS

这里使用的 CSS 应该是不言自明的:你正在定位定义列表relative,这样大的、绝对定位的图像是相对于列表而不是文档的主体来组织的。绝对定位大图像也意味着您可以将它们堆叠在完全相同的位置,并且文档的其余部分(包括缩略图)将表现得好像全尺寸图像根本不在那里一样。最后,用visibility: hidden隐藏大图。,并通过在带有相邻组合子的dt元素上使用:hover选择器再次显示它们,如清单 3-8 所示。

清单 3-8。 CSS 用于一个简单的图库

dl#gallery { position: relative; }
dl#gallery dt img { width: 150px; height: 150px; margin: 2.2em; }
dl#gallery dd { position: absolute; left: 200px; top: 2.2em; visibility: hidden; }
dl#gallery dt:hover + dd { visibility: visible; }

将鼠标移动到缩略图图像上,会立即显示定义列表中与之配对的大图像。但是,在将动画引入画廊之前,您需要解决一个 UI 问题。

改善画廊

到目前为止,您所做的工作是有效的,但是有点笨拙:您会注意到,将鼠标放在缩略图图像的右侧会使相关的大图像立即出现。您将通过几行 CSS 来解决这两个问题,从用visibility(不能动画)隐藏大图像改为用opacity(可以),同时与缩略图共享定义术语的大小,如清单 3-9 所示。

清单 3-9。 用转场增强图库的 CSS

dl#gallery dd { position: absolute; left: 200px; top: 2.2em; opacity: 0;
transition: .85s opacity linear; }
dl#gallery dt:hover + dd { opacity: 1; }

现在,当你将鼠标移动到缩略图上时,大图会平滑地淡入。

添加字幕

如果用户能够阅读图片说明,这将非常有帮助。在这种情况下,不需要添加任何额外的标签,只需要标题内容和 CSS。我将修改其中一个<dt ><dd >对作为例子,如清单 3-10 所示。

清单 3-10。 简单标题图片的 HTML 示例

<dt><img src=jatropha_thumb.jpg alt="Jatropha Leaf Thumbnail">
<dd><img src=jatropha.jpg alt="Jatropha Leaf Large"> A closeup photograph of a Jatropha Hybrid

你的 CSS 也必须做出相应的改变(见清单 3-11 )。

清单 3-11。 CSS 为简单的带标题的图片

dl#gallery dd { position: absolute; left: 200px; top: 2.2em; opacity: 0;
text-align: center; font-family: Futura, Arial, sans-serif; color: white;
transition: .85s opacity linear; }
dl#gallery dd img { display: block; margin: auto; padding-bottom: 1.2em; }

在这种情况下,你的说明会随着图片淡入。将标题与图像分开制作动画也很常见,这将在下一个练习中进行。

改变启动事件

虽然:hover用于启动图库中的大图像的淡入,但对于用户来说,点击缩略图似乎更自然。这里,您遇到了一个问题:在 CSS 中没有与 JavaScript onclick事件处理程序直接对等的东西。然而,在这种情况下有几个选择。

:活动

虽然它与链接紧密相关,但也可以使用:active伪类来启动转换,如清单 3-12 所示。

清单 3-12。 CSS 对鼠标按下产生效果

dl#gallery dt:active + dd { opacity: 1; }

您将立即看到这种方法的主要缺点:只有在缩略图上按住鼠标按钮时,大图像才会出现。

:目标

在这种情况下,使用:target可能是最有效的伪选择器,尽管它确实需要在标记中添加一些内容。:target源自使用传统的id值的“锚”,检测链接到这些 id 的元素的点击。

您的 HTML 更改为清单 3-13 中显示的内容。

清单 3-13。 HTML 为一个图库配:target

<dl id=gallery>
<dt><a href=#jatropha><img src=jatropha_thumb.jpg alt="Jatropha Leaf Thumbnail"></a>
<dd id=jatropha><img src=jatropha.jpg alt="Jatropha Leaf Large"> 
A closeup photograph of a Jatropha Hybrid leaf
<dt><a href=#veins><img src=leaf-veins_thumb.jpg alt="Leaf Veins Thumbnail"></a>
<dd id=veins><img src=leaf-veins.jpg alt="Leaf Veins"> 
Closeup photgraph of leaf veins
<dt><a href=#cascada><img src=cascada_thumb.jpg alt="Cascada Thumbnail"></a>
<dd id=cascada><img src=cascada.jpg alt="Cascada Large"> 
Falls in Dundas Peak, Ontario, Canada
</dl>

在正常情况下,一个锚的链接会迫使页面滚动到id的位置,并有一个视觉跳转;这种情况下可以避免,因为dd元素绝对位于页面顶部附近。

只有一行 CSS 需要修改。您的:hover声明如清单 3-14 中的所示。

清单 3-14。 一个图库用 CSS:target

dd#jatropha:target, dd#veins:target, dd#cascada:target { opacity: 1; }

这种方法还具有修改 URL 的优点,这意味着通过使用带有附加 id 的链接,用户可以被引导到特定的图像。例如,www.yourdomain.com/gallery.html#cascada会自动调出图库中的最后一幅图像。

简单的弹出图像标题

也可以在鼠标悬停时显示图像的标题,可以在图库中显示,也可以作为用户界面的一部分。理想的标记要么是一个定义列表,如前一个例子,要么是一个<figure >和<figcaption>,这是你将在下一个例子中使用的元素,如图 3-3 和清单 3-15 所示。(我用的是布拉德利·戴维斯(www.flickr.com/photos/backpackphotography/244716694/)和沃尔夫冈·斯陶特(www.flickr.com/photos/wolfgangstaudt/)的照片。如果您决定使用自己的图像,请确保它们的大小相似。)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-3。动画图像字幕

在这种情况下,标题是图像的描述,但这种技术也可以用于网站的图形导航(见第四章)。

清单 3-15 。HTML5 图形和图形标题代码

<figure>
        <img src=devils-tower.jpg alt="A photo of Devil's Tower, inWyoming, USA">
        <figcaption> Devil's Tower, Wyoming, USA</figcaption>
</figure>
<figure style=left:550px>
        <img src=sunrise-point.jpg alt="A photo of Sunrise Point, Bryce National Park, Utah, USA">
        <figcaption> Bryce National Park, Utah, USA</figcaption>
</figure>

您将在 CSS 中做一些事情。首先,图像和它们周围的figure元素应该设置为相同的大小,并且并排浮动。您还将在用更多 CSS 隐藏标题之前对其进行样式化。

雷姆:不是乐队

传统上,网页上的字体是以像素、百分比或 ems 来确定大小的。后两种方法通常是首选方法,因为它们具有内在的可伸缩性。由于1em实际上是M字符的宽度,将段落文本放大 20%就像声明p选择器的font-size1.2em一样简单。使用em还可以随着字体大小的增加和减小,方便地按比例调整元素之间的间距。例如,您可以通过以em为单位测量图像的边距来设置图像及其周围文本之间的装订线,从而在正文和插图之间创建一种视觉关系。

在网页中使用em作为度量系统的一个问题是它很复杂,因为单位总是相对于父元素的字体大小来设置*。将li元素的大小设置为1.2em是没问题的,直到你在其中嵌套了一个列表:内部 l i的内容将以1.4em的大小呈现。*

rem (for root em )通过相对于根元素(即html元素)测量自身来解决这个问题。这意味着你可以在html选择器上声明一个单一的字体大小,并相对于它缩放一切,如清单 3-16 所示。

清单 3-16。 为文档调整 rem 字体大小

html { font-size: 62.5% }
body { font-size: 1.4rem; }
h1 { font-size: 2.4rem; }

这也很好地转换为像素:在上面的样式表中,页面上的正文文本大小相当于 14px,而h1元素呈现为 24 像素。

浏览器对 rem 的支持出奇的好:最近所有支持 CSS 转换的浏览器(Safari 5+,Chrome,Firefox 3.6+,IE9+,Opera 11.6+)也都支持rem单元)。

现在让我们来看看图表和标题的基本 CSS(见清单 3-17 )。

清单 3-17。 基本 CSS 为一个图和标题

figure { float: left; }
figure, figure img { width: 500px; height: 333px; }

figcaption {
font-family: Baskerville, "Baskerville Old Face", Garamond, "Times New Roman", serif;
font-style: italic; background: rgba(0,0,0,0.4);
font-size: 2rem; padding: 0.8rem; color: #fff;
}

在这个阶段,页面看起来将类似于图 3-4 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-4。隐藏前带有定位字幕的图像

现在它们已经被样式化了,您将通过在 figure 元素上使用overflow: hidden来隐藏标题。同时,你需要定位标题。对于本例中的图像,从顶部向下放置标题可能看起来最好。有几种可能的方法来定位字幕。我将使用relative定位和一个稍微大于图片高度加上标题高度的bottom值(见清单 3-18 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在添加转场之前检查元素的重定位是否有效是个好主意。

清单 3-18。 CSS 隐藏并定位标题

figure { float: left; }
figure, figure img { width: 500px; height: 333px; overflow: hidden; }
figcaption {
font-family: Baskerville, Garamond, "Times New Roman", serif;
font-style: italic; background: rgba(0,0,0,0.4); font-size: 2rem;
padding: 0.8rem; color: #fff;  position: relative;  bottom: 400px;
}
figure:hover figcaption { bottom: 340px; }

最后,你将添加标题的过渡,如清单 3-19 所示。

清单 3-19。 CSS 到转场一个字幕

figcaption {
font-family: Baskerville, Garamond, "Times New Roman", serif;
font-style: italic; background: rgba(0,0,0,0.4);
font-size: 2rem; padding: 0.8rem; color: #fff;
position: relative;  bottom: 400px;
transition: 2s all; }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意我已经通过使用描述性文件名和 alt 属性值来保持我们的图像的可访问性。这是非常重要的:永远记住,不是每个人都能够看到你的设计或与之互动。

图像牌叠和扇形显示

随着网页变得越来越复杂,它们变得越来越难以概括和说明。如果你创建了一个大的图库页面,很难只选择一张图片来激发访问者的兴趣。一个可能的解决方案是使用几个图像,显示在一个关键帧滑块画廊(如第五章所示)或一个交互式显示器中。在这种情况下,我会将几张照片明显地堆叠在一起,在鼠标悬停时显示它们,以产生更大的兴趣和对链接内容的理解(参见图 3-5 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-5。一种动画卡牌粉丝效果

同样,您将使用相同大小的图像来产生最佳效果,如清单 3-20 所示。

清单 3-20 。动画图像的 HTML】卡扇效果

<div id=cardfan>
        <img src=bike.jpg alt="A photograph of a bicycle parked on Italian street">
        <img src=florence.jpg alt="A photograph of bridge in Florence, Italy">
        <img src=roma.jpg alt="A photograph of a ruined aqueduct outside Rome">
</div>

您已经将图像包装在一个容器元素中,使它们更容易通过 CSS 引用和控制。div和它包含的图像大小相同。当样式化和堆叠里面的图像时,你也将使容器居中对齐页面(见清单 3-21 )。

清单 3-21 。 基本 CSS 为一卡一扇效果

#cardfan, #cardfan img { width: 640px; height: 480px; }
#cardfan { margin: 0 auto; }
#cardfan img { border: 32px solid #ffe;
box-shadow: 12px 12px 10px rgba(0, 0, 0, 0.2);
position: absolute; }

您希望当用户将鼠标悬停在图像上时,图像呈扇形展开;你可以通过使用:first-child:last-child伪类将堆栈中的第一个最后一个图像旋转 12 度来实现,如清单 3-22 所示。

清单 3-22 。 卡片叠中第一张和最后一张图片的旋转效果

#cardfan:hover img:first-child {
    transform: rotate(12deg);
}
#cardfan:hover img:last-child {
    transform: rotate(−12deg);
}

清单 3-22 中的代码将产生如图图 3-6 所示的图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-6。使用 CSS 变换围绕各自中心旋转的堆叠图像

如你所见,图像围绕其中心旋转。在这种情况下,您希望图像稍微成扇形,因此您需要将变换轴移动到图像的下方(参见清单 3-23 )。

**清单 3-23 。偏移图像的变换原点

#cardfan img { border: 32px solid #ffe;
    box-shadow: 12px 12px 10px rgba(0, 0, 0, 0.2);
    position: absolute;
    transform-origin: center 600px;
}

清单 3-23 中的代码将产生如图图 3-7 所示的输出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-7。围绕偏移原点旋转的堆叠图像,用十字光标高亮显示

现在你可以真正地将卡片展开,同时应用一个过渡,如清单 3-24 所示。(请注意,我已经更改了一些值来增加风扇效果。)

清单 3-24 。 全 CSS 为动画卡粉丝图库

#cardfan, #cardfan img { width: 640px; height: 480px;
transition: .6s transform ease-out;
}
#cardfan { margin: 0 auto; }
#cardfan img { border: 32px solid #ffe;
box-shadow: 12px 12px 10px rgba(0, 0, 0, 0.2);
position: absolute;
transform-origin: center 1200px;
}
div#cardfan:hover img:first-child {
    transform: rotate(24deg);
}
div#cardfan:hover img:last-child {
    transform: rotate(−24deg);
}

你也可以将图片链接到一个图库页面,如清单 3-25 所示。

清单 3-25 。 一联卡粉丝图库

<div id=cardfan>
 <a href=gallery.html>
 	<img src=bike.jpg alt="A photograph of a bicycle parked on Italian street">
 	<img src=florence.jpg alt="A photograph of bridge in Florence, Italy">
 	<img src=roma.jpg alt="A photograph of a ruined aqueduct outside Rome">
 </a>
</div>

如果您想旋转第一个和第二个图像,并保持顶部的照片不变,请更改以下选择器:

div#cardfan:hover img:last-child

div#cardfan:hover img:nth-child(2n)

你也可以稍微旋转图像的默认位置,让用户对将要发生的事情有所了解,如清单 3-26 所示。

清单 3-26 。 一个视觉上有暗示的卡迷图库

#cardfan img:first-child {
    transform: rotate(6deg);
}
#cardfan img:nth-child(2n) {
    transform: rotate(−6deg);
}

你也可以将照片单独链接到本章开头的图库示例(见清单 3-27 )。

清单 3-27 。

<div id=cardfan>
<a href="gallery.html#bike">
    <img src=bike.jpg alt="A photograph of a bicycle parked on Italian street">
</a>
<a href="gallery.html#florence">
    <img src=florence.jpg alt=="A photograph of bridge in Florence, Italy">
</a>
<a href="gallery.html#aqueduct">
    <img src=roma.jpg alt="A photograph of a ruined aqueduct outside Rome">
</a>
</div>

但是,如果您单独链接图像,您将需要更改您的 CSS,因为您的标记的组织已经发生了变化。你将通过它们的src属性的值来引用图像,而不是将它们作为子对象来引用(参见清单 3-28 )。

清单 3-28 。 一个卡片爱好者图库,图片被其 src 属性引用

#cardfan img[src="bike.jpg"] {
    transform: rotate(6deg);
}
#cardfan img[src="roma.jpg"] {
    transform: rotate(−6deg);
}
#cardfan:hover img[src="bike.jpg"] {
    transform: rotate(24deg);
}
#cardfan:hover img[src="roma.jpg"] {
    transform: rotate(−24deg);
}

注意清单 3-26 中的技术没有为你的图像创建和引用 id 值灵活:如果你因为任何原因改变了文件名,你将不得不相应地改变你的 CSS。

你也可以在鼠标悬停时将单个图像提升到前景(见清单 3-29 )。

清单 3-29 。 一个卡迷图库的图像提升到前台

img[src="bike.jpg"]:hover, img[src="florence.jpg"]:hover { z-index: 2; }

通过使用::before::after伪元素选择器来生成其他图像,您可以编写更少的标记(但稍微多一点 CSS)。(请注意,您不能在<img >标签上使用生成的内容,因为它们是替换元素的一种形式)。同样重要的是要注意,这种方法实际上扼杀了可访问性,因为大多数屏幕阅读器目前不访问生成的内容,JavaScript 也不能访问它。这里显示的技术是一种有趣的可能性,而不是作为一种网站中心内容的生产方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意 替换的元素是 HTML 元素,有固有的宽度和高度,没有 CSS 的好处;也就是说,任何产生占位符的标记,其内容随后被外部资源替换。例如,当您使用<input type =text>时,文本框会以适合单行文本输入的大小出现。这并不意味着你不能应用 CSS 来调整它的大小,只是默认情况下浏览器用预定大小的元素替换了<input>标签的实例。<img>也是如此;如果没有 CSS,图像会以其自然的宽度和高度加载到页面上。

<br>, <img>, <video>, <iframe>, and <object>are all replaced elements, as are <input>, <button>, and <textrarea>.

最重要的是,在这个练习的上下文中,作为一般规则,*生成的内容不能应用于替换的元素。*也就是说,你不能在<img>或者上面列出的其他标签上使用::before或者::after。此外,不能转换内联元素,除非它们也是被替换的元素。

走这条路,你的 HTML 和 CSS 代码简化成你在清单 3-30 中看到的样子。

清单 3-30 。 HTML 和 CSS 代码为一张卡片生成粉丝效果图

<div id=cardfan>
        <img src=florence.jpg alt="A photograph of bridge in Florence, Italy">
</div>
#cardfan { position: relative; margin: 0 auto; }
#cardfan, #cardfan img, #cardfan img:before, #cardfan img:after {
    width: 640px; height: 480px;
}
#cardfan img, #cardfan:before, #cardfan:after {
    border: 32px solid #ffe;
    box-shadow: 12px 12px 10px rgba(0, 0, 0, 0.2);
    position: absolute;
    transform-origin: center 1200px;
}
div#cardfan::before { content: url(bike.jpg); }
#cardfan::after { content: url(roma.jpg); }
#cardfan::before, div#cardfan:after { position: absolute; left: 0; top: 0; }
#cardfan::before { transform: rotate(6deg); }
#cardfan::after { transform: rotate(−6deg);  }

清单 3-30 中的代码创造了同样的卡迷效果,可以说具有更强的适应性;要更改中心图像两侧的照片,只需修改 CSS,而无需修改标记。如前所述,这种方法也有明显的缺点。

你可以通过链接伪选择器来制作这些图像的动画,如清单 3-31 所示。

清单 3-31 。 CSS 代码动画生成内容

div#cardfan:hover::before {
    transform: rotate(24deg);
}
div#cardfan:hover::after {
    transform: rotate(−24deg);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 为什么::before::after中的双冒号?CSS2 和 CSS2 之间对现有选择器的少数正式更改之一是 W3C 在生成的内容选择器中添加了另一个冒号,以便区分它们的不同性质。现代浏览器将会识别并支持:::前置到生成的内容选择器。在本书中,我使用了新的正式版本;为了更好地向后兼容旧的浏览器,您可能希望只使用一个冒号。

具有不同进入和退出效果的快板图像字幕

虽然从顶部或底部引入图像标题适用于短文本,但当涉及大量文本时,过渡会有点大且笨拙。如果标题文本很长,最好在悬停时“摆动”它。

你将使用与之前相同的方法:一张已知尺寸的图像(由美国宇航局提供),使用overflow: hidden隐藏标题,直到你在悬停时显示它(见图 3-8 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-8。快板字幕动画

图 3-8 所示的快板标题的 HTML 和 CSS 如清单 3-32 所示。

清单 3-32 。 代码创建一个快板标题

<figure class=clapperboard> 
  <img src=apollo-17.jpg alt="Photograph of astronaut on the Moon">
<figcaption>
<q>We leave as we came and, God willing, as we shall return, with peace and hope...</q> 
– Eugene Cernan, commander of Apollo 18, the last man on the moon.
</figcaption>
</figure>
figure.clapperboard { position: relative; }
figure.clapperboard figcaption { position: absolute; top: 0; left: 0; padding: 2rem; }
figure.clapperboard, figure.clapperboard figcaption { width:618px;height:515px; }
figure.clapperboard figcaption q { font-size: 2rem; display: block; margin-bottom: 2rem; }

你还没有隐藏标题,这使得它更容易定位:你需要将figcaption元素旋转 90 度,使其右下角与图像的角相匹配(见图 3-9 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-9。图和旋转的标题,突出显示重新定位的变换原点

在图 3-9 中定位标题的代码可以在清单 3-33 中看到。(注意,我使用了 CSS3 box-sizing属性来确保添加填充后figcaption保持正确的宽度和高度。)

清单 3-33 。 CSS 代码来定位一个快板标题

figure.clapperboard figcaption { font-family: Futura, Arial, sans-serif;
font-weight: 100; font-style: italic; color: black;
box-sizing: border-box;
font-size: 1.2rem; padding: 2rem; padding-top: 8rem;
border: 2px solid black;
transform-origin: bottom right; transform: rotate(90deg);
}

现在标题在正确的位置,你可以关闭border,设置overflowhidden,并反转颜色(见清单 3-34 )。

清单 3-34 。 CSS 代码来定位一个拍板的标题

figure.clapperboard, figure.clapperboard figcaption {
    width:618px;height:515px;
    overflow: hidden;
}
figure.clapperboard figcaption {
    font-family: Futura, Arial, sans-serif;
    font-weight: 100; font-style: italic; color: white;
    font-size: 1.2rem; padding: 2rem; padding-top: 8rem;
    box-sizing: border-box;
    background: rgba(0,0,0,0);
    transform-origin: bottom right;
    transform: rotate(90deg);
}
figure.clapperboard:hover figcaption {
    transform: rotate(0);
}

要使这成为一个动画过渡,请将以下内容添加到figure.clapperboard figcaption声明中:transition: transform 2s cubic-bezier(.12,.49,.17,.87);.

(注意,通过使用适当的属性,您将转换限制为仅仅跟踪转换:这不仅更有效,而且当您在六个月后再次使用它时,更容易跟踪代码。。。同时避免仅仅因为在字幕的默认状态和旋转状态之间改变了某些东西而出现意外的转换)。

虽然这种方法可行,但仍然存在一些问题。例如,在宇航服和月亮的背景下,文本确实不够清晰,所以你会想给figcaption添加一些text-shadowbackground

清单 3-35。 改进了快板字幕过渡的代码

figure.clapperboard figcaption {
    font-family: Futura, Arial, sans-serif;
    font-weight: 100; font-style: italic; color: white;
    font-size: 1.2rem; padding: 2rem; padding-top: 8rem;
    box-sizing: border-box;
    background: rgba(0,0,0,0.6);
    text-shadow: 3px 3px 1px rgba(0,0,0,0.6);
    transform-origin: bottom right;
    transform: rotate(90deg);
    transition: transform 2s cubic-bezier(.12,.49,.17,.87);
}

这对于文本的易读性来说是一个显著的改进,但是背景边缘下降的方式看起来仍然有点奇怪。有几个可能的解决方案:一个是使figcaption更宽,把文本推到右边,把figcaption本身推到左边,这样盒子看起来更像一个视觉“切片”效果(清单 3-36 )。

清单 3-36 。 改进了快板字幕过渡的代码

figure.clapperboard figcaption {
    width: 1236px; height:515px;
    font-family: Futura, Arial, sans-serif;
    font-weight: 100; font-style: italic; color: white;
    font-size: 1.2rem; padding:
    padding: 8rem 2 rem 0 660px;
    box-sizing: border-box;
    background: rgba(0,0,0,0.6);
    text-shadow: 3px 3px 1px rgba(0,0,0,0.6);
    transform-origin: bottom right;
    transform: rotate(90deg);
    left: -618px;
    transition: transform 2s cubic-bezier(.12,.49,.17,.87);
}

在这种情况下,我将figcaption的宽度增加了一倍,并从左侧填充内容,使其覆盖图像的相同部分。通过改变figcaption框的位置和元素变换原点的位置,你会发现创建许多不同种类的效果是可能的。

创建单独的过渡序列

创建字幕过渡的另一种方法是在文本旋转到位后,淡入字幕背景*。这需要设置两个独立属性的动画,并延迟其中一个属性,直到第一个属性完成。默认情况下将figcaptionbackground设置为完全透明可以启动这个过程,然后用逗号分隔过渡效果,并为一组值添加延迟。参见图 3-10 中的示例。*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-10。扩展 figcaption,获得更好的隔板字幕过渡效果。(溢出:为了便于说明,隐藏被关闭,颜色被反转,并且添加了边框。)

清单 3-37 展示了完整的 CSS 代码。

清单 3-37 。 用于快板标题的 CSS 代码

figure.clapperboard { position: relative; overflow: hidden; }
figure.clapperboard figcaption { position: absolute; top: 0; left: 0; padding: 2rem; }
figure.clapperboard, figure.clapperboard figcaption { width:618px;height:515px; }
figure.clapperboard figcaption {
    font-family: Futura, Arial, sans-serif; font-weight: 100; font-style: italic;
    color: white;  font-size: 1.2rem; padding: 2rem; padding-top: 8rem;
    box-sizing: border-box; background: rgba(0,0,0,0);
    text-shadow: 3px 3px 1px rgba(0,0,0,0.6);
    transform-origin: bottom right; transform: rotate(90deg);
}
figure.clapperboard:hover figcaption {
    transform: rotate(0);
    opacity: 1;
    background: rgba(0,0,0,0.6);
    transition: transform 2s cubic-bezier(.12,.49,.17,.87), background .9s linear 2.2s;
}
figure.clapperboard figcaption q { font-size: 2rem; display: block; margin-bottom: 2rem; }

你会注意到,在文本旋转到位后,背景会在 200 毫秒内消失。剩下的一个问题是,当用户将鼠标从图像上移开时,标题会立即消失,这导致了我在《??》第二章中引入转场时遇到的同样问题。将figcaption的转换代码移动到默认状态将意味着转换将在 mouseout 上反转,这看起来也有点奇怪。理想情况下,你想要的是让figcaption以不同于它出现时的方式消失。

改变退出事件

为了达到这个效果,你将制作三个属性的动画:opacitytransformbackground。您将明确地将转换划分为单独的组件,以便于跟踪。每次指定属性的顺序必须相同,此效果才能生效。

然而,首先,您将把opacity添加到各种状态中(清单 3-38 )。

清单 3-38 。 改进了用于快板标题的 CSS 代码

figure.clapperboard figcaption {
    opacity: 0;
...
figure.clapperboard:hover figcaption {
    opacity: 1;
...

现在这没有任何区别,因为标题在默认状态下是不可见的,因为figure元素上有overflow: hidden。但是稍后会有所不同,你很快就会看到。

接下来,你将分解不同的动画组件(清单 3-39 )。

清单 3-39 。 为快板标题的 CSS 代码

figure.clapperboard:hover figcaption { transform: rotate(0); opacity: 1;
    transition-property:         opacity,    transform,                              background;
    transition-timing-function:     ease,         cubic-bezier(.12,.49,.17,.87), linear;
    transition-duration:                 0s,           .9s,                      1s;
    transition-delay:                      0s,            0s,                    1s;
 }

它有助于将转换更改作为列来阅读,这就是为什么我在代码中添加了不必要的空格。在这种情况下,opacity没有计时功能,没有持续时间,也没有延迟(意味着它立即生效),而background具有线性计时功能,持续一秒,延迟一秒(意味着它在文本旋转到位后生效)。

现在到了figcaption的默认状态(清单 3-40 )。

清单 3-40 。 为快板标题的 CSS 代码

figure.clapperboard figcaption {
opacity: 0;
transition-property:                 opacity,   transform,               background;
transition-timing-function;     linear,      ease,                        linear;
transition-duration:                 2s,           9999999s,                0s;
transition-delay:                      0s,           0s,                    0s;
...

这些效果发生在从转换回默认状态的过程中,在两秒钟内将figcaption的不透明度设置回 0。你可能想知道为什么自转会持续不到 1000 万秒。这个高得离谱的数字是适当的,因此将figcaption转换回默认方向(即侧身站立)实际上具有无限的持续时间。从视觉上看,这意味着当用户将鼠标从图像上移开时,文本不会发生任何旋转:标题只是保持静止并淡出。

背景图像过渡和页面加载动画

为了说明页面加载的转变,您将创建一个新西兰在线旅游指南页面(参见图 3-11 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-11。过渡背景图像

当页面加载时,您希望几张图片从页面的一边滑到另一边。在这个例子中,我将使用车红(www.flickr.com/photos/chleong/6867222762/)、安德里亚斯·比克(www.flickr.com/photos/kiwiwings/2148854337/sizes/l/in/photostream/)、戈登·瑞格里(www.flickr.com/photos/tolomea/4498923741/sizes/l/in/photostream/)和大卫·普尔斯豪斯(www.flickr.com/photos/mdid/2235443912/sizes/l/in/photostream/)的照片。

首先,你将设置你的基本页面,其标记在整个练习中将保持不变(见清单 3-41 )。请注意,图像从页面左侧偏移其宽度(1300 像素)加上一个增量,在水平方向上交错排列。

清单 3-41 。 HTML 和 CSS 代码,用于页面加载时的后台过渡

<div id=wrapper>
<h1> New Zealand</h1>
<p> Lorem ipsum dolor sit amet....
</div>
body { font-family: Futura; margin: 0; line-height: 200%;
background:
    url(lake-benmore-new-zealand-panorama.jpg) -1300px 200px no-repeat,
    url(lake-tekapo-new-zealand-panorama.jpg) -2000px 600px no-repeat,
    url(new-zealand-panorama.jpg) -3900px 1000px no-repeat,
    url(lindis-pass-new-zealand-panorama.jpg) -1300px 1300px no-repeat;
}
div#wrapper { width: 600px; margin: 5em auto; padding: 3em; }

不幸的是,CSS 中还没有background-opacity属性;在保存图像之前,您必须在 PhotoShop 中淡出图像,或者在图像经过文本下方时,采取其他措施来保持文本的易读性。首先,通过应用background: rgba(255, 255, 255, 0.8);,给div添加一个部分透明的background-color

加载背景图像时制作动画

用 CSS3 关键帧开始这样的动画是最容易的(在第五章中讨论过),但是通过在主体上放置一个伪类,只使用过渡也可以达到类似的效果。为了演示这个概念,您将向您的 CSS 添加一个新的声明(清单 3-42 )。

清单 3-42 。 CSS 代码用于页面加载时的背景过渡

body:hover {
background:
    url(lake-benmore-new-zealand-panorama.jpg) calc(100%+1300px) 200px no-repeat,
    url(lake-tekapo-new-zealand-panorama.jpg) 2400px 600px no-repeat,
    url(new-zealand-panorama.jpg) 2400px 1000px no-repeat,
    url(lindis-pass-new-zealand-panorama.jpg) 2400px 1300px no-repeat;
    transition: 70s all linear;
}

假设浏览器窗口宽度小于 2400 像素,这会将图像设置在屏幕的最右侧。(现在做出一个合理的假设,但长期来看是危险的:更好的解决方案是在完全支持 CSS3 变量或 calc 后使用它们。)

这种方法有三个缺点:第一个也是最严重的一个缺点是,当用户的鼠标移出浏览器窗口时,图像会重置到屏幕左侧的默认位置。您可以通过将转换代码移动到默认的身体状态来稍微缓解这个问题,这样当用户的鼠标移开时,转换将开始反转。

第二个问题是所有的背景图像必须作为一个组一起被动画化;使用这种方法无法单独过渡图像。

CALC 是什么?

虽然在这种情况下技术上没有必要,但我在清单 3-42 中的声明中使用了calc作为展示一个令人兴奋的新属性的手段。calc非常接近 CSS3 变量的概念(另一个新的 CSS3 模块),允许我们将任何长度值指定为算术表达式。在清单 3-42 的例子中,计算只是简单地将当前元素的宽度加到它的父元素(??)上,这样当页面加载时,图像就能保证不在屏幕上。

你可以在https://hacks.mozilla.org/2010/06/css3-calc/阅读更多关于calc的内容。

最后一个不太严重的问题是,当背景图像移动到div后面时会突然褪色。这个问题有两个显而易见的解决方案:

  • 使用与divbackground同色的双box-shadow和高模糊量来模糊div的左右边缘,如清单 3-43 所示。

清单 3-43 。 CSS 代码模糊背景图片的过渡

div#wrapper { width: 600px; margin: 5em auto;
    padding: 3em;
    background: rgba(255, 255, 255, 0.8);
    box-shadow: 100px 0 100px  rgba(255, 255, 255, 0.8),
    -100px 0 100px  rgba(255, 255, 255, 0.8);

}

  • 扩展div以覆盖整个身体,这样它后面的所有东西都会被淡出。如清单 3-44 中的所示设置开始声明。

清单 3-44 。 CSS 代码强制整个页面背景图片的不透明度

html, body { min-height: 100%; margin: 0; }
html, body { height: 100%; margin: 0; }
div#wrapper { width: 100%; min-height: 100 %;
    padding: 3em;
    box-sizing: border-box; background: rgba(255, 255, 255, 0.8);
}

创建假背景图像并制作动画

如果您希望对背景图像有更大程度的控制,您必须通过利用positionz-index CSS 属性将图像强制放入背景中来伪造它们。有两种主要方法可以做到这一点。第一个是创建真实的图像,并把它们放在背景中。

这种技术不是通过 CSS 绘制背景图像,而是将它们作为图像放在代码中的上方、下方,甚至是在div ( 清单 3-45 )内部。

清单 3-45 。 HTML 和 CSS 代码为页面创建假背景图片

<img src=lake-benmore-new-zealand-panorama.jpg alt="Lake Benmore, New Zealand" id=benmore>
<img src=lake-tekapo-new-zealand-panorama.jpg alt="Lake Tekapo, New Zealand" id=tekapo>
<img src=lindis-pass-new-zealand-panorama.jpg alt="Lindis Pass, New Zealand" id=lindis>
#benmore, #tekapo, #lindis { position: absolute; z-index: -1; }
#benmore { top: 300px; left: 200px; }
#tekapo { top: 600px; left: 800px; }
#benmore, #tekapo, #lindis {
    position: absolute; z-index: -1; opacity: 0; transition: 4s linear all 2 s; }
#lindis { top: 900px; left: 50px; }

作为单独的图像,这些元素可以跨所有属性单独设置动画。为元素提供一个负的z-index将它们推入深层背景。它们在清单 3-46 中以与之前练习中相同的方式被制作成动画。

清单 3-46 。 动画假背景图片

body:hover img#benmore, body:hover img#tekapo, body:hover img#lindis { opacity: 0.6;  }

同样,如果您希望序列不管用户活动如何都循环播放,您通常会使用关键帧动画。

或者,您可以通过使用生成的内容来创建相同的效果。这样做的优点是不需要额外的标记,但是限制了两个添加的元素(一个通过使用:before生成,一个通过使用:after)。如前所述,给定z-indexopacity,这些元素也可以被转换。

摘要

在这一章中,你已经学习了如何使用带有不透明度的 CSS3 过渡和 CSS4 交叉淡入淡出来交叉淡入淡出两幅图像。您还创建了一个简单的图片库(在许多站点环境中都很有用),并通过过渡逐渐增强了图片库。我已经向您展示了如何使用几个不同的伪选择器(:target:active:hover),)来启动这些转换,其中的每一个都将适用于特定的演示。

您已经为图像的标题制作了动画,并且在这个上下文中,移动了变换轴以创建“偏移”旋转。

过渡模块有几种延迟序列以创建分层动画效果的方法,从简单的(transition-delay)到诸如提供极高的时间值以有效地将过渡元素永久保持在适当位置的技巧。您可以使用这些相同的技术在过渡元素中创建不同的入和出效果,这些效果通常只是按照它们出现时的动画顺序进行反转。

最后,您已经将过渡推进到了大多数开发人员很少涉足的领域:生成内容的动画和页面加载时移动的背景图像。

在下一章,我将向你展示如何将 CSS3 过渡应用到网站导航和其他用户界面功能中。

四、UI 元素的 CSS3 过渡

CSS3 transitions 的另一个明显的作用是增强网页中的用户界面元素:在导航、表单和按钮中构建动画,使网站上的信息更清晰、更吸引人。在这一章中,我将学习到目前为止你已经探索过的动画原理和 CSS 语法,并在课程中对它们进行扩展,这将使你的设计更具互动性、更有趣、更好玩。

现代网站导航标记

在你的站点导航中添加过渡之前,花点时间研究一下你将把 CSS 规则挂入的标记是值得的。对于 HTML5 网站,主导航应该位于一个<nav>元素中。为了确保与屏幕阅读器的兼容性,您将在标签中添加一个 ARIA 导航角色,如清单 4-1 所示。

清单 4-1 。 最小 HTML5 站点导航结构

<nav role=navigation>
<a href=index.html>Home</a>
<a href=about.html>About Us</a>
<a href=products.html>Products</a>
</nav>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 您可以在www.w3.org/TR/wai-aria-practices/了解更多关于 ARIA 地标角色的信息。

如您所见,HTML5 允许您在nav元素中放置一系列简单的站点链接。但是,您可能会发现,添加标记增加了导航的语义价值,同时允许您以更大的灵活性修改其外观。在大多数情况下,站点导航可以被视为一个无序列表;或者,如果希望用户以特定的顺序阅读页面,您可能希望使用有序列表。

无论您选择哪种方法,键盘快捷键也应该通过accesskey属性添加到主链接中,如清单 4-2 所示。(注意,role属性已经移动到无序列表中。)

清单 4-2 。 一个易访问的站点导航代码结构

<nav>
<ul role=navigation >
<li><a href=index.html accesskey=1>Home</a>
<li><a href=new-xyz-corp.html accesskey=2>What's New</a>
<li><a href=about-xyz-corp.html accesskey=a>About Us</a>
<li><a href=contact-xyz-corp.html accesskey=6>Contact Us / Help</a>
</ul>
</nav>

这是你将在本章中构建的每一个主要导航界面的基础。为了节省空间,您并不总是需要包含完整的辅助功能,但是在最终的产品代码中使用这些功能是非常重要的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意在某些情况下,对于 CSS 规则的某些组合,如果链接在水平排列的<li>元素中,它们之间可能会出现微小的视觉间隙(如清单 4-3 )。虽然无论如何格式化都希望保留您的代码——与 HTML 相反,HTML 将所有连续的空格字符折叠成一个空格,回车符计为一个空格,除非内容包含在<pre>标签中——但是找出这些差距的原因可能会非常令人沮丧。

The issue lies not with the CSS, but with the HTML, in the form of carriage returns between each list item. While CSS solutions to this problem exist (setting font-size: 0 on the parent element, for example, or floating the list item elements), the best option is usually to remove the carriage returns, placing all of the list items in a single line, as shown in Listing 4-3.

清单 4-3 。 一个无障碍的站点导航代码结构,没有多余的空格

<nav>
<ul role=navigation><li><a href=index.html accesskey=1>Home</a><li><a href=new-xyz-←
corp.html accesskey=2>What's New</a><li><a href=about-xyz-corp.html accesskey=a>About←Us</a><li><a href=contact-xyz-corp.html accesskey=6>Contact Us / Help</a></ul>
</nav>

`For the sake of clarity I will not be using this solution in the code samples to come, but you should be aware of the potential problem and its solution.

不管它们是否用一行代码编写,用有序或无序列表构建的导航结构都会在单独的一行上显示每个链接。要创建水平导航栏,您必须在 CSS 中添加一个内容。

水平导航栏基础知识

当网站相对较小时,通常使用水平导航界面。(下拉菜单条是这个规则的一个例外,我将很快介绍它。)

“神奇的数字 7,加或减 2”是确定导航结构的有效经验法则:平均而言,人类在任何时候都可以回忆或联系到多达 7 个项目。导航中超过七个条目通常意味着你需要重新考虑 UI(用户界面)——分块或者将相关条目组合在一起通常可以解决问题。根据屏幕的宽度,你通常也可以在一个导航浏览器窗口中水平放置七个导航项目;非常窄的窗口(比如在移动设备上)或者超过七个主链接通常需要垂直方向的导航格式。

链接是自动内联显示的,所以几乎不需要添加 CSS 来使它们在水平导航栏中看起来有组织。如果您已经将链接包装在<li>标签中,那么几乎没有什么工作要做:只需将清单 4-4 中的声明添加到您的样式表中。

清单 4-4 。从一个 HTML5 导航结构创建一个水平导航条

nav li { display: inline; }

现在您已经为最常见的站点导航格式建立了基本的标记,您可以继续使用 CSS3 来增强它们。

用 CSS3 增强的简单导航栏

让我们从清单 1-1 中选取最简单的导航标记,并在导航栏后面放置一个background-image。您将可视化地格式化文本,以便通过添加a text-shadow and a hover effect仍然可以阅读,如清单 4-5 所示。

清单 4-5 。从一个 HTML5 导航结构创建一个水平导航条

nav { background: url(img/clouds.jpg) no-repeat; padding: 1em 0; }
nav a { text-decoration: none; color: #fff; padding: 1em;
font-family: Futura, Arial, sans-serif;
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.6); }
nav a:hover { background: rgba(0, 0, 0, 0.7); }

然后,你将添加一个简单的过渡,通过调整清单 4-6 中的选择器,来淡入一个悬停链接后面的背景。

清单 4-6 。 使用 CSS3 给链接引入过渡效果

nav a { text-decoration: none; color: #fff; padding: 1em;
font-family: Futura, Arial, sans-serif;
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.6);
-webkit-transition: background .85s ease-in-out;
-moz-transition: background .85s ease-in-out;
-o-transition: background .85s ease-in-out;
transition: background .85s ease-in-out;
 }

最后,做一点安全检查:任何时候你把一张图片放在一个元素的背景中,你都应该设置一个代表图片主色的background-color,以防图片无法加载。修改nav声明,如清单 4-7 所示,确保链接的文本在任何情况下都清晰可辨。

清单 4-7 。 创建一个 CSS 背景色作为图片的退路

nav { background: url(img/clouds.jpg) #007 no-repeat; padding: 1em 0; }

您还可以使用nav a:visited作为选择器,对用户之前访问过的链接应用不同的外观。如清单 4-8 所示,当鼠标悬停在这样的链接上时,你甚至可以创建一个不同颜色的过渡。

清单 4-8 。 为访问过的链接创建单独的效果

nav a:visited:hover {
background: #f00;
background: rgba(255, 0, 0, 0.7);
}

过渡效果仍将应用于已访问的链接,但它们将褪色为红色,而不是黑色。这将产生如图 4-1 所示的菜单。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-1。具有动画悬停效果的导航栏

以这种方式添加 CSS3 完全向后兼容旧的浏览器。如果浏览器不支持过渡,用户只会在当前悬停的链接后面看到部分透明的背景。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示想象只支持 CSS 2.1 的旧浏览器的行为的最简单的方法是记住,它们对任何过渡都施加了一个持续时间0。顺便说一下,这就是为什么transition-durationtransition property的默认值分别是0all

如果您想确保更好的跨浏览器兼容性,您可以在声明的rgba部分之前为悬停的链接添加一个后退的黑色(#000背景。理解rgba的浏览器会遵循最后一条规则;那些没有的将遵循十六进制颜色。淡入仍然可以工作,并且在支持它的浏览器中正确显示。

在导航中高亮显示当前页面

在导航栏中突出显示用户的当前页面是有问题的。CSS 不知道应用的内部状态——它不知道*在哪里。*你可以通过在body标签上为每个页面上的自引用链接创建一个classdata属性或id来避免这个问题,允许 CSS 匹配选择器,如图图 4-2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-2。高亮显示当前位置的导航栏

从清单 4-9 中的代码开始。

清单 4-9 。 在网站导航条上标记出“你在这里”的视觉效果

index.html:

<body id=home>
<nav role=navigation>
<a href=index.html class=home>Home</a>
<a href=about.html class=about>About Us</a>
<a href=products.html class=products>Products</a>
</nav>
about.html:
<body id=about>
<nav role=navigation>
<a href=index.html class=home>Home</a>
<a href=about.html class=about>About Us</a>
<a href=products.html class=products>Products</a>
</nav>

定位表示当前页面的链接是一个简单的过程,将一系列后代选择器分组,如清单 4-10 所示。

清单 4-10 。 CSS 高亮显示当前页面链接

#home nav a.home, #about nav a.about { background: rgba(0,0,212,0.6);}

也可以通过在每个页面上嵌入一个单独处理每个链接类的样式表来达到这种效果。这两种方法都有相同的缺点:它们需要为每个页面定制标记。更好的解决方案可能是 CSS 和 JavaScript 的结合(这里以 JQuery 的形式显示)。

HTML 返回到开始时的样子(清单 4-1 ),你的样式表简单地加入一个新类,如清单 4-11 所示。

清单 4-11 。 CSS 通过 JavaScript 突出显示“你在这里”链接

a.current { background: rgba(0,255,0,0.7); }

在每个文档的head中,你包含了清单 4-12 中的代码。

清单 4-12 。 JavaScript 将“你在这里”类应用到站点导航中

<script src=//code.jquery.com/jquery.min.js></script>
<script>
$(document).ready(function(){
$('ul[role="navigation"] a').each(function() {
if (this.href === window.location.href){ $(this). addClass('current');}
});
})
</script>

在下一节将要创建的更高级的导航示例中,您可以使用这些方法中的任何一种来突出显示当前页面。

带有 CSS3 过渡的水平标签导航

作为站点导航的一个更高级的例子,你可以在“标签”导航中包含移动。在这种情况下,你将把链接放在一个有序列表中以提供更多的结构,就像你在清单 4-2 中所做的那样。按照清单 4-13 中的,你将通过并排设置链接,在它们的右上角和左上角添加一个border-radius,并在每个标签的背景中放置一个渐变来创建标签的视觉效果。这将产生如图 4-3 中所示的菜单。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-3。动画标签导航系统

在这个例子中,您将使用一个属性选择器来访问列表项和链接。

清单 4-13 。 CSS 将导航链接样式化为选项卡

ul[role=navigation] li {
display: inline; font-family: Futura, Arial, sans-serif;
text-transform: uppercase;
}
ul[role=navigation] li a {
text-decoration: none; color: #fff;
padding: 0.8rem 1.2rem 2rem 1.2rem;
border: 1px solid #777; border-radius: 5px 5px 0 0;
background: linear-gradient(to bottom, #dfc891, #776c51);
box-shadow: 0 0 15px rgba(0,0,0,0.5);
letter-spacing: 0.15rem; text-shadow: 0 1px 0 #000;
}

接下来,您需要稍微重叠选项卡。您可以通过为每个列表项提供一个负数margin-left来实现。鼠标经过时标签会上移,所以你故意把它们做得比正常状态下要长。使用无序列表上的overflow: hidden隐藏底部边缘的多余部分,如清单 4-14 所示。

清单 4-14 。 CSS 将导航链接样式设置为选项卡

ul[role=navigation] {
background: #000;  padding-top: 3.2rem; padding-bottom: 1rem;
overflow: hidden; margin-top: 0; }
ul[role=navigation] li {
display: inline; font-family: Futura, Arial, sans-serif;
text-transform: uppercase; margin-left: -.5rem;  }

代表当前页面的链接将应用一个类forefront。这个类通过使用负的topposition: relative和修改后的z-index ( 清单 4-15 ),将适当的链接放在所有其他选项卡之上,并且比其他选项卡略高。

清单 4-15 。 将当前页面的链接放置在其他页面的顶部

ul[role=navigation] li a.forefront { -0.2rem; z-index: 2;}

您可以使用已经讨论过的任何一种方法来应用这个类:将它添加到标记中,或者用 JavaScript 动态地应用它。最后,你将在悬停时通过提升链接的顶部位置来提升链接,并将默认状态的转换动画化(清单 4-16 )。

清单 4-16 。 制作标签页链接动画

ul[role=navigation] li a {
position: relative; top: 0;
transition: 0.2s all linear;
...
}
ul[role=navigation] li a:hover,  ul[role=navigation] li a:focus {
top: -0.6rem;
}

HTML5 表单自定义验证错误动画

用户输入表单的信息通常至少要检查两次:一次在前端(通常用 JavaScript),一次在后端(用 PHP 或其他服务器端语言)。这种方法有几个优点:

  • 冗余 :如果客户端验证过程失败,或者在浏览器中被阻止或不支持,后端过程仍然会寻找错误。
  • 即时性 :客户端解决方案通常在访问者向字段中输入信息时或字段失去焦点后提供即时反馈;除非使用 AJAX 或类似技术,否则服务器端解决方案在提交按钮被按下之前无法提供响应。
  • 安全 :一般来说,服务器端语言将提供一种比使用 JavaScript 更合适、更安全的方式从 VISA 和 Mastercard 获取信用卡验证信息。

JavaScript 中已经有很多验证脚本,但是在 HTML5 中,同样的验证表单的能力现在在浏览器中得到了原生支持,具有pattern属性和两个新的 CSS 伪类::valid:invalid。为了演示这一点,你将创建如图 4-4 所示的表单。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-4。用 CSS3 制作动画形式的错误信息

你从易访问表单的基本标记开始,如清单 4-17 所示。

清单 4-17 。?? 一个可访问的 HTML5 表单

<form>
<label for=age accesskey=a>Age</label>
<input type=number name=age id=age size=3 maxlength=2 min=1 max=99 ←pattern="^([1-9]|[1-9][0-9]){1,2}$” required >
<label for=name accesskey=n>Name</label>
<input type=text name=name id=name size=40 maxlength=38 ←
pattern="^[a-zA-Z]'?[- 'a-zA-Z]+$" placeholder="Your full name" required >
<label for=email accesskey=e>eMail address</label>
<input type=email name=email id=email size=50 maxlength=256 placeholder="Your contacteMail"  required>
<input type=submit value=submit>
</form>

正如您所看到的,您使用了一个带有minmax值的number字段来限制用户输入的年龄、一个电子邮件输入和一个带有正则表达式的标准文本输入来获取用户的姓名。所有输入都是必需的。(我给number输入添加了一个pattern,尽管它在 HTML5 中是无效的,以便在 Firefox 14 和更早的版本中得到加强,它识别pattern但不识别number属性值本身,默认字段为标准文本输入。)你可以使用一些基本的 CSS 来改善这些元素的显示,如清单 4-18 所示。

清单 4-18 。 CSS 为典型的可访问表单

form { font-size: 1.2rem; font-family: "Gill Sans", Arial, sans-serif; }
label,input { display: block; }
label:first-letter { border-bottom: 2px solid #bbb; }
input { border: 1px solid #bbb; padding: .4rem; border-radius: .2rem; margin: .5rem 0; }
input[type="submit"] { border: none; text-transform: uppercase; }

这个样式表唯一稍有不同的地方是第三个声明,它给每个表单标签的第一个字母加下划线,以显示相关字段的适当的 accesskey。要显示输入的信息是对还是错,需要添加清单 4-19 中的代码。(注意第一个 CSS 声明,它关闭了有效和无效输入的当前默认 Firefox UA 样式)。

清单 4-19 。 CSS 为典型的可访问表单

input:valid, input:invalid {box-shadow: none; }
input:valid { border: 2px solid green; }
input:invalid { border: 2px solid yellow; }

虽然您当然可以将目前的表单制作成动画,但是目前的表单有一些缺点:当用户第一次看到页面时,浏览器默认将输入显示为无效,并且没有指示用户输入错误的确切内容。

您不能使用伪类在输入之后生成错误消息,因为它们是被替换的元素,但是您可以将错误消息放在输入之后的跨度的属性中。清单 4-20 中显示了一些例子。

清单 4-20 。 在 HTML5 表单输入后添加 Span 元素作为验证错误消息

<span title="Must be between 1 and 99"></span>
<span title="Must a complete valid eMail address"></span>
<span title="Letters, spaces, apostrophes and hyphens only"></span>

因为每个span只包含其title属性中的信息,没有可见的内容,所以不完全支持 CSS3 的旧浏览器不能向用户显示任何令人困惑的消息。从你的代码中删除清单 4-20 ,用清单 4-21 代替。

***清单 4-21 。*样式和显示验证错误

input + span:after { content: attr(title); color: red; margin-left: 0.6rem; opacity: 0; }
input:invalid + span:after { opacity: 1; }

有一个直接的问题:浏览器通过在页面加载时显示span title属性来继续显示输入错误。原因?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示具有required属性的input由它的pattern评估,或者在用户聚焦或向字段中输入任何信息之前输入type

通过从输入中移除required属性,并给错误消息添加一个转换,如清单 4-22 中的所示,你实现了你想要的效果。请注意,我已经为转换添加了延迟:如果没有延迟,在输入字段中的第一个字符时,错误消息会立即显示出来。在你告诉用户他们的信息是错误的之前,你需要一段合理的时间。

清单 4-22 。 延迟后显示表单验证错误信息

input + span:after { content: attr(title); color: red; margin-left: 0.6rem; opacity: 0;
transition-property: opacity;transition-duration: 2s; transition-delay: 2s;}

您还可以通过在表单元素中显示勾号来显示输入的有效性状态。回到清单 4-17 中的标记和清单 4-18 中的 CSS,添加清单 4-23 中的 CSS。(你可以进一步将tick.png变成精灵图像,并在输入无效时显示一个十字)。

清单 4-23 。 显示表单输入验证的背景图像

input:focus:valid { background-image: url(tick.png); background-repeat: no-repeat;
background-position: right 6px;  }

您不能直接淡入背景图像(到目前为止,还没有对背景图像不透明度的直接控制),但是您可以操作图像,所以如果您想淡入符号,您可以将图像放在输入之后,并像您之前处理验证消息一样转换它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意您也可以完全通过 JavaScript 关闭浏览器的内置表单验证消息,如下所示,使用 jQuery:

$(document).ready(function() {
$('form').bind('invalid', function(e){
$(e.target).attr('validity')
}); });

UI 按钮按下过渡

使用 CSS,你也可以给人一种链接或按钮降低或沉入页面的感觉,如图图 4-5 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-5。典型的按钮示例

实现这一效果的简单方法如清单 4-24 所示。

清单 4-24 。 CSS 使链接点击时降低

a:active { position: relative; top: 1px; }

当然,也可以更精细地设计一个链接,如清单 4-25 所示。

清单 4-25 。 HTML 和 CSS 创建巨型帮助按钮

<a href=# class=bigbutton>help</a>
a.bigbutton {
font-family: "Blue Highway"; text-transform: uppercase; color: #fff;
background: radial-gradient(center 50px, circle farthest-corner, #ef6634, #c63a17 43%,#ba1a01 45%,#bf6e4e 100%);
display: inline-block; width: 200px; height: 200px; border-radius: 100%;
font-size: 70px; text-decoration: none; text-align: center; padding-top: 50px;
box-sizing: border-box; font-weight: 900;
box-shadow: 0 8px 0 rgb(183,0,0), 0 15px 20px rgba(0,0,0,.35);
text-shadow: 0 3px 1px rgba(122,17,8,.8);
transition: .4s all ease-in;
}

在这里,您通过创建两个方框阴影来创建 3D 按钮的效果:一个用于创建按钮边缘的效果,另一个在其下方作为常规阴影。您通过转换四个同时发生的动作来创建按钮降低的印象:

  1. 降低按钮上的文本。
  2. 使用 translate 物理降低整个按钮。
  3. 减少代表按钮边缘的阴影。
  4. 减少和加强整个元素下方阴影的模糊度。

你将在一个基于:active伪选择器的声明中做到这一点,如清单 4-26 所示。

清单 4-26 。 HTML 和 CSS 创建巨型帮助按钮

.bigbutton:active {
   padding-top: 53px;
   transform: translate(0, 4px);
   box-shadow: 0 4px 0 rgb(183,0,0), 0 8px 6px rgba(0,0,0,.45);
}

还可以创建一个按钮显示效果,您将在下一节看到。

UI 按钮显示过渡

标准的 HTML button元素也可以用包含过渡的 CSS 进行大量定制。在这种情况下,你需要一个按钮在hover上展开,显示里面的推广或引导信息(见图 4-6 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-6。一个按钮有两种模式,用 CSS3 过渡了

你的 HTML 将由三个元素组成:一个包含两个标签的button。你可以在清单 4-27 中看到这个标记。

清单 4-27 。 HTML 为一个显示按钮

<button>Sign up
<span class=hidden>For Free</span>
<span class=right></span>
</button>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示当用于 UI 元素的右侧时,Unicode 字符比图像适应性更强,也更容易控制。我在这里使用了一个十进制实体字符来表示向右的黑色(可以在copypastecharacter.com找到 Unicode 字符的一个很好的资源)。)

接下来,您将添加 CSS 来设置您的按钮外观(清单 4-28 )。

清单 4-28 。 为一个显示按钮的基本 CSS

* {box-sizing: border-box;
color: #333; font-family: Futura, Arial, sans-serif;
}
button {
        font-weight: 600;
        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.3);
border-radius: 34px; height: 68px; width: 180px;
padding: 0 20px; font-size: 18px;
background: linear-gradient(to bottom, #1e5799,#7db9e8);
border: 1px solid rgba(0,0,0,0.4);
box-shadow: 0px 1px 1px rgba(255, 255, 255, 0.8) inset,
1px 1px 3px rgba(0, 0, 0, 0.2),
0px 0px 0px 4px rgba(188, 188, 188, 0.5);
text-align: left;
}
span.hidden, span.right  { color: #fff;  }
span.right { padding-left: 18px;  }
span.hidden {background: linear-gradient(to bottom, #222, #000);
display: inline-block; width: 0; margin-left: 22px;
overflow: hidden;
white-space: nowrap; padding: 22px 0;
border-left: 2px double rgba(0,0,0,0.3); }

因为.hidden跨度设置为box-sizing: border-boxwhite-space: nowrapoverflow: hiddenwidth: 0,所以正常情况下你只能在左侧看到它的border

您希望多个过渡事件在同一时间以相同的动作发生。虽然您可以将转换属性放在单独的声明中,但是将它们放在 CSS 中尽可能高的位置通常会更有效。

清单 4-29。 CSS 为一个按钮显示过渡

button { transition: .6s all ease-in-out; }
button:hover { width: 290px; color: #fff; text-shadow: none;  }
button:hover span.hidden { width: 120px; padding: 22px;  }

带有 CSS3 过渡 的可访问水平下拉导航

下拉菜单是复杂网站的常见导航选项。用户已经熟悉了他们电脑上用户界面的格式,所以在网站上使用相同的界面设计是有意义的。参见图 4-7 中的示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-7。下拉菜单

HTML 页面上的下拉菜单传统上是使用 Flash 或 JavaScript 创建的,但这些工具都有一个明显的缺点:对于残疾人来说,使用屏幕阅读器和/或键盘使用它们创建的菜单可能很困难。

通过在带有 CSS3 过渡的 HTML5 标记中使用 ARIA 特性,您可以获得最好的一切:可访问的、视觉上吸引人的、动画的 UI 元素。基本标记如清单 4-30 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示你可以在www.w3.org/TR/wai-aria/roles了解更多关于咏叹调角色的信息。

清单 4-30 。 可访问下拉菜单的 HTML

<nav role=navigation aria-label="Main menu">
<ul role=menubar>
<li role=menuitem tabindex=0><a href=#>Home</a>
<li role=menuitem aria-haspopup=true tabindex=0><a href=#>Services</a>
<ul class=submenu role=menu aria-hidden=true>
<li role=menuitem tabindex=-1><a href=#>Abrasion</a>
<li role=menuitem tabindex=-1><a href=#>Peel</a>
<li role=menuitem tabindex=-1><a href=#>Wax</a>
</ul>
<li role=menuitem tabindex=0><a href=#>Contact</a>
</ul>
</nav>

代码类似于您在清单 4-1 中开始的代码(没有访问键,为了节省空间,本例中省略了访问键)。导航角色已经移回到nav元素上,该元素也获得了一个描述其用途的标签,相当于标题工具提示。

每个列表项都有一个角色menuitem,表示它是可操作的,还有一个tabindex,或者是0(表示它可以通过使用 TAB 键在两个列表项之间跳转)或者是-1(意味着必须使用其他控件,比如箭头键来聚焦它们)。最后,包含子菜单的列表项有一个aria-haspopup属性,子菜单本身有一个aria-hidden属性,表示默认情况下它是不可见的。

为此,你要添加一些基本的 CSS,如清单 4-31 所示。

**清单 4-31 。**代码为 CSS3 的下拉菜单

body { font-family: Futura, Arial, sans-serif; }
nav { height: 41px;
background: linear-gradient(to bottom, rgb(93,146,207) 0%, rgb(79,79,181) 100%); }
nav ul { margin: 0; }
nav, ul.submenu { background: #35f; border-radius: 5px;  padding: 0;  }
nav ul li { display: block; width: 150px; text-align: center; float: left; margin: 0; padding: 0;  }
nav li:hover { background: rgba(0,0,0,0.4); }
nav a { color: #fff; text-decoration: none; display: block; padding: 10px; }
nav ul.submenu { background: rgba(0,0,0,0.8); position: relative; border-radius: 0 0 5px 5px; height: 0px; overflow: hidden; }
nav ul.submenu li { float: none; text-align: left; border-bottom: 1px solid rgba(0,0,0,0.3); }

清单 4-31 中的代码应该是不言自明的:主列表项并排浮动,子菜单放在下面,在本例中,通过将其高度设置为 0 来隐藏。

在当前大多数浏览器中,CSS3 的实现要求您在转换元素的维度时设置明确的度量;在这种情况下,height: 100%height: auto都不起作用。此外,您希望将相同的过渡效果添加到多个元素中;与其重复自己,不如在清单 4-32 的顶部添加声明。

清单 4-32 。 CSS 为一个动画下拉菜单

nav ul li { transition: .3s all linear; }
nav ul li:hover ul.submenu { height: 126px;  }

这种标记和 CSS 可以成为许多界面设计的基础。例如,通过一些小的调整,垂直扩展的“手风琴式”菜单也可以遵循这个模板。

点击按钮后启动 CSS3 过渡效果

在大多数标准 HTML 中,没有记录状态的方法;也就是说,你可以捕捉用户的鼠标在一个元素上的动作(:hover)、按下的动作(:active),以及在某些情况下,在一个元素内输入的动作(:focus),但是很少有直接明显的方式来说“如果这个元素被点击,这样做;但如果关闭了,就撤销动作。”

然而,对于 CSS,您确实有一些选择。CSS 可以通过使用:checked伪类读取复选框和单选按钮元素的状态。通过隐藏复选框,但通过使用关联的label元素来保持可访问性,您可以使用 CSS 来“切换”页面的显示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意虽然我接下来要讨论的技术在 HTML5 中是有效的(它允许你在页面的任何地方放置表单元素),但是它们在语义上是有问题的。有一个学派认为表单元素只应该在表单中使用,并且这些类型的行为应该专门归属于 JavaScript。在继续下面的技术之前,您应该意识到这种争用。

接下来,我将演示如何实现图 4-8 所示的图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-8。一张火星的图片和描述,显示了一个被点击的元素(图片由美国宇航局提供)

根据清单 4-33 中的,你的标记将由一个容器div、一个复选框input和一个包含一些内容的内部div组成。

清单 4-33 。??【复选框标记】打开和关闭一个关联的 div

<div id=mars>
<input type=checkbox id=marstoggle>
<div class=toggle>
<img src=mars.jpg alt=Mars>
<p>Trace amounts of methane were discovered in the atmosphere of Mars in 2003... ←Asmethane is unstable, its presence indicates an active source on the planet that is ←continuallyreplenishing the gas, at the rate of approximately 270 tons per year. ←
</div>
</div>

您将使用清单 4-34 中的代码对外部div及其内容进行样式化。

清单 4-34 。 div 为弹出文本

div#mars { background: #000; color: #fff;
font-family: Futura, Arial, sans-serif;
width: 400px; padding: 1.6rem;
line-height: 175%; border-radius: 6px; }
img { display: block; margin: 0 auto; }
div#mars p { margin: 1rem; }

您想要隐藏内部的div,方法是使用同级选择器将它的height设置为0,并隐藏它之外的任何内容。同时,您还将使用前面讨论的推拉动画原理来设置过渡。(参见清单 4-35 。)

清单 4-35 。??【开合一格】过渡

input ∼ div { overflow: hidden; height: 0; transition: .6s all cubic-bezier(0.735, -0.485, ←
0.145, 1.625);   }

要完成交互式元素的基本功能,如果复选框被选中,您需要展开内部的div。正如我提到的,height需要被显式设置,以便元素在当前浏览器中正确转换(参见清单 4-36 )。

清单 4-36 。 div 为弹出文本

input:checked ∼ div { height: 480px; }

这在这里效果很好,但是用单选按钮隐藏和显示页面内容对于大多数设计来说可能不太好。为了解决这个问题,您可以将一个labelinput相关联,通过使用for属性将label的文本“链接”到checkbox。因此,点击label将打开表单元素,并使你的 CSS 继续响应,即使复选框本身是隐藏的(见清单 4-37 )。

清单 4-37 。 完成复选框关联 div 的标记

<div id=mars>
<label for=marstoggle>Mars</label>
<input type=checkbox class=toggle id=marstoggle>
<div>
<img src=mars.jpg alt=Mars>
<p>Trace amounts of methane were discovered in the atmosphere of Mars in 2003...
</div>
</div>
label { display: block; text-align: center; font-size: x-large;
background: red; border-radius: 6px; padding: .2rem; }
label:hover { background: yellow; color: #000; cursor: pointer; }
input { display: none; }

如果您愿意忽略一些语义问题,这个复选框控件有许多可能性。甚至可以在菜单中使用它来保持状态打开(例如,作为一系列下面有内容的选项卡,或者作为一个折叠菜单)。

用 CSS3 制作表单元素动画

可以扩展转换来直接修改表单元素的外观。一个简单的例子是当输入文本元素的信息不正确时,视觉上的“抖动和淡入”,如清单 4-38 和图 4-9 中的所示。

清单 4-38 。简单动画表单元素的 CSS

input { padding: 1rem; transition: .5s 2s all cubic-bezier(0.475, -0.600, 0.435, 1.650);   }

input:invalid { border: 3px solid red; transform: translateX(10px); }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4-9。一组动画的、定制的单选按钮

有一些注意事项,您可以使用 Simurai ( http://simurai.com/)首先提出的技术将它扩展到单选按钮。基本的标记非常简单:每个单选按钮都有相同的名称,这意味着每个按钮在被单击时都会关闭其他按钮。默认情况下,一个单选按钮自动打开,如清单 4-39 所示。

清单 4-39 。 HTML 为动画单选按钮

<input type="radio" name="radiobutton" checked>
<input type="radio" name="radiobutton">
<input type="radio" name="radiobutton">
<input type="radio" name="radiobutton">
<input type="radio" name="radiobutton">

接下来是 CSS,如清单 4-40 所示。

**清单 4-40 。**动画单选按钮的 CSS

body, input { background-color: rgb(20%,20%,20%); }
input {
     appearance: none;
     margin: 10px; width: 22px; height: 22px;
     border-radius: 50%; cursor: pointer;
     vertical-align: middle;
     box-shadow: hsla(0,0%,100%,.15) 0 1px 1px, inset rgba(0,0,0,.5) 0 0 0 1px;
     background-color: rgb(20%,20%,20%);
        background-image: radial-gradient(
        hsla(0,100%,90%,1) 0%,
        hsla(0,100%,70%,1) 15%,
        hsla(0,100%,60%,.3) 28%,
        hsla(0,100%,30%,0) 70%
    );
      background-repeat: no-repeat;
      transition-property: background-position, transform;
      transition-duration: .15s, .25s;
       transition-timing-function: cubic-bezier(.8, 0, 1, 1);
     }
input:checked {
     transition-property: background-position, transform;
     transition-duration: .2s, .25s;
     transition-delay: .15s, 0s;
     transition-timing-function: cubic-bezier(0, 0, .2, 1);
   }
input:active { transform: scale(1.5); transition: transform .1s cubic-bezier(0, 0, .2, 1); }
input,input:active { background-position: 22px 0; }
input:checked { background-position: 0 0; }
input:checked ∼ input, input:checked ∼ input:active { background-position: -22px 0; }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意appearance属性旨在从一个元素中移除所有预配置的默认样式,或者允许元素呈现其他元素的外观(例如,将一个span样式化为一个textbox)。appearance是为 CSS3 提出的,但没有进入 UI 模块的规范,尽管它正在被考虑用于规范的未来迭代。该属性在 Webkit 中支持前缀,在 Firefox 中支持部分前缀。出于这个原因,在我写这篇文章的时候,清单 4-40 中显示的代码在 Chrome 中运行得最好。

一旦你克服了hsla颜色渐变的复杂性(非常适合创建不同颜色的“信号”灯),剩下的代码就简单了:单选按钮在焦点上变大,释放时径向渐变的背景图像移动到按钮的位置。

摘要

在这一章中,你已经看到了 CSS3 过渡可以用来增强用户界面元素的一些方法,从表单到站点导航。有无数的可能性,我将留给你的想象力和实验。

尽管它们很有用,但转换受到两个事实的限制:它们依赖于某种用户动作来启动,并且它们总是在两点或两种状态之间活动。在曲线上移动对象是不可能的,因为让它们自己循环或运行是不可能的。所有这些特性都属于 CSS 动画模块的范围(我称之为“关键帧动画”以进一步区分它们和过渡)。我将在下一章讨论这个模块。`

转载请注明出处或者链接地址:https://www.qianduange.cn//article/17317.html
标签
VKDoc
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!