StyleSheet/CSS
CSS3 : Modal Animation
jaiyah
2017. 2. 21. 11:24
레이어 팝업 CSS3 애니메이션
CSS3 를 이용한 모달 애니메이션에 대해 살펴보도록 합니다.
소스는 코드펜의 css 를 참고하세요.
Modal Animation Source
See the Pen 모달 애니메이션 by jaeheekim (@jaehee) on CodePen.
css
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
min-height: 100%;
height: 100%;
font-family: helvetica neue, helvetica, arial, sans-serif;
}
.content {
min-height: 100%;
height: 100%;
background: #fff;
position: relative;
z-index: 0;
}
.content h1 {
padding: 75px 0 30px 0;
text-align: center;
font-size: 30px;
line-height: 30px;
}
.content .buttons {
max-width: 800px;
margin: 0 auto;
text-align: center;
}
.content .buttons .button {
display: inline-block;
text-align: center;
text-decoration: none;
background: #efefef;
padding: 10px 15px;
margin: 10px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
color: #333;
font-weight: bold;
}
.content .buttons .button:hover {
color: #fff;
background: #009bd5;
}
/* modal style */
html.modal-active,
body.modal-active {
overflow: hidden;
}
#modal-container {
position: fixed;
left: 0;
top: 0;
display: table;
height: 100%;
width: 100%;
z-index: 1;
/* hidden 처리 */
transform: scale(0);
}
#modal-container .modal-background {
display: table-cell;
background: rgba(0, 0, 0, .8);
text-align: center;
vertical-align: middle;
}
#modal-container .modal-background .modal {
background: #fff;
padding: 50px;
display: inline-block;
border-radius: 3px;
position: relative;
}
#modal-container .modal-background .modal h2 {
font-size: 25px;
line-height: 25px;
margin-bottom: 15px;
}
#modal-container .modal-background .modal p {
font-size: 18px;
line-height: 22px;
}
/*
* ------------------------------
* Unfolding Animation
* ------------------------------
*/
#modal-container.one {
/*transform: scaleX(0) scaleY(1);*/
animation: unfoldIn 1s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.one .modal-background .modal {
/* 초기 display: none 처럼 크기를 0 으로 하여 보여주지 않음*/
transform: scale(0);
/* 0.5 초 동안 애니메이션을 실행, 단 0.8초 지연시켜 0.8초 후에 애니메이션을 실행 */
animation: zoomIn .5s .8s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.one.out {
transform: scale(1);
animation: unfoldOut 1s .3s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.one.out .modal-background .modal {
animation: zoomOut 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
/* Dimmed showing */
@keyframes unfoldIn {
0% {
transform: scaleX(0) scaleY(0.005);
}
50% {
/* 0.5 초간 세로 크기는 작은상태로 가로 너비만 확대 */
transform: scaleX(1) scaleY(0.005);
}
100% {
/* 0.5 초간 세로 크기를 확대 */
transform: scaleY(1) scaleX(1);
}
}
/* Show modal content */
@keyframes zoomIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
/* Hide modal content */
@keyframes zoomOut {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
/* Dimmed hiding */
@keyframes unfoldOut {
0% {
transform: scale(1)
}
50% {
transform: scaleX(1) scaleY(0.005);
}
100% {
transform: scaleX(0) scaleY(0.005);
}
}
/*
* ------------------------------
* Revealing Animation
* ------------------------------
*/
#modal-container.two {
transform: scale(1);
}
#modal-container.two .modal-background {
background: transparent;
animation: fadeIn .5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.two .modal-background .modal {
/* 콘텐츠를 초기에 보여주지 않음 */
opacity: 0;
animation: scaleUp 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
.content.two {
/* 콘텐츠 크기를 줄임 */
animation: scaleBack 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.two.out {
/* 전체 모달 컨테이너를 숨김 처리(다른 애니메이션이 모두 끝난 0.5초 후에 처리하기 위해 0.5초 지연시킴 */
animation: quickScaleDown 0s .5s linear forwards;
}
#modal-container.two.out .modal-background {
animation: fadeOut 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.two.out .modal-background .modal {
animation: scaleDown 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
.content.two.out {
animation: scaleForward 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
/* Dimmed showing */
@keyframes fadeIn {
0% {
background: transparent;
}
100% {
background: rgba(0, 0, 0, .7);
}
}
/* Show modal content from bottom to top */
@keyframes scaleUp {
0% {
/* 모달 콘텐츠를 하단에 위치시킴 */
transform: scale(.8) translateY(1000px);
opacity: 0;
}
100% {
/* 모달 콘텐츠를 본래 위치로 돌려놓음 */
transform: scale(1) translateY(0);
opacity: 1;
}
}
/* Shrink content */
@keyframes scaleBack {
0% {
transform: scale(1);
}
100% {
transform: scale(.8);
}
}
/* Hide modal container*/
@keyframes quickScaleDown {
0% {
transform: scale(1);
}
99.9% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
/* Dimmed hiding */
@keyframes fadeOut {
0% {
background: rgba(0, 0, 0, .7);
}
100% {
background: transparent;
}
}
/* modal content from top to bottom */
@keyframes scaleDown {
0% {
transform: scale(1) translateY(0);
opacity: 1;
}
100% {
transform: scale(.8) translateY(1000px);
opacity: 0;
}
}
@keyframes scaleBack {
0% {
transform: scale(1);
}
100% {
transform: scale(.85);
}
}
@keyframes scaleForward {
0% {
transform: scale(0.85);
}
100% {
transform: scale(1);
}
}
/*
* ------------------------------
* Uncovering Animation
* ------------------------------
*/
#modal-container.three {
z-index: 0;
transform: scale(1);
}
#modal-container.three .modal-background {
background: rgba(0, 0, 0, .9);
}
#modal-container.three .modal-background .modal {
animation: moveUp 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
.content.three {
z-index: 1;
animation: slideUpLarge 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.three.out .modal-background .modal {
animation: moveDown 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
.content.three.out {
animation: slideDownLarge 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
/* Show Modal content*/
@keyframes moveUp {
/* 하단에서 */
0% {
transform: translateY(200px);
}
/* 중앙으로 위치 */
100% {
transform: translateY(0);
}
}
/* Slide up Content */
@keyframes slideUpLarge {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
/* Hide Modal content */
@keyframes moveDown {
/* 중앙에 있는 모달 콘텐츠를 */
0% {
transform: translateY(0);
}
/* 하단으로 위치 */
100% {
transform: translateY(200px);
}
}
/* Slide down content */
@keyframes slideDownLarge {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0);
}
}
/*
* ------------------------------
* Blow Up Animation
* ------------------------------
*/
#modal-container.four {
z-index: 0;
transform: scale(1);
}
#modal-container.four .modal-background {
background: rgba(0, 0, 0, 0.9);
}
#modal-container.four .modal-background .modal {
animation: blowUpModal 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
.content.four {
z-index: 1;
animation: blowUpContent 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.four.out .modal-background .modal {
animation: blowUpModalTwo 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
.content.four.out {
animation: blowUpContentTwo 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
/* Show modal content */
@keyframes blowUpModal {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
/* Hide content */
@keyframes blowUpContent {
0% {
transform: scale(1);
opacity: 1;
}
/* 원본 크기에서 2배로 커지면서 투명도를 서서히 낮춤 */
99.9% {
transform: scale(2);
opacity: 0;
}
/* 마지막에 숨김 처리 */
100% {
transform: scale(0);
}
}
/* Hide modal content */
@keyframes blowUpModalTwo {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(0);
opacity: 0;
}
}
/* Show content */
@keyframes blowUpContentTwo {
0% {
transform: scale(2);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
/*
* ------------------------------
* Meep Meep Animation
* ------------------------------
*/
#modal-container.five {
transform: scale(1);
}
#modal-container.five .modal-background {
background: transparent;
animation: fadeIn 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.five .modal-background .modal {
transform: translateX(-1500px);
animation: roadRunnerIn 0.3s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.five.out {
animation: quickScaleDown 0s .5s linear forwards;
}
#modal-container.five.out .modal-background {
animation: fadeOut 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.five.out .modal-background .modal {
animation: roadRunnerOut 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
/* 모달 콘텐츠 반동 효과로 나타나기 */
@keyframes roadRunnerIn {
0% {
transform: translateX(-1500px) skewX(30deg) scaleX(1.3);
}
70% {
transform: translateX(50px) skewX(0deg) scaleX(0.9);
}
100% {
transform: translateX(0px) skewX(0deg) scaleX(1);
}
}
/* 모달 콘텐츠 반동 효과로 숨기기 */
@keyframes roadRunnerOut {
0% {
transform: translateX(0px) skewX(0deg) scaleX(1);
}
30% {
transform: translateX(-100px) skewX(-5deg) scaleX(0.9);
}
100% {
transform: translateX(1500px) skewX(30deg) scaleX(1.3);
}
}
/*
* ------------------------------
* James Bond Animation
* ------------------------------
*/
#modal-container.six {
transform: scale(1);
}
#modal-container.six .modal-background {
background: transparent;
animation: fadeIn 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.six .modal-background .modal {
/* 초기 모달 콘텐츠 크기 및 라운드 정의 */
width: 200px;
height: 200px;
border-radius: 100%;
overflow: hidden;
animation: JamesBond 1.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.six .modal-background .modal h2,
#modal-container.six .modal-background .modal p {
/* 콘텐츠 내용 숨김 */
opacity: 0;
position: relative;
/* 원형 모달이 본래 모양을 완성된 후 1.4 지연후에 보여줌 */
animation: modalContentFadeIn .5s 1.4s linear forwards;
}
#modal-container.six.out {
animation: slowFade .5s 1.5s linear forwards;
}
#modal-container.six.out .modal-background {
background-color: rgba(0, 0, 0, 0.7);
animation: fadeToRed 2s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.six.out .modal-background .modal {
border-radius: 3px;
height: 162px;
width: 227px;
animation: killShot 1s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.six.out .modal-background .modal h2,
#modal-container.six.out .modal-background .modal p {
animation: modalContentFadeOut 0.5s 0.5 cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
/* Show modal content : round shape */
@keyframes JamesBond {
0% {
transform: translateX(1000px);
}
80% {
transform: translateX(0px);
width: 150px;
height: 150px;
border-radius: 100%;
}
90% {
border-radius: 3px;
width: 340px;
height: 240px;
}
100% {
border-radius: 3px;
width: 300px;
height: 200px;
}
}
/* 모달 콘텐츠 내의 요소 효과 처리 */
@keyframes modalContentFadeIn {
0% {
opacity: 0;
top: -20px;
}
100% {
opacity: 1;
top: 0;
}
}
/* 전체 모달 컨테이너 숨김처리 */
@keyframes slowFade {
0% {
opacity: 1;
}
99.9% {
opacity: 0;
transform: scale(1);
}
100% {
transform: scale(0);
}
}
/* 박스 그림자를 이용한 효과 */
@keyframes fadeToRed {
0% {
box-shadow: inset 0 0 0 rgba(201, 24, 24, 0.8);
}
100% {
/* y 축 박스 그림자를 위에서부터 아래로 내리는 효과 */
box-shadow: inset 0 2000px 0 rgba(201, 24, 24, 0.8);
}
}
/* 모달 콘텐츠 비스듬히 하단으로 떨어뜨림 */
@keyframes killShot {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
}
100% {
/* 하단으로 회전시켜 떨어뜨림 */
transform: translateY(400px) rotate(45deg);
opacity: 0;
}
}
/* 모달 콘텐츠가 떨어질 때 효과처리 */
@keyframes modalContentFadeOut {
0% {
opacity: 1;
top: 0;
}
100% {
opacity: 0;
top: -20px;
}
}
Jaehee's WebClub