这是我参与更文挑战的第7天,活动详情查看: 更文挑战
Flex Panels Image Gallery
一、效果展示
今天的这部分内容实现的效果就是,当点击任逸一张图片的时候,图片展开,同时文字从图片的上下两侧划入,再次点击展开的图片,图片会被压缩成之前的样子,同时文字被挤走,恢复原样。
1.index-START.html
2.index-FINISHED.html
3.我的最终效果
二、实现
最终代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex Panels ?</title>
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
</head>
<body>
<style>
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}
.panel {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
}
.panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
.panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
/* Flex Children */
.panel > * {
flex: 1;
margin: 0;
width: 100%;
transition: transform 0.5s;
}
.panel p {
display: flex;
justify-content: center;
text-transform: uppercase;
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
.panel >*:first-child {
transform: translateY(-100%);
}
.panel >*:last-child {
transform: translateY(100%);
}
.panel.open-active>*:first-child {
transform: translateY(0%);
}
.panel.open-active >*:last-child {
transform: translateY(0%);
}
.panel p:nth-child(1) {
display: flex;
align-items: flex-end;
}
.panel p:nth-child(2) {
font-size: 4em;
align-items: center;
}
.panel.open {
font-size: 40px;
flex: 5;
}
</style>
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
<script>
;(function(){
const panels = document.querySelectorAll(".panel")
function clickHandler(){
this.classList.toggle("open");
}
function transionHandler(e){
if(e.propertyName.indexOf('flex') !== -1){
this.classList.toggle("open-active")
}
}
panels.forEach(panel =>{
panel.addEventListener("click",clickHandler);
panel.addEventListener("transitionend",transionHandler)
})
})()
</script>
</body>
</html>
复制代码
三、总结回顾
这个案例里边我们主要要掌握三个关键点:
Flex 弹性布局
CSS class样式的切换
transition 动画事件的处理
当然用了 Flex 布局主要是因为方便,但是 float 大家也不能就丢弃了,有些情景下还是要用到 float 去做样式排版的。
过程分解
1.将初始化页面变为 Flex 布局
原作者给的初始化页面的显示和最终的显示并不是一样的,因为一开始的页面的布局是 display:block; 所以整个模块就是一排一排的往下排。
我们要将页面变为横向排列,这个时候我们就要用到 Flex 布局。
.panels {
min-height: 100vh;
overflow: hidden;
//改为flex布局
display: flex;
}
.panel {
//铺满页面,每一块都是一份
flex: 1;
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
}
复制代码
然后我们现在的页面是这样的:
但是我们发现,我们现在的文字是不居中的,所以下一步我们就要将文字居中
- 垂直居中文字
.panel {
flex: 1;
//-----------
display: flex;
flex-direction: column;
justify-content: center;
//-----------
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
}
/* Flex Children */
.panel > * {
//-----------
flex: 1;
//-----------
margin: 0;
width: 100%;
transition: transform 0.5s;
}
.panel p {
//-----------
display: flex;
justify-content: center;
//-----------
text-transform: uppercase;
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
//-----------
.panel p:nth-child(1) {
display: flex;
align-items: flex-end;
}
//-----------
.panel p:nth-child(2) {
font-size: 4em;
//-----------
align-items: center;
//-----------
}
复制代码
然后实现了这样的效果:
现在我们的文字已经垂直居中了,但是我们初始化的时候了,上下两侧的文字是消失。
- 上下两侧的文字初始化消失
.panel >*:first-child {
transform: translateY(-100%);
}
.panel >*:last-child {
transform: translateY(100%);
}
复制代码
这样我们两侧的文字现在已经是消失状态了
- JavaScript 事件
这里我们可分为两个动画事件:
(1) 放大和还原动画;
(2)两侧文字的显示。
先实现第一个动画。
我们上面将这五份每一个都当成了一份,现在我们要在实现展开放大的时候,那么我们就要将每一份放大成大于一的份数,我这里设置成了5.
.panel.open {
font-size: 40px;
flex: 5;
}
;(function(){
const panels = document.querySelectorAll(".panel")
function clickHandler(){
this.classList.toggle("open");
}
panels.forEach(panel =>{
panel.addEventListener("click",clickHandler);
})
})()
复制代码
这个时候实现了我们的动画第一步,就不做展示了,可自行尝试,我们继续。
实现第二段动画的时候,我们就要用到 transionend 事件了。
.panel.open-active>*:first-child {
transform: translateY(0%);
}
.panel.open-active >*:last-child {
transform: translateY(0%);
}
复制代码
function transionHandler(e){
if(e.propertyName.indexOf('flex') !== -1){
this.classList.toggle("open-active")
}
}
panels.forEach(panel =>{
panel.addEventListener("click",clickHandler);
panel.addEventListener("transitionend",transionHandler)
})
复制代码
四、重难点
就这个案例而言的话,其实并没有什么难点需要注意的,主要的话还是重点巩固一下 Flex 弹性布局。
下面贴一下阮一峰老师的 Flex 学习网址,总结的非常到位,跟着这个文档走一遍,相信你对 Flex 布局的学习将会有一个全面的了解并且会掌握它的使用。
地址:www.ruanyifeng.com/blog/2015/0…
但是,还有个布局样式排版,那就是 Grid 布局,如果有兴趣的可以去做一个学习,用起来也是非常方便的。