❤️💕💕HTML和CSS高级教程。更多的文章请移步博客Myblog:http://nsddd.top
[TOC]
视觉设计结合了排版、色彩理论、图形、动画、页面布局等,以表达独特的信息。
基于美化一个卡片组件的外观,借此展示了若干核心原则。
web 内容大部分都是文本。 CSS 里面的 text-align
属性可以控制文本的对齐方式。
text-align: justify;
将文本隔开,使每行的宽度相等。
text-align: center;
可以让文本居中对齐。
text-align: right;
可以让文本右对齐。
text-align: left;
是默认值,它可以让文本左对齐。
请让内容文本为 “Google” 的 h4
标签居中对齐, 然后将介绍 Google 创立历程的段落文本两端对齐。
<style>
h4 {
text-align: center;
}
p {
text-align: justify;
}
.links {
margin-right: 20px;
}
.fullCard {
border: 1px solid #ccc;
border-radius: 5px;
margin: 10px 5px;
padding: 4px;
}
.cardContent {
padding: 10px;
}
</style>
<div class="fullCard">
<div class="cardContent"> <!--可以有继承关系!!! -->
<div class="cardText">
<h4>Google</h4>
<p>Google was founded by Larry Page and Sergey Brin while they were Ph.D. students at Stanford University.</p>
</div>
<div class="cardLinks">
<a href="https://en.wikipedia.org/wiki/Larry_Page" target="_blank" class="links">Larry Page</a>
<a href="https://en.wikipedia.org/wiki/Sergey_Brin" target="_blank" class="links">Sergey Brin</a>
</div>
</div>
</div>
其实在markdown也是一样的,有些文字是在markdown中没办法设置大小和颜色,我们需要用到html的标签
为了让页面更美观,除了设置整个页面的背景色以及文字颜色外,你还可以单独设置文字的背景色,即在文字的父元素上添加 background-color
属性。 在本挑战里我们将使用 rgba()
颜色,而不是之前学到的 hex
编码或者 rgb()
颜色。
rgba 代表: r = red 红色 g = green 绿色 b = blue 蓝色 a = alpha 透明度
RGB 值可以取在 0 到 255 之间。 alpha 值可取在 0 到 1 之间,其中 0 代表完全透明,1 代表完全不透明。 rgba()
在需要设置颜色透明度时十分有用, 这意味着你可以做出一些很漂亮的半透明效果。
用这个代码 background-color: rgba(45, 45, 45, 0.1)
。 它表示背景是黑灰色,因为设置了透明度为 0.1,所以几乎是透明的。
<style>
h4 {
text-align: center;
padding: 10px;
background-color: background-color: rgba(45, 45, 45, 0.1);
}
p {
text-align: justify;
}
.links {
text-align: left;
color: black;
}
.fullCard {
width: 245px;
border: 1px solid #ccc;
border-radius: 5px;
margin: 10px 5px;
padding: 4px;
}
.cardContent {
padding: 10px;
}
.cardText {
margin-bottom: 30px;
}
</style>
<div class="fullCard">
<div class="cardContent">
<div class="cardText">
<h4>Alphabet</h4>
<hr>
<p><em>Google was founded by Larry Page and Sergey Brin while they were <u>Ph.D. students</u> at <strong>Stanford University</strong>.</em></p>
</div>
<div class="cardLinks">
<a href="https://en.wikipedia.org/wiki/Larry_Page" target="_blank" class="links">Larry Page</a><br><br>
<a href="https://en.wikipedia.org/wiki/Sergey_Brin" target="_blank" class="links">Sergey Brin</a>
</div>
</div>
</div>
标题元素(h1
到 h6
)的字体大小通常应大于段落标签的字体大小。 这使用户更容易直观地了解页面上所有内容的布局和重要性级别。 你可以使用 font-size
属性来调整元素中文本的大小。
h4 {
text-align: center;
background-color: rgba(45, 45, 45, 0.1);
padding: 10px;
font-size: 27px;
}
box-shadow
属性用来给元素添加阴影,该属性值是由逗号分隔的一个或多个阴影列表。
box-shadow
属性按顺序采用以下值:
offset-x
(阴影的水平偏移量),offset-y
(阴影的垂直偏移量),blur-radius
spread-radius
color
其中 blur-radius
和 spread-radius
是可选的。
可以通过逗号分隔每个 box-shadow
元素的属性来添加多个 box-shadow。
如下为添加了模糊效果的例子,它使用了透明度较高的黑色作为阴影:
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
CSS 里的 opacity
属性用来设置元素的透明度。
属性值为 1 代表完全不透明。 属性值为 0.5 代表半透明。 属性值为 0 代表完全透明。
透明度会应用到元素内的所有内容,不论是图片,还是文本,或是背景色。
CSS 里的 text-transform
属性可以改变英文字母的大小写。 使用这个属性时,我们无需改变 HTML 元素中的文本也可以统一页面里英文的显示。
下面的表格展示了 text-transform
的不同值对文字 “Transform me” 的影响:
值 | 结果 |
---|---|
lowercase |
"transform me" |
uppercase |
"TRANSFORM ME" |
capitalize |
"Transform Me" |
initial |
使用默认值 |
inherit |
使用父元素的 text-transform 值。 |
none |
**Default:**不改变文字。 |
请使用 text-transform
属性把 h4
内容文本中的所有字母变成大写。
<style>
h4 {
text-align: center;
background-color: rgba(45, 45, 45, 0.1);
padding: 10px;
font-size: 27px;
text-transform: uppercase;
}
p {
text-align: justify;
}
.links {
text-align: left;
color: black;
opacity: 0.7;
}
#thumbnail {
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
}
.fullCard {
width: 245px;
border: 1px solid #ccc;
border-radius: 5px;
margin: 10px 5px;
padding: 4px;
}
.cardContent {
padding: 10px;
}
.cardText {
margin-bottom: 30px;
}
</style>
<div class="fullCard" id="thumbnail">
<div class="cardContent">
<div class="cardText">
<h4>Alphabet</h4>
<hr>
<p><em>Google was founded by Larry Page and Sergey Brin while they were <u>Ph.D. students</u> at <strong>Stanford University</strong>.</em></p>
</div>
<div class="cardLinks">
<a href="https://en.wikipedia.org/wiki/Larry_Page" target="_blank" class="links">Larry Page</a><br><br>
<a href="https://en.wikipedia.org/wiki/Sergey_Brin" target="_blank" class="links">Sergey Brin</a>
</div>
</div>
</div>
本挑战将要涉及到伪类。 伪类是可以添加到选择器上的关键字,用来选择特定状态的元素。
比如,可以使用 :hover
伪类选择器来选取超链接的悬停状态。 下面的代码可以在鼠标悬停在超链接上时将其 color
变成红色:
a:hover {
color: red;
}
在 CSS 里一切 HTML 元素皆为盒子,也就是通常所说的盒模型。 块级元素自动从新的一行开始(比如标题、段落以及 div),行内元素排列在上一个元素后(比如图片以及 span)。 元素默认按照这种方式布局称为文档的普通流,同时 CSS 提供了 position 属性来覆盖它。
当元素的定位设置为 relative
时,它允许你通过 CSS 指定该元素在当前文档流页面下的相对偏移量。 CSS 里控制各个方向偏移量的属性是 left
、right
、top
和 bottom
。 它们代表从原来位置向远离该方向偏移指定的像素、百分比或者 em。 下面的例子展示了段落向上偏移 10px:
p {
position: relative;
bottom: 10px;
}
把元素的位置设置成相对,并不会改变该元素在布局中所占的位置,也不会对其它元素的位置产生影响。
注意: 定位可以使页面布局更灵活、高效。 不管元素的定位是怎样的,HTML 标记在从上到下阅读起来时应该是整洁的、有意义的。 这样可以让视障人士(重度依赖辅助设备比如屏幕阅读软件的人们)也能够无障碍地浏览你的网页。
把 h2
的 position
设置成 relative
,使用相应的 CSS 属性调整它的位置,使其相对 top
偏移 15px,同时还在文档流中处于原来的位置。 这不会对 h1 和 p 元素的位置产生影响。
当一些元素在位置上重叠时(例如,使用 position: absolute | relative | fixed | sticky
时),在 HTML 里后出现的元素会默认显示在更早出现的元素的上面。 你可以使用 z-index
属性指定元素的堆叠次序。 z-index
的取值是整数,数值大的元素会叠放到数值小的元素上面。
在应用设计中经常需要把一个块级元素水平居中显示。 一种常见的实现方式是把块级元素的 margin
值设置为 auto。
同样的,这个方法也对图片奏效。 图片默认是内联元素,但是可以通过设置其 display
属性为 block
来把它变成块级元素。
<style>
div {
background-color: blue;
height: 100px;
width: 100px;
}
</style>
<div></div>
色彩理论以及设计色彩学很复杂,这里将只涉及基础部分。 在网站设计里,颜色能让内容更醒目,能调动情绪,从而创造舒适的视觉体验。 不同的颜色组合对网站的视觉效果影响很大,精妙的设计都需要适宜的颜色来美化页面内容。
色环是我们认识颜色关系的好工具。它是一个近色相邻、异色相离的圆环。 当两个颜色恰好在色环的两端时,这两个颜色就互为补色。 两个互为补色的颜色会在混合后变成灰色。 然而,补色搭配能形成强烈的视觉对比效果。
下面是一些以 hex 形式表示的补色例子:
红色(#FF0000)和蓝绿色 (#00FFFF) 绿色(#00FF00)和品红色(#FF00FF) 蓝色(#0000FF)和黄色(#FFFF00)
这与我们许多人在学校学的过时的 RYB 色彩模式不同,RYB 有不同的原色和补色。 现代色彩理论使用 RGB 模型(如在计算机屏幕上)和 CMY(K)模型(如在印刷中)。
现在,很多在线选色工具也为我们提供了寻找补色的功能。
注意: 对于颜色相关的挑战:颜色搭配是提起用户兴趣或吸引用户注意的重要方式之一。 但我们不应让颜色作为传达重要信息的唯一方式,因为视觉障碍用户可能无法像其他人一样看出其中的含义。 我们将会在应用无障碍章节进行详细介绍。
把 class 为 blue
和 yellow
的元素的 background-color
属性改成相应的颜色。 注意观察这两个颜色的搭配效果,以及对比白色背景的视觉效果。
<style>
body {
background-color: #FFFFFF;
}
.blue {
background-color: #0000FF;
}
.yellow {
background-color: #FFFF00;
}
div {
display: inline-block;
height: 100px;
width: 100px;
}
</style>
<div class="blue"></div>
<div class="yellow"></div>
电脑显示器和各类屏幕都是基于颜色叠加的模型:将红(R)、绿(G)、蓝(B)三原色的色光以不同的比例相加,就可以产生各种色彩光。 这在现代色彩理论中叫作三原色光模式(RGB Color Model)。 红色(R)、绿色(G)和蓝色(B)叫作三原色。 如果把两种原色相加,就可以产生二次色:蓝绿(G+B)、品红(R+B)和黄色(R+G), 我们在上一个挑战里已经见过这些颜色了。 这些二次色恰好是在合成它们时未使用的原色的补色,即在色环中位于两端。 例如,品红色是红色和蓝色相加产生,它是绿色的补色。
三次色是由原色和二次色相加产生的颜色, 例如,在 RGB 颜色模型中,红色(原色)和黄色(二次色)相加产生橙色(三次色)。 将这六种颜色中相邻的颜色相加,便产生了十二色色环。
设计里面有很多种颜色搭配方法。 涉及到三次色的一种配色方法是分裂补色搭配法。 选定主色之后,在色环上选择与它的补色相邻的两种颜色与之搭配。 此种搭配既有对比,又不失和谐。
下面是使用分裂补色搭配法创建的三个颜色:
颜色 | HEX 颜色码 |
---|---|
橙色 | #FF7F00 |
蓝绿色 | #00FFFF |
树莓红 | #FF007F |
把 class 为 orange
、cyan
和 raspberry
的 background-color
改成其对应的颜色。 在这个挑战中,请使用颜色的十六进制符号(即 hex code)来表示。
<style>
body {
background-color: #FFFFFF;
}
.orange {
background-color: #FF7F00;
}
.cyan {
background-color: #00FFFF;
}
.raspberry {
background-color: #FF007F;
}
div {
height: 100px;
width: 100px;
margin-bottom: 5px;
}
</style>
<div class="orange"></div>
<div class="cyan"></div>
<div class="raspberry"></div>
我们知道了补色搭配能形成强列的对比效果,让内容更富生机。 但是如果使用不当效果会适得其反:比如将文字背景色和文字颜色设置为互补色,这样文字会很难看清。 通常的做法是,一种颜色做为主要颜色,然后使用其补色用来装点那些需要用户特别注意的部分。
使用深青色(#09A7A1
)做为页面主色,用其补色橙色(#FF790E
)来装饰登录按钮。 把 header
和 footer
的 background-color
从黑色改成深青色。 然后把 h2
的文字 color
也改成深青色。 最后,把 button
的 background-color
改成橙色。
<style>
body {
background-color: 09A7A1;
}
header {
background-color: 09A7A1;
color: white;
padding: 0.25em;
}
h2 {
color: 09A7A1;
}
button {
background-color: FF790E;
}
footer {
background-color: 09A7A1;
color: white;
padding: 0.5em;
}
</style>
<header>
<h1>Cooking with FCC!</h1>
</header>
<main>
<article>
<h2>Machine Learning in the Kitchen</h2>
<p>Join this two day workshop that walks through how to implement cutting-edge snack-getting algorithms with a command line interface. Coding usually involves writing exact instructions, but sometimes you need your computer to execute flexible commands, like <code>fetch Pringles</code>.</p>
<button>Sign Up</button>
</article>
<article>
<h2>Bisection Vegetable Chopping</h2>
<p>This week-long retreat will level-up your coding ninja skills to actual ninja skills. No longer is the humble bisection search limited to sorted arrays or coding interview questions, applying its concepts in the kitchen will have you chopping carrots in O(log n) time before you know it.</p>
<button>Sign Up</button>
</article>
</main>
<br>
<footer>© 2018 FCC Kitchen</footer>
颜色具有多种特性,包括色相、饱和度和亮度。 CSS3 引入了hsl()
函数,作为直接说明这些特征来挑选颜色的替代方法。
色相 是色彩的基本属性,就是平常所说的颜色名称,如红色、黄色等。 以颜色光谱为例,光谱左边从红色开始,移动到中间的绿色,一直到右边的蓝色,色相值就是沿着这条线的取值。 在 hsl()
里面,色相用色环来代替光谱,色相值就是色环里面的颜色对应的从 0 到 360 度的角度值。
饱和度 是指色彩的纯度,也就是颜色里灰色的占比。 饱和度越高则灰色占比越少,色彩也就越纯;反之则完全是灰色。 饱和度的取值范围是表示灰色所占百分比的 0 至 100。
亮度 决定颜色的明暗程度,也就是颜色里白色或者黑色的占比。 其中,100% 的亮度表示纯白色, 0% 的亮度则表示纯黑色;而 50% 的亮度就表示在色相中选取的颜色。
下面是一些使用 hsl()
描述颜色的例子,颜色都为满饱和度,中等亮度:
颜色 | HSL |
---|---|
红 | hsl(0, 100%, 50%) |
黄 | hsl(60, 100%, 50%) |
绿 | hsl(120, 100%, 50%) |
蓝绿 | hsl(180, 100%, 50%) |
蓝 | hsl(240, 100%, 50%) |
品红 | hsl(300, 100%, 50%) |
将 class 为 green
、cyan
和 blue
的 div
的 background-color
属性值设置为使用 hsl()
表示的颜色。 颜色都为满饱和度,亮度中等。
HTML 元素的背景色并不局限于单色。 CSS 还为我们提供了颜色渐变。 可通过 background
里的 linear-gradient()
实现线性渐变, 以下是它的语法:
background: linear-gradient(gradient_direction, color 1, color 2, color 3, ...);
第一个参数指定了颜色过渡的方向——它的值是角度,90deg
表示垂直渐变(从左到右),45deg
表示沿对角线渐变(从左下方到右上方)。 其他参数指定了渐变颜色的顺序:
例如:
background: linear-gradient(90deg, red, yellow, rgb(204, 204, 255));
使用 linear-gradient()
给 div
元素添加 background
渐变色,渐变角度为 35 度,从 #CCFFFF
过渡到 #FFCCCC
。
<style>
div {
border-radius: 20px;
width: 70%;
height: 400px;
margin: 50px auto;
background-image: linear-gradient(35deg, #CCFFFF, #FFCCCC);
}
</style>
<div></div>
repeating-linear-gradient()
函数和 linear-gradient()
很像,主要区别是前者会重复指定的渐变。 repeating-linear-gradient()
有很多参数,为了便于理解,本关只用到角度值和色标。
角度就是渐变的方向。 色标代表渐变颜色及发生渐变的位置,由百分比或者像素值表示。
在代码编辑器的例子里,渐变开始于 0 像素位置的 yellow
,然后过渡到距离开始位置 40 像素的 blue
。 由于下一个渐变颜色的起始位置也是 40 像素,所以颜色直接渐变成第三个颜色值 green
,然后过渡到距离开始位置 80 像素的 red
。
下面的代码可以帮助理解成对的起止渐变颜色值是如何过渡的。
0px [yellow -- blend -- blue] 40px [green -- blend -- red] 80px
如果每对起止渐变颜色值的颜色都是相同的,由于是在两个相同的颜色间过渡,那么中间的过渡色也为同色,接着就是同色的过渡色和下一个起止颜色,最终产生的效果就是条纹。
使用 repeating-linear-gradient()
函数创建一个渐变角度为 45deg
的条纹,然后设置第一对渐变颜色为 yellow
,第二对渐变颜色为 black
。
<style>
div{
border-radius: 20px;
width: 70%;
height: 400px;
margin: 50 auto;
background: repeating-linear-gradient(
45deg,
yellow 0px,
yellow 40px,
black 40px,
black 80px
);
}
</style>
<div></div>
CSS 属性 transform
里面的 scale()
函数可以用来改变元素的显示比例。 下面的例子把页面的段落元素放大到了原来的 2 倍:
p {
transform: scale(2);
}
把 id 为 ball2
的元素放大到原始大小的 1.5 倍。
transform
属性有很多函数可以调用,可以对元素进行调整大小、移动、旋转、翻转等操作。 当使用伪类选取元素的指定状态(如 :hover
)时,我们可以通过 transform
属性非常方便地给元素添加交互。
下面是当用户悬停在段落元素时,段落大小缩放到原始大小 2.1 倍的例子:
p:hover {
transform: scale(2.1);
}
注意: 给 div
元素添加 transform 也会影响这个 div 包裹的子元素。
通过伪类,给 div
的 hover
状态添加 transform
属性,使 div
当鼠标悬停时大小缩放到原始大小的 1.1 倍。
<style>
div {
width: 70%;
height: 100px;
margin: 50px auto;
background: linear-gradient(
53deg,
#ccfffc,
#ffcccf
);
}
div:hover {
transform: scale(1.1);
}
</style>
<div></div>
transform
属性是 skewX()
:它使选择的元素沿着 X 轴(横向)倾斜指定的角度。
下面的代码沿着 X 轴倾斜段落元素 -32 度。
p {
transform: skewX(-32deg);
}
通过使用不同的选择器和属性,你可以做出有趣的形状, 一个简单的例子是新月形状。 在这个挑战中,我们会学习如何使用 box-shadow
属性来设置元素的阴影,以及使用 border-radius
属性控制元素的圆角边框。
首先我们来创建一个圆的、透明的图形,它具有模糊阴影并略微向两边递减。 如你所见,这个阴影其实就是新月形狀。
<style>
.center {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100px;
height: 100px;
background-color: blue;
border-radius: 0px;
box-shadow: 25px 10px 10px 10px green;
}
</style>
<div class="center"></div>
为了创建一个圆形的对象,border-radius
应该被设置成 50%。
你应该还记得之前关卡的 box-shadow
属性以及它的依次取值 offset-x
、offset-y
、blur-radius
、spread-radius
和 color
值。 其中 blur-radius
和 spread-radius
是可选的。
把编辑器里的正方形元素变成新月形状。 首先,把 background-color
改为 transparent
,接着把 border-radius
属性设置成 50%,以创建一个圆形。 最后,更改 box-shadow
属性,使其 offset-x
为 25px,offset-y
为 10px,blur-radius
为 0,spread-radius
为 0,color
为 red
。
<style>
.center {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100px;
height: 100px;
background-color: transparent;
border-radius: 50px;
box-shadow: 25px 10px 0px 0px blue;
}
</style>
<div class="center"></div>
世界上最流行的形状非心形莫属了,在本挑战中我们将用纯 CSS 创建一个心形。 但是首先你需要了解伪元素 ::before
和 ::after
。 ::before
创建一个伪元素,它是所选元素的第一个子元素; ::after
创建一个伪元素,它是所选元素的最后一个子元素。 在下面的代码中,::before
伪元素用来给 class 为 heart
的元素添加一个正方形:
.heart::before {
content: "";
background-color: yellow;
border-radius: 25%;
position: absolute;
height: 50px;
width: 70px;
top: -50px;
left: 5px;
}
::before
和 ::after
必须配合 content
来使用。 这个属性通常用来给元素添加内容诸如图片或者文字。 尽管有时 ::before
和 ::after
是用来实现形状而非文字,但 content
属性仍然是必需的,此时它的值可以是空字符串。 在上面的例子里,class 为 heart
元素的 ::before
伪类添加了一个黄色的长方形,长方形的高和宽分别为 50px
和 70px
。 这个矩形有圆角,因为它的 border-radius
为 25%,它的位置是绝对位置,位于离元素左边和顶部分别是 5px
、50px
的位置。
把屏幕里的元素变成心形。 在 .heart::after
选择器里,把 background-color
改成 pink
,把 border-radius
改成 50%。
接下来,用类选择器选取 class 为 heart
(只是 heart
)的元素,为它添加 transform
属性。 使用 rotate()
函数并设置角度为 -45 度。
最后,在 ,heart::before
选择器里面,设置 content
属性值为空字符串。
<style>
.heart {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: pink;
height: 50px;
width: 50px;
transform: rotate(-45deg);
}
.heart::after {
background-color: pink;
content: "";
border-radius: 50%;
position: absolute;
width: 50px;
height: 50px;
top: 0px;
left: 25px;
}
.heart::before {
content: '';
background-color: pink;
border-radius: 50%;
position: absolute;
width: 50px;
height: 50px;
top: -25px;
left: 0px;
}
</style>
<div class="heart"></div>
如果要给元素添加动画,你需要了解 animation 属性以及 @keyframes
规则。 animation 属性控制动画的外观,@keyframes
规则控制动画中各阶段的变化。 总共有 8 个 animation 属性。 为了便于理解,本挑战中我们只会暂时涉及到两个最常用的属性。
animation-name
用来设置动画的名称,也就是我们稍后要在 @keyframes
里用到的名称。
animation-duration
设置动画所花费的时间。
@keyframes
可以通过设置特定时间点的行为来创建动画。 为此,我们只需要给持续时间内的特定帧(从 0% 到 100%)加上 CSS 规则。 如果用一部电影来做类比,那么 CSS 里面的 0% 关键帧就像是电影里面的开场镜头;100% 关键帧就像是电影里的片尾,就是那个之后会出现演职人员列表的片尾。 在动画设定的时间内,CSS 会根据关键帧的规则来给元素添加动画效果。 100% 位置的 CSS 属性就是元素最后的样子,相当于电影里的演职员表或者鸣谢镜头。 然后CSS 应用魔法来在给定的时间内转换元素以使其脱离场景。 下面举例说明 @keyframes
和动画属性的用法:
#anim {
animation-name: colorful;
animation-duration: 3s;
}
@keyframes colorful {
0% {
background-color: blue;
}
100% {
background-color: yellow;
}
}
id 为 anim
的元素,我们在代码中将它的 animation-name
设置为 colorful
,同时设置 animation-duration
为 3 秒。 然后我们把 @keyframes
规则添加到名为 colorful
的动画属性上。 在动画开始时(0%)的背景颜色为蓝色,在动画结束时(100%)的背景颜色为黄色。 注意我们不只可以设置开始和结束,而是从 0% 到 100% 间的任意位置都可以设置。
给 id 为 rect
的元素添加动画,设置其 animation-name
为 rainbow
,设置其 animation-duration
为 4 秒。 然后声明 @keyframes
规则,设置动画开始时(0%
)的 background-color
为蓝色,动画中间时(50%
)为绿色,动画结束时(100%
)为为黄色。
<style>
div {
height: 40px;
width: 70%;
background: black;
margin: 50px auto;
border-radius: 5px;
}
#rect {
animation-name: rainbow;
animation-duration: 4s;
}
@keyframes rainbow{
0% {
background-color: blue;
}
50% {
background-color: green;
}
100% {
background-color: yellow;
}
}
</style>
<div id="rect"></div>
你可以在按钮悬停时使用 @keyframes
改变按钮的颜色。
下面是在图片悬停时改变图片宽度的例子:
<style>
img {
width: 30px;
}
img:hover {
animation-name: width;
animation-duration: 500ms;
}
@keyframes width {
100% {
width: 40px;
}
}
</style>
<img src="https://cdn.freecodecamp.org/curriculum/applied-visual-design/google-logo.png" alt="Google's Logo" />
注意 ms
代表毫秒,1000ms 等于 1s。
使用 @keyframes
来改变 button
元素的 background-color
,使其在悬停时变成 #4791d0
。 @keyframes
规则应该只有一个 100%
条目。
<style>
button {
border-radius: 5px;
color: white;
background-color: #0F5897;
padding: 5px 10px 8px 10px;
}
button:hover {
animation-name: background-color;
animation-duration: 500ms;
}
@keyframes background-color {
100% {
background-color: #4791d0;
}
}
</style>
<button>Register</button>
但是现在还不完美。 注意动画在 500ms
之后重置了,所以按钮又变成了之前的颜色。 而我们想要的效果是按钮在悬停时始终高亮。
为此,我们可以通过把 animation-fill-mode
设置成 forwards
来实现。 animation-fill-mode
指定了在动画结束时元素的样式: 你可以这样设置:
animation-fill-mode: forwards;
在元素的 position
已有指定值(如 fixed
或者 relative
)时,CSS 偏移属性 right
、left
、top
、bottom
可以用在动画规则里创建动作。
就像下面的例子展示的那样,你可以在 50%
keyframe 处设置 top
属性为 50px,在开始(0%
)和结束(100%
)keyframe 处设置为 0px,以实现元素先向下运动,然后返回的动作效果。
@keyframes rainbow {
0% {
background-color: blue;
top: 0px;
}
50% {
background-color: green;
top: 50px;
}
100% {
background-color: yellow;
top: 0px;
}
}
请实现让 div
水平运动的效果。 使用 left
偏移属性,添加 @keyframes
规则,让 rainbow 在 0%
处偏移 0px,在 50%
处偏移 25px,在 100%
处偏移 -25px。 不要修改编辑器里的 top
属性,元素应该同时在水平和竖直方向运动。
<style>
div {
height: 40px;
width: 70%;
background: black;
margin: 50px auto;
border-radius: 5px;
position: relative;
}
#rect {
animation-name: rainbow;
animation-duration: 4s;
}
@keyframes rainbow {
0% {
background-color: blue;
left: 0px;
}
50% {
background-color: green;
left: 25px;
}
100% {
background-color: yellow;
left: -25px;
}
}
</style>
<div id="rect"></div>
在本挑战中,我们需要改变动画元素的 opacity
属性值,使其在到达屏幕右侧时渐隐。
在示例动画中,具有渐变背景的圆形元素在 @keyframes
为 50% 的节点向右移动。
@keyframes fade {
50% {
left: 60%;
opacity: 0.1;
}
}
之前的关卡里介绍了一些动画属性以及 @keyframes
规则的用法。 还有一个常用的动画属性是 animation-iteration-count
,这个属性允许你控制动画循环的次数。 下面是一个例子:
animation-iteration-count: 3;
在这里动画会在运行 3 次后停止,如果想让动画一直运行,可以把值设置成 infinite
。
把 animation-iteration-count
属性改成 infinite
,使右边的球一直跳跃。
<style>
#ball {
width: 100px;
height: 100px;
margin: 50px auto;
position: relative;
border-radius: 50%;
background: linear-gradient(
35deg,
#ccffff,
#ffcccc
);
animation-name: bounce;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes bounce{
0% {
top: 0px;
}
50% {
top: 249px;
width: 130px;
height: 70px;
}
100% {
top: 0px;
}
}
</style>
<div id="ball"></div>
这也是一个用 animation-iteration-count
属性创造持续动画的例子,它基于我们在前面挑战中创建的心形。
心跳动画的每一秒包含两个部分。 heart
元素(包括 :before
和 :after
)使用 transform
属性改变其大小,背景 div
使用 background
属性改变其颜色。
给 back
class 和 the heart
class 添加 animation-iteration-count
属性,将属性值设置为 infinite
,使心保持跳动。 heart:before
和 heart:after
所选择的元素则不需要添加动画属性。
<style>
.back {
position: fixed;
padding: 0;
margin: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: white;
animation-name: backdiv;
animation-duration: 1s;
animation-iteration-count: infinite;
}
.heart {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: pink;
height: 50px;
width: 50px;
transform: rotate(-45deg);
animation-name: beat;
animation-duration: 1s;
animation-iteration-count: infinite;
}
.heart:after {
background-color: pink;
content: "";
border-radius: 50%;
position: absolute;
width: 50px;
height: 50px;
top: 0px;
left: 25px;
}
.heart:before {
background-color: pink;
content: "";
border-radius: 50%;
position: absolute;
width: 50px;
height: 50px;
top: -25px;
left: 0px;
}
@keyframes backdiv {
50% {
background: #ffe6f2;
}
}
@keyframes beat {
0% {
transform: scale(1) rotate(-45deg);
}
50% {
transform: scale(0.6) rotate(-45deg);
}
}
</style>
<div class="back"></div>
<div class="heart"></div>
改变相似元素的动画频率的方法有很多。 目前我们接触到的就有 animation-iteration-count
和 @keyframes
。
举例说明,右边的动画包含了两个小星星,每个小星星都在 @keyframes
为 20% 处变小并且透明度变低,也就是一闪一闪的动画效果。 你可以通过改变其中一个元素的 @keyframes
规则以使两个小星星以不同的频率闪烁。
在前面的关卡里,我们通过修改 @keyframes
改变了两个相似动画元素的频率。 你也可以通过改变多个元素的 animation-duration
来达到同样的效果。
在代码编辑器里运行的动画中,天空中有三颗以同样频率不停闪烁的星星。 你可以设置每一个星星的 animation-duration
属性为不同的值,以使其具有不同的闪烁频率。
依次设置 class 为 star-1
、star-2
、star-3
的元素的 animation-duration
为 1s、0.9s、1.1s。
<style>
.stars {
background-color: white;
height: 30px;
width: 30px;
border-radius: 50%;
animation-iteration-count: infinite;
}
.star-1 {
margin-top: 15%;
margin-left: 60%;
animation-duration: 1s;
animation-name: twinkle;
}
.star-2 {
margin-top: 25%;
margin-left: 25%;
animation-duration: 0.9s;
animation-name: twinkle;
}
.star-3 {
margin-top: 10%;
margin-left: 50%;
animation-duration: 1.1s;
animation-name: twinkle;
}
@keyframes twinkle {
20% {
transform: scale(0.5);
opacity: 0.5;
}
}
#back {
position: fixed;
padding: 0;
margin: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(black, #000099, #66c2ff, #ffcccc, #ffeee6);
}
</style>
<div id="back"></div>
<div class="star-1 stars"></div>
<div class="star-2 stars"></div>
<div class="star-3 stars"></div>
在 CSS 动画里,animation-timing-function
用来定义动画的速度曲线。 速度曲线决定了动画从一套 CSS 样式变为另一套所用的时间。 如果要描述的动画是一辆车在指定时间内(animation-duration
)从 A 运动到 B,那么 animation-timing-function
表述的就是车在运动中的加速和减速等过程。
有一些预定义的关键字可用于常见的选项。 比如,默认值是 ease
,动画以低速开始,然后加快,在结束前变慢。 其它常用的值包括 ease-out
:动画以高速开始,以低速结束;ease-in
,动画以低速开始,以高速结束;linear
:动画从头到尾的速度是相同的。
给 id 为 ball1
和 ball2
的元素添加 animation-timing-function
,ball1
的属性值为 linear
,ball2
的属性值为 ease-out
。 它们的 animation-duration
都为 2 秒,注意观察它们在开始和结束时的不同。
<style>
.balls {
border-radius: 50%;
background: linear-gradient(
35deg,
#ccffff,
#ffcccc
);
position: fixed;
width: 50px;
height: 50px;
margin-top: 50px;
animation-name: bounce;
animation-duration: 2s;
animation-iteration-count: infinite;
}
#ball1 {
left:27%;
animation-timing-function: linear;
animation-duration: 2s;
}
#ball2 {
left:56%;
animation-timing-function: ease-out;
animation-duration: 2s;
}
@keyframes bounce {
0% {
top: 0px;
}
100% {
top: 249px;
}
}
</style>
<div class="balls" id="ball1"></div>
<div class="balls" id="ball2"></div>
上一个挑战中,我们介绍了 animation-timing-function
以及它的一些预设值,这些值定义了不同时间内的动画速度。 除了预定义值之外,CSS 还提供了贝塞尔曲线(Bezier curves)来更细致地控制动画的速度曲线。
在 CSS 动画里,我们可以用 cubic-bezier
来定义贝塞尔曲线。 曲线的形状代表了动画的速度。 曲线在 1 * 1 的坐标系统内, 其中 X 轴代表动画的时间间隔(类似于时间比例尺),Y 轴代表动画的改变。
cubic-bezier
函数包含了 1 * 1 网格里的4个点:p0
、p1
、p2
、p3
。 其中 p0
和 p3
是固定值,代表曲线的起始点和结束点,坐标值依次为 (0, 0) 和 (1, 1)。 你只需设置另外两点的 x 值和 y 值,设置的这两点确定了曲线的形状从而确定了动画的速度曲线。 在 CSS 里面通过 (x1, y1, x2, y2)
来确定 p1
和 p2
。 以下就是 CSS 贝塞尔曲线的例子:
animation-timing-function: cubic-bezier(0.25, 0.25, 0.75, 0.75);
在上面的例子里,两个点的 x 和 y 值相等(x1 = 0.25 = y1 和 x2 = 0.75 = y2)。如果你还记得几何课的知识,结果是从原点到点 (1, 1) 的一条直线。 元素在动画中的速度呈线性,效果和使用 linear
关键词的效果一致。 换言之,元素匀速运动。
前面的关卡涉及了使用 ease-out
预定义值描述了动画以高速开始低速结束。 右边的动画展示了 ease-out
效果(蓝色的元素)和 linear
效果(红色的元素)的区别。 同样的,ease-out
预定义值也可以用贝塞尔曲线函数实现。
通俗的讲,将一条直线放在范围只有 1 的坐标轴中,并从中间拿 p1
和 p2
两个点来拉扯(X 轴的取值区间是 [0, 1],Y 轴任意),最后形成的曲线就是动画的贝塞尔速度曲线。 下面是一个使用值来模仿 ease-out
样式的 Bezier 曲线示例:
animation-timing-function: cubic-bezier(0, 0, 0.58, 1);
记住所有的 cubic-bezier
函数都是从坐标为 (0, 0) 的 p0
开始,在坐标为 (1, 1) 的 p3
结束。 在这个例子里,曲线在 y 轴(从 0 开始,运动到 p1
的 0,然后运动到 p2
的 1)上移动得比在 x 轴(从 0 开始,运动到 p1
的 0,到 p2
的 0.58)上移动得快。 结果是,在这一段动画内元素运动得快。 到曲线的结尾,x 和 y 之间的关系反过来了,y 值保持为 1,没有变化,x 值从 0.58 变为 1,元素运动得慢。
为了看贝塞尔曲线的运动效果,把 id 为 red
的元素的 animation-timing-function
属性改为 cubic-bezier
函数,其中 x1,y1,x2,y2 值分别为 0、0、0.58、1。 这会使两个元素运动过程类似。
<style>
.balls{
border-radius: 50%;
position: fixed;
width: 50px;
height: 50px;
margin-top: 50px;
animation-name: bounce;
animation-duration: 2s;
animation-iteration-count: infinite;
}
#red {
background: red;
left: 27%;
animation-timing-function: cubic-bezier(0, 0, 0.58, 1);;
}
#blue {
background: blue;
left: 56%;
animation-timing-function: ease-out;
}
@keyframes bounce {
0% {
top: 0px;
}
100% {
top: 249px;
}
}
</style>
<div class="balls" id= "red"></div>
<div class="balls" id= "blue"></div>
在这个挑战中,我们需要给元素添加动画来模拟杂耍中被抛接的球。 之前的挑战中,我们学习了 linear
和 ease-out
的贝塞尔曲线描述,但这两个都无法完美地描述杂耍球的运动。 在本关里你需要定制贝塞尔曲线。
当 animation-iteration-count
值为 infinite 时,animation-timing-function
会自动循环 keyframe。 由于我们是在动画周期的中间点(50%
处)设置的 keyframe 规则,最终的结果是球向上和球向下是两个同样的动画过程。
下面的例子模拟了杂耍球运动:
cubic-bezier(0.3, 0.4, 0.5, 1.6);
注意 y2 的值是大于 1 的。 虽然贝塞尔曲线是在 1*1 的坐标系统内,x 值只能在 0 到 1,但是 y 值是可以大于 1 的。 这样才能模拟杂耍球运动。
把 id 为 green
的元素的 animation-timing-function
值改成 cubic-bezier
函数,函数的参数 x1,y1,x2,y2 值依次为 0.311、0.441、0.444、1.649。
<style>
.balls {
border-radius: 50%;
position: fixed;
width: 50px;
height: 50px;
top: 60%;
animation-name: jump;
animation-duration: 2s;
animation-iteration-count: infinite;
}
#red {
background: red;
left: 25%;
animation-timing-function: linear;
}
#blue {
background: blue;
left: 50%;
animation-timing-function: ease-out;
}
#green {
background: green;
left: 75%;
animation-timing-function: cubic-bezier(0.311, 0.411, 0.444, 1.649);
}
@keyframes jump {
50% {
top: 10%;
}
}
</style>
<div class="balls" id="red"></div>
<div class="balls" id="blue"></div>
<div class="balls" id="green"></div>