这是一款4种效果非常炫酷的纯CSS3页面切换过渡动画特效。该CSS3页面过渡动画使用CSS keyframes制作而成,所有的动画效果和延时都是使用CSS属性,没有任何的javascript timeout()代码。
所有的4个页面切换效果都使用相同的js文件(用于点击事件和页面关闭事件)和CSS文件。每个demo的class名称略有区别。所有的demo都在 Chrome、Safari、Firefox、Opera、IE11 和 IE10浏览器上做了测试(还有iOS也做了测试)。下面文章中的代码没有添加浏览器厂商的前缀,实际代码中需要添加-webkit-和-moz-前缀, Opera 和 IE10+浏览器不需要添加厂商的前缀。关于浏览器厂商的前缀你可以阅读W3C关于vendor prefixes的资料。
关于基本的CSS3 Animation
CSS3的keyframes属性可以让我们非常方便的在某个时间内控制某个元素的CSS样式。你可以控制动画的开始时间为0%,结束时间为100%。关键字from和to等效于0%和100%。由于兼容性的原因,请确保动画的起始和结束时间值总是0%和100%。
CSS keyframes的语法格式
CSS keyframes的语法格式如下:
/* Percentage */
@keyframes moveTop {
0% { top: 0px; }
100% { top: 100px; }
}
/* From -> To */
@keyframes moveTop {
from { top: 0px; }
to { top: 100px; }
}
在声明了上面的语句之后,你可以通过animation属性为任何元素添加moveTop动画规则。关于CSS3 animations可以阅读W3C的CSS3 animations相关文档。
CSS animation语法格式
CSS animation语法格式如下:
.animated { animation: moveTop 2s 3; }
上面的语句将在.animated元素上执行moveTop帧动画,动画在2秒时间内执行3次。
制作方法
下面将以第一种效果为例讲解这些页面加载过渡动画效果的制作方法。
HTML结构
第一个DEMO的HTML结构十分简单,4个导航按钮放置在<nav>元素中,<section>元素中的内容时要切换的页面内容,默认是隐藏的。
<!-- Navigation -->
<nav class="nav clearfix">
<button class="nav-el" id="el-topleft" data-id="ov-topleft">
<span class="icon-heart"></span>
</button>
...
</nav>
<!-- Overlays -->
<section class="overlay" id="ov-topleft">
<div class="wrap">
<h1>Section 1</h1>
<p>Lorem ipsum dolor sit amet...</p>
</div>
<button class="close"><span class="mfg-cancel"></span></button>
</section>
<section class="overlay" id="ov-topright">
<div class="wrap">
<h1>Section 2</h1>
<p>Lorem ipsum dolor sit amet...</p>
</div>
<button class="close"><span class="mfg-cancel"></span></button>
</section>
代码中为导航按钮使用了data attribute属性用于和它们各自的遮罩页面相关联。这些将在后面使用js来处理。
CSS样式
下面是导航按钮的一些基本样式。这些按钮分别是一个大的矩形,中间放置一个图标。它们被设计为响应式的布局方式。并且为每一个按钮制定.active、.active_reverse和.inactive状态下的样式。
.nav {
width: 80%;
max-width: 420px;
margin: 90px auto 90px;
font-size: 33px;
}
/* Nav elements */
.nav-el {
position:relative;
display: inline-block;
float: right;
width: 47.5%;
padding-bottom: 47.5%;
color: white;
background-color: #16a085;
transition: background-color .3s ease-in;
z-index: 10;
}
.nav-el:hover, .nav-el.active {
background-color: #107360;
}
.nav-el.active_reverse {
background-color: transparent;
}
/* Active button always on top */
.nav-el.active, .nav-el.active_reverse {
z-index: 11;
}
/* Prevent click/hover on inactive buttons */
.nav-el.inactive {
pointer-events: none;
cursor: default;
}
/* Specific floating and margin */
.nav-el:nth-of-type(2n+1) { float: left; }
.nav-el:nth-of-type(n+3) { margin-top: 5%; }
/* Icons are horizontally/vertically centered */
[class^="icon-"], [class*=" icon-"] {
position: absolute;
display: inline-block;
top: 50%;
left: 50%;
line-height: 0;
width: 1em;
所有的遮罩层都是固定定位,默认情况下是隐藏的。
/* Overlay */
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
z-index: 9999;
visibility: hidden;
}
.close {
position: absolute;
top: 50px;
right: 50px;
font-size: 36px;
}
还有一个额外的在<body>元素隐藏遮罩层的class noscroll,稍后会用到它:
.noscroll {
overflow: hidden;
height: 100%;
width: 100%;
}
CSS3 Animations动画
激活状态
这个状态时整个页面过渡动画的核心,它在1.6秒时间内将页面中所有的动画元素进行一次动画:
- 当每一个按钮被点击之后的动画
- 当另一个按钮被点击之后其它按钮的动画
- 按钮点击之后的遮罩层效果
当使用CSS animation或transition来移动一个元素的时候,都会使用到translate3d属性。这种方式会大大增加用户体验度,但是对浏览器的性能要求会有所提高。
@keyframes fx-el_topleft-active {
0% {}
16% { transform: translate3d(-27.5%, -27.5%, 0); }
50% { transform: translate3d(55.1%, 55.1%, 0) scale(1); color: #FFF;}
62% { color: transparent; }
100% { transform: translate3d(55.1%, 55.1%, 0) scale(20); color: transparent; }
}
@keyframes fx-el_topright-active {
0% {}
16% { transform: translate3d(27.5%, -27.5%, 0); }
50% { transform: translate3d(-55.1%, 55.1%, 0) scale(1); color: #FFF;}
62% { color: transparent; }
100% { transform: translate3d(-55.1%, 55.1%, 0) scale(20); color: transparent; }
}
@keyframes fx-el_btmleft-active {
0% {}
16% { transform: translate3d(-27.5%, 27.5%, 0); }
50% { transform: translate3d(55.1%, -55.1%, 0) scale(1); color: #FFF;}
62% { color: transparent; }
100% { transform: translate3d(55.1%, -55.1%, 0) scale(20); color: transparent;}
}
@keyframes fx-el_btmright-active {
0% {}
16% { transform: translate3d(27.5%, 27.5%, 0); }
50% { transform: translate3d(-55.1%, -55.1%, 0) scale(1); color: #FFF;}
62% { color: transparent; }
100% { transform: translate3d(-55.1%, -55.1%, 0) scale(20); color: transparent; }
}
#el-topleft.active {
animation: fx-el_topleft-active 1.6s 1 ease-in-out;
}
#el-topright.active {
animation: fx-el_topright-active 1.6s 1 ease-in-out;
}
#el-btmleft.active {
animation: fx-el_btmleft-active 1.6s 1 ease-in-out;
}
#el-btmright.active {
animation: fx-el_btmright-active 1.6s 1 ease-in-out;
}
下面是没有被点击的按钮的动画。它们以相同的方式移动,最终被隐藏(opacity: 0)。
@keyframes fx-el_topleft-inactive {
0% { transform: translate3d(0%, 0%, 0); opacity: 1; }
16% { transform: translate3d(-27.5%, -27.5%, 0);opacity: 1; }
40% { opacity: 0;}
50% { transform: translate3d(55.1%, 55.1%, 0); }
100% { transform: translate3d(55.1%, 55.1%, 0); opacity: 0; }
}
@keyframes fx-el_topright-inactive {
0% { transform: translate3d(0%, 0%, 0); opacity: 1; }
16% { transform: translate3d(27.5%, -27.5%, 0); opacity: 1; }
40% { opacity: 0;}
50% { transform: translate3d(-55.1%, 55.1%, 0); }
100% { transform: translate3d(-55.1%, 55.1%, 0); opacity: 0; }
}
@keyframes fx-el_btmleft-inactive {
0% { transform: translate3d(0%, 0%, 0); opacity: 1; }
16% { transform: translate3d(-27.5%, 27.5%, 0); opacity: 1; }
40% { opacity: 0;}
50% { transform: translate3d(55.1%, -55.1%, 0); }
100% { transform: translate3d(55.1%, -55.1%, 0); opacity: 0; }
}
@keyframes fx-el_btmright-inactive {
0% { transform: translate3d(0%, 0%, 0); opacity: 1; }
16% { transform: translate3d(27.5%, 27.5%, 0); opacity: 1; }
40% { opacity: 0;}
50% { transform: translate3d(-55.1%, -55.1%, 0); }
100% { transform: translate3d(-55.1%, -55.1%, 0); opacity: 0; }
}
#el-topleft.inactive {
animation: fx-el_topleft-inactive 1.6s 1 ease-in-out;
}
#el-topright.inactive {
animation: fx-el_topright-inactive 1.6s 1 ease-in-out;
}
#el-btmleft.inactive {
animation: fx-el_btmleft-inactive 1.6s 1 ease-in-out;
}
#el-btmright.inactive {
animation: fx-el_btmright-inactive 1.6s 1 ease-in-out;
}
接下来是遮罩层的动画效果,代码非常容易理解。
@keyframes fx-overlay {
0% { visibility: visible; color: transparent; }
50% { background-color: #107360; color: white; }
100% { visibility: visible; background-color: #107360; color: #FFF; }
}
.overlay.active {
animation: fx-overlay .8s 1.25s 1 ease-in-out forwards;
}
遮罩层的动画延时时间为1.25秒,这将使遮罩层的内容在按钮动画结束之后才显示出来。forwards属性时指定动画结束的时间值,在这里表示保存遮罩层一直可见。
Active_reverse 状态
当用户点击遮罩层上的关闭按钮时,会使用该状态来反向执行动画:遮罩层消失,按钮回到原来的位置上。
@keyframes fx-el_topleft-active_reverse {
0% { transform: translate3d(55.1%, 55.1%, 0) scale(20);
color: transparent; background-color: #107360; }
38% { color: transparent;}
50% { transform: translate3d(55.1%, 55.1%, 0) scale(1); color: #FFF; background-color: #107360; }
82% { transform: translate3d(-27.5%, -27.5%, 0); background-color: #16a085;}
100% { transform: translate3d(0%, 0%, 0); }
}
@keyframes fx-el_topright-active_reverse {
0% { transform: translate3d(-55.1%, 55.1%, 0) scale(20);
color: transparent; background-color: #107360; }
38% { color: transparent; }
50% { transform: translate3d(-55.1%, 55.1%, 0) scale(1); color: #FFF; background-color: #107360;}
82% { transform: translate3d(27.5%, -27.5%, 0); background-color: #16a085;}
100% { transform: translate3d(0%, 0%, 0); }
}
@keyframes fx-el_btmleft-active_reverse {
0% { transform: translate3d(55.1%, -55.1%, 0) scale(20);
color: transparent; background-color: #107360; }
38% { color: transparent; }
50% { transform: translate3d(55.1%, -55.1%, 0) scale(1); color: #FFF; background-color: #107360;}
82% { transform: translate3d(-27.5%, 27.5%, 0); background-color: #16a085;}
100% { transform: translate3d(0%, 0%, 0); }
}
@keyframes fx-el_btmright-active_reverse {
0% { transform: translate3d(-55.1%, -55.1%, 0) scale(20);
color: transparent; background-color: #107360; }
38% { color: transparent; }
50% { transform: translate3d(-55.1%, -55.1%, 0) scale(1); color: #FFF; background-color: #107360;}
82% { transform: translate3d(27.5%, 27.5%, 0); background-color: #16a085;}
100% { transform: translate3d(0%, 0%, 0); }
}
#el-topleft.active_reverse {
animation: fx-el_topleft-active_reverse 1.6s 1 ease-in-out;
}
#el-topright.active_reverse {
animation: fx-el_topright-active_reverse 1.6s 1 ease-in-out;
}
#el-btmleft.active_reverse {
animation: fx-el_btmleft-active_reverse 1.6s 1 ease-in-out;
}
#el-btmright.active_reverse {
animation: fx-el_btmright-active_reverse 1.6s 1 ease-in-out;
}
未被点击的按钮的反向动画代码如下:
@keyframes fx-el_topleft-inactive_reverse {
0% { transform: translate3d(55.1%, 55.1%, 0); opacity: 0; }
50% { transform: translate3d(55.1%, 55.1%, 0); }
82% { transform: translate3d(-27.5%, -27.5%, 0); }
45% { opacity: 0; }
100% { transform: translate3d(0%, 0%, 0); opacity: 1; }
}
@keyframes fx-el_topright-inactive_reverse {
0% { transform: translate3d(-55.1%, 55.1%, 0); opacity: 0; }
50% { transform: translate3d(-55.1%, 55.1%, 0); }
82% { transform: translate3d(27.5%, -27.5%, 0); }
45% { opacity: 0; }
100% { transform: translate3d(0%, 0%, 0);opacity: 1; }
}
@keyframes fx-el_btmleft-inactive_reverse {
0% { transform: translate3d(55.1%, -55.1%, 0); opacity: 0; }
50% { transform: translate3d(55.1%, -55.1%, 0); }
82% { transform: translate3d(-27.5%, 27.5%, 0); }
45% { opacity: 0; }
100% { transform: translate3d(0%, 0%, 0);opacity: 1; }
}
@keyframes fx-el_btmright-inactive_reverse {
0% { transform: translate3d(-55.1%, -55.1%, 0); opacity: 0; }
50% { transform: translate3d(-55.1%, -55.1%, 0); }
82% { transform: translate3d(27.5%, 27.5%, 0); }
45% { opacity: 0; }
100% { transform: translate3d(0%, 0%, 0); opacity: 1; }
}
#el-topleft.inactive_reverse {
animation: fx-el_topleft-inactive_reverse 1.6s 1 ease-in-out;
}
#el-topright.inactive_reverse {
animation: fx-el_topright-inactive_reverse 1.6s 1 ease-in-out;
}
#el-btmleft.inactive_reverse {
animation: fx-el_btmleft-inactive_reverse 1.6s 1 ease-in-out;
}
#el-btmright.inactive_reverse {
animation: fx-el_btmright-inactive_reverse 1.6s 1 ease-in-out;
}
遮罩层的反向动画代码如下:
@keyframes fx-overlay-reverse {
0% { visibility: visible; background-color: #107360; color: #FFF;}
40% { background-color: #107360; color: transparent;}
85% {background-color: transparent; }
100% {visibility: invisible; color: transparent; background-color: transparent; }
}
.overlay.active_reverse {
animation: fx-overlay-reverse .8s 1 ease-in backwards;
}
Backwards属性的作用和forwards属性类似。当它应用到目标元素上时,动画会将这些值应用到第一个关键帧上。