2.11 CSS3 Effect

그림자, 그레이디언트, 트랜지션, 애니메이션, 트랜스폼

1. 벤더 프리픽스 (Vendor Prefix)

CSS3 표준이 확정되기 이전 또는 브라우저 개발사가 실험적으로 제공하는 기능을 사용하기 위해서는 벤더 프리픽스를 사용하여야 한다.

Can I use? 에서 제공하는 브라우저별 CSS 지원 정보를 보면 텍스트와 요소의 선택을 방지하는 user-select 속성은 모든 브라우저에 벤더 프리픽스를 사용하여야 한다. 브라우저의 버전이 올라감에 따라 벤더 프리픽스를 사용하지 않아도 될 수 있다. 그러나 구형 브라우저를 지원하기 위하여 벤더 프리픽스를 사용하여야 할 필요가 있다.

caniuse screen shot

2016년 3월 기준

* {
  -webkit-user-select: none;  /* Chrome all / Safari all */
  -moz-user-select: none;     /* Firefox all */
  -ms-user-select: none;      /* IE 10+ */
  user-select: none;          /* Likely future */
}

vendor-prefix in chrome-devtool

브라우저 별 벤더 프리픽스는 다음과 같다.

Browser Vendor Prefix
IE or Edge -ms-
Chrome -webkit-
Firefox -moz-
Safari -webkit-
Opera -o-
iOS Safari -webkit-
Android Browser -webkit-
Chrome for Android -webkit-

많은 브라우저를 위한 벤더 프리픽스를 사용하는 것은 코드의 양을 늘게 하고 또한 브라우저는 거의 매달 업데이트가 이루어지고 있어 불필요한 벤더 프리픽스를 사용할 가능성이 크다. 사용하지 않아도 되는 벤더 프리픽스를 사용하는 것은 성능에도 영향을 주기 때문에 Prefix Free 라이브러리 를 사용하는 것은 매우 유용한 방법이다.

사용법은 매우 간단하다. Prefix Free 사이트에서 라이브러리를 다운로드하고 include 하기만 하면 이 후에는 벤더 프리픽스없이 모든 CSS를 사용할 수 있다.

<script src="prefixfree.min.js"></script>

2. 그림자 (Shadow)

텍스트나 요소에 그림자 효과를 부여하는 속성이다.

shadow effect

2.1 text-shadow

텍스트에 그림자 효과를 부여하는 속성이다.

선택자 { text-shadow: Horizontal-offset Vertical-offset Blur-Radius Shadow-Color; }
속성값 단위 설명 생략
Horizontal-offset px 그림자를 텍스트의 오른쪽으로 지정값만큼 이동시킨다  
Vertical-offset px 그림자를 텍스트의 아래로 지정값만큼 이동시킨다  
Blur-Radius px 그림자의 흐림정도를 지정한다. 지정값만큼 그림자가 커지고 흐려진다. (양수) 가능
Shadow-Color color 그림자의 색상을 지정한다 가능
<!DOCTYPE html>
<html>
<head>
  <style>
    h1:nth-child(1) {
      text-shadow: 5px 5px;
    }
    h1:nth-child(2) {
      text-shadow: 5px 5px red;
    }
    h1:nth-child(3) {
      text-shadow: 5px 5px 3px red;
    }
    h1:nth-child(4) {
      color: white;
      text-shadow: 5px 5px 3px black;
    }
    h1:nth-child(5) {
      text-shadow: 0 0 3px red;
    }
    /*Multiple Shadows*/
    h1:nth-child(6) {
      text-shadow: 0 0 3px red, 0 0 10px blue;
    }
    /*Multiple Shadows*/
    h1:nth-child(7) {
      color: white;
      text-shadow: 1px 1px 2px black, 0 0 25px blue, 0 0 5px darkblue;
    }
  </style>
</head>
<body>
  <h1>Text-shadow effect!</h1>
  <h1>Text-shadow effect!</h1>
  <h1>Text-shadow effect!</h1>
  <h1>Text-shadow effect!</h1>
  <h1>Text-shadow effect!</h1>
  <h1>Text-shadow effect!</h1>
  <h1>Text-shadow effect!</h1>
</body>
</html>
Property Chrome Edge IE Firefox Safari Opera
text-shadow 4.0 12.0 10.0 3.5 4.0 9.5

2.2 box-shadow

요소에 그림자 효과를 부여하는 속성이다.

선택자 { box-shadow: Inset Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color; }
속성값 단위 설명 생략
Inset inset inset 키워드를 지정하면 그림자가 요소 안쪽에 위치한다. 가능
Horizontal-offset px 그림자를 텍스트의 오른쪽으로 지정값만큼 이동시킨다  
Vertical-offset px 그림자를 텍스트의 아래로 지정값만큼 이동시킨다  
Blur-Radius px 그림자의 흐림정도를 지정한다. 지정값만큼 그림자가 커지고 흐려진다. (양수) 가능
Spread px 그림자를 더 크게 확장시킨다. (음수, 양수) 가능
Shadow-Color color 그림자의 색상을 지정한다 가능
<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 300px;
      height: 100px;
      padding: 15px;
      margin: 20px;
      background-color: yellow;
    }
    /*box-shadow: Inset Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color;*/
    /* Horizontal-offset Vertical-offset */
    div:nth-of-type(1) {
      box-shadow: 10px 10px;
    }
    /* Horizontal-offset Vertical-offset Shadow-Color */
    div:nth-of-type(2) {
      box-shadow: 10px 10px blue;
    }
    /* Horizontal-offset Vertical-offset Blur-Radius Shadow-Color */
    div:nth-of-type(3) {
      box-shadow: 10px 10px 5px blue;
    }
    /* Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color */
    div:nth-of-type(4) {
      box-shadow: 10px 10px 5px 5px blue;
    }
    /* Inset Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color */
    div:nth-of-type(5) {
      box-shadow: inset 10px 10px 5px 5px blue;
    }
    /* Horizontal-offset Vertical-offset Blur-Radius Spread Shadow-Color */
    div:nth-of-type(6) {
      background-color: white;
      box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
    }
  </style>
</head>
<body>
  <div>This is a div element with a box-shadow</div>
  <div>This is a div element with a box-shadow</div>
  <div>This is a div element with a box-shadow</div>
  <div>This is a div element with a box-shadow</div>
  <div>This is a div element with a box-shadow</div>
  <div>This is a div element with a box-shadow</div>
</body>
</html>
Property Chrome Edge IE Firefox Safari Opera
box-shadow 10.0 12.0 9.0 4.0 5.1 10.5
prefix 4.0     3.5 3.1  

3. 그레이디언트 (Gradient)

그레이디언트는 2가지 이상의 색상을 혼합하여 부드러운 색감의 배경 등을 생성하는 것이다. CSS3가 이 기능을 제공하기 이전에는 포토샵 등의 소프트웨어를 사용하여 그레이디언트 효과의 이미지를 제작하여 사용하였다. 그러나 이러한 방법은 이미지 다운로드에 시간이 소요되는 문제와 이미지를 확대하였을 때 해상도가 나빠지는 문제 등을 내포하고 있었다.

그레이디언트는 2가지 종류가 있다.

  • 선형 그레이디언트 (Linear Gradient: goes down/up/left/right/diagonally)
  • 방사형 그레이디언트 (Radial Gradient: defined by their center)

그레이디언트는 CSS3가 비교적 최근부터 제공하는 기술로서 대부분의 브라우저에 벤더프리픽스를 사용하여야 하고 브라우저에 따라 조금씩 문법이 상이하여 다루기가 수월하지 않다. 따라서 그레이디언트를 직접 작성하는 것보다 작성 툴을 이용하는 것이 보편적이다.

<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      margin: 0;
    }
    div {
      width: 100vw;
      height: 100vh;
    }
    .dawn {
      /* Old browsers */
      background: #b3cae5;
      /* FF3.6+ */
      background: -moz-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
      /* Chrome,Safari4+ */
      background: -webkit-gradient(linear, left top, right bottom, color-stop(12%, #b3cae5), color-stop(46%, #dbdde4), color-stop(70%, #e4e3e4), color-stop(94%, #f7ddbb), color-stop(100%, #efcab2));
      /* Chrome10+,Safari5.1+ */
      background: -webkit-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
      /* Opera 11.10+ */
      background: -o-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
      /* IE10+ */
      background: -ms-linear-gradient(-45deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
      /* W3C */
      background: linear-gradient(135deg, #b3cae5 12%, #dbdde4 46%, #e4e3e4 70%, #f7ddbb 94%, #efcab2 100%);
    }
  </style>
</head>
<body>
  <div class="dawn"></div>
</body>
</html>
Property Chrome Edge IE Firefox Safari Opera
linear-gradient 26.0 12.0 10.0 16.0 6.1 12.1
prefix 10.0     3.6 5.1 11.1
Property Chrome Edge IE Firefox Safari Opera
radial-gradient 26.0 12.0 10.0 16.0 6.1 12.1
prefix 10.0     3.6 5.1 11.1
Property Chrome Edge IE Firefox Safari Opera
repeating-linear-gradient 26.0 12.0 10.0 16.0 6.1 12.1
prefix 10.0     3.6 5.1 11.1
Property Chrome Edge IE Firefox Safari Opera
repeating-radial-gradient 26.0 12.0 10.0 16.0 6.1 12.1
prefix 10.0     3.6 5.1 11.1

4. 트랜지션 (Transition)

CSS 속성이 변경되면 속성 변경에 따른 표시의 변화(transition)은 즉시 발생한다. 아래 코드를 실행해 보면 div 요소에 마우스가 올라가면 div 요소의 border-radius, background가 즉시 변화한다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background: red;
    }
    div:hover {
      border-radius: 50%;
      background: blue;
    }
  </style>
</head>
<body>
  <div></div>
</body>
</html>

트랜지션(transition)은 CSS 속성 변경에 따른 표시의 변화를 부드럽게 하기 위해 애니메이션 속도를 조절한다. 즉 속성 변경이 표시의 변화에 즉시 영향을 미치게 하는 대신 그 속성의 변화가 일정 시간(duration)에 걸쳐 일어나도록 하는 것이다.

위 예제에 트랜지션 효과를 부여해 보자.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background: red;
      transition: all 2s;
    }
    div:hover {
      border-radius: 50%;
      background: blue;
    }
  </style>
</head>
<body>
  <div></div>
</body>
</html>

위 예제에서는 div 요소에 마우스가 올라갈 때(hover on)와 마우스가 내려올 때(hover off) border-radius, background 속성의 변경이 발생한다. 그리고 이들 속성의 변경을 2초에 걸쳐 변화하도록 한 것이다.

div에 transition을 설정하면 마우스가 올라갈 때(hover on)와 마우스가 내려올 때(hover off) 모두 transition이 발동한다. 하지만 div:hover에 transition을 설정하면 마우스가 올라갈 때(hover on)는 transition이 발동하지만 마우스가 내려올 때(hover off)는 transition이 발동하지 않는다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background: red;
    }
    div:hover {
      background: blue;
      border-radius: 50%;
      transition: all 2s;
    }
  </style>
</head>
<body>
  <div></div>
</body>
</html>

transition은 자동으로 발동되지 않는다. :hover와 같은 가상 클래스 선택자(Pseudo-Classes) 또는 JavaScript의 onclick 이벤트 등이 부수적인 액션에 의해 발동한다. 위 예제의 div 요소에 적용된 transition은 이와 같은 부수적 액션없이는 어떤 효과도 볼 수 없다.

transition의 속성은 아래와 같다.

속성 설명 기본값
transition-property 트랜지션의 대상이 되는 CSS 속성명을 지정한다 all
transition-duration 트랜지션이 일어나는 지속시간(duration)을 초 단위로 지정한다 0s
transition-timing-function 트랜지션 효과를 위한 수치 함수를 지정한다. ease
transition-delay 속성이 변한 시점과 트랜지션이 실제로 시작하는 사이에 대기하는 시간을 초 단위로 지정한다 0s
transition 모든 트랜지션 속성을 한번에 지정한다 (shorthand syntax)  

4.1 transition-property

transition-property 속성은 트랜지션의 대상이 되는 CSS 속성명을 지정한다. 지정하지 않는 경우 모든 속성이 트랜지션의 대상이 된다. 복수의 속성을 지정하는 경우 쉼표(,)로 구분한다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 50px;
      background-color: red;
      margin-bottom: 10px;
      transition-property: width, background-color;
      transition-duration: 2s, 2s;
    }
    div:hover {
      width: 300px;
      background-color: blue;
    }
  </style>
</head>
<body>
  <div></div>
</body>
</html>

주의해야 할 사항은 모든 CSS 속성이 트랜지션의 대상이 될 수 없다는 것이다. 예를 들어 width, font-size, background-color 등은 하나의 범주(width, font-size는 크기, background-color는 색상)안에서 값이 변화하지만 display 속성은 그렇지 않다.

트랜지션의 대상이 될 수 있는 CSS 속성은 다음과 같다.

width height  max-width max-height  min-width  min-height
padding margin
border-color  border-width  border-spacing
background-color  background-position
top left  right bottom  
color font-size font-weight letter-spacing  line-height
text-indent text-shadow  vertical-align  word-spacing
opacity
outline-color outline-offset  outline-width
visibility  z-index

또한 요소의 속성이 변화하면 브라우저는 속성 변화에 영향을 받는 모든 요소의 기하값(위치와 크기)를 계산하여 layout 작업을 수행해야 한다. 이것은 브라우저에게 스트레스를 주어 성능 저하의 요인이 된다. 심지어 다수의 자식 요소를 가지고 있는 요소(예를 들어 body 요소)가 변경되면 모든 자식 요소의 기하값이 재계산될 수 도 있다. 따라서 layout에 영향을 주는 트랜지션 효과는 회피하기 위한 노력이 필요하다.

layout에 영향을 주는 속성은 다음과 같다.

width height  padding margin  border
display position  float overflow
top left  right bottom
font-size font-family font-weight
text-align  vertical-align  line-height
clear white-space

4.2 transition-duration

transition-duration 속성은 트랜지션에 일어나는 지속시간(duration)을 초 단위로 지정한다. 속성값을 지정하지 않을 경우 기본값 0s이 적용되어 어떠한 트랜지션 효과도 볼 수 없다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 50px;
      padding: 10px;
      color: white;
      background-color: red;
      margin-bottom: 10px;
      transition-property: width, opacity;
    }
    div:nth-child(1) {
      transition-duration: 0.5s;
    }
    div:nth-child(2) {
      transition-duration: 2s, 1s;
    }
    div:nth-child(3) {
      transition-duration: 5s, 2.5s;
    }
    div:hover {
      width: 300px;
      opacity: .1;
    }
  </style>
</head>
<body>
  <div>0.5s</div>
  <div>2s, 1s</div>
  <div>5s, 2.5s</div>
</body>
</html>

transition-duration 속성값은 transition-property 속성값과 1:1 대응한다. 아래의 경우, width 속성은 2초에 지속시간을 갖는다(2초에 걸쳐 변화한다).

div {
  transition-property: width;
  transition-duration: 2s;
}

아래의 경우, width 속성은 2초, opacity 속성은 4초의 지속시간을 갖는다.

div {
  transition-property: width, opacity;
  transition-duration: 2s, 4s;
}

또한 transition 속성만으로 표현이 가능하다.

div {
  transition: width 2s, opacity 4s;
}

아래의 경우, width 속성은 2초, opacity 속성은 1초, left 속성은 2초, top 속성은 1초의 지속시간을 갖는다.

div {
  transition-property: width, opacity, left, top;
  transition-duration: 2s, 1s;
}

4.3 transition-timing-function

트랜지션 효과의 변화 흐름, 시간에 따른 변화 속도와 같은 일종의 변화의 리듬을 지정한다.

대부분의 타이밍 함수는 큐빅 베이지어(cubic bezier)를 정의하는 네 점에 의해 정의되므로 상응하는 함수의 그래프로 제공해서 명시할 수 있다. transition-timing-function 속성값으로 미리 정해둔 5개의 키워드가 제공된다. 기본값은 ease이다.

속성값 효과 그래프
ease 기본값. 느리게 시작하여 점점 빨라졌다가 느리지면서 종료한다.
linear 시작부터 종료까지 등속 운동을 한다.
ease-in 느리게 시작한 후 일정한 속도에 다다르면 그 상태로 등속 운동한다.
ease-out 일정한 속도의 등속으로 시작해서 점점 느려지면서 종료한다.
ease-in-out ease와 비슷하게 느리게 시작하여 느리지면서 종료한다.
<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      font: bold 16px/50px "Open Sans";
      color: white;
      text-align: center;
      width: 100px;
      height: 50px;
      background-color: red;
      margin-bottom: 10px;
      transition: width 2s;
    }
    div:nth-child(1) {
      transition-timing-function: ease;
    }
    div:nth-child(2) {
      transition-timing-function: linear;
    }
    div:nth-child(3) {
      transition-timing-function: ease-in;
    }
    div:nth-child(4) {
      transition-timing-function: ease-out;
    }
    div:nth-child(5) {
      transition-timing-function: ease-in-out;
    }
    div:hover {
      width: 300px;
    }
  </style>
</head>
<body>
  <h3>transition-timing-function</h3>
  <div>ease</div>
  <div>linear</div>
  <div>ease-in</div>
  <div>ease-out</div>
  <div>ease-in-out</div>
</body>
</html>

4.4 transition-delay

속성이 변한 시점과 트랜지션이 실제로 시작하는 사이에 대기하는 시간을 초 단위로 지정한다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      font: bold 16px/50px "Open Sans";
      color: white;
      text-align: center;
      width: 100px;
      height: 50px;
      background-color: red;
      margin-bottom: 10px;
      transition: width 1s;
    }
    div:nth-of-type(1) {
      transition-delay: 0s;
    }
    div:nth-of-type(2) {
      transition-delay: 1s;
    }
    div:nth-of-type(3) {
      transition-delay: 3s;
    }
    div:hover {
      width: 300px;
    }
  </style>
</head>
<body>
  <h3>transition-delay</h3>
  <div>0s</div>
  <div>1s</div>
  <div>3s</div>
</body>
</html>

4.5 transition

모든 트랜지션 속성을 한번에 지정할 수 있는 shorthand이다. 값을 지정하지 않은 속성에는 기본값이 지정된다. 지정 방법은 다음과 같다.

transition: property duration function delay

transition-duration은 반드시 지정해야 한다. 지정하지 않는 경우 기본값 0이 셋팅되어 어떠한 트랜지션도 실행되지 않는다. 기본값은 아래와 같다.

all 0 ease 0
<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      font: bold 0.5em/50px "Open Sans";
      color: white;
      text-align: center;
      width: 100px;
      height: 50px;
      margin-bottom: 10px;
      background-color: red;
    }
    div:nth-of-type(1) {
      /* property duration function delay */
      transition: width 1s ease-in 1s;
    }
    div:nth-of-type(2) {
      /* duration */
      transition: 1s
    }
    div:nth-of-type(3) {
      /* property duration */
      transition: width 1s
    }
    div:nth-of-type(4) {
      /* duration function */
      transition: 1s ease-in;
    }
    div:nth-of-type(5) {
      /* duration delay*/
      transition: 1s 1s;
    }
    div:hover {
      width: 300px;
    }
  </style>
</head>
<body>
  <div>width 1s ease-in 1s</div>
  <div>1s</div>
  <div>width 1s</div>
  <div>1s ease-in</div>
  <div>1s 1s</div>
</body>
</html>
Property Chrome Edge IE Firefox Safari Opera
transition-* 26.0 12.0 10.0 16.0 6.1 12.1
prefix 4.0     4.0 3.1 10.5

5. 애니메이션 (Animation)

애니메이션 효과는 HTML 요소에 적용되는 CSS 스타일을 다른 CSS 스타일로 부드럽게 변화시킨다. 애니메이션은 애니메이션을 나타내는 CSS 스타일과 애니메이션의 sequence를 나타내는 복수의 키프레임(@keyframs) 들로 이루어진다.

transition으로도 어느 정도의 애니메이션 효과를 표현할 수 있으나 animation보다는 제한적이다. 일반적으로 트랜지션 효과는 요소 속성값이 다른 값으로 변화할 때 주로 사용하며 요소의 로드와 함께 자동으로 발동되지 않는다. :hover 와 같은 가상 클래스 선택자(Pseudo-Class Selector) 또는 자바스크립트의 이벤트 등의 부수적 액션에 의해 발동된다.

즉 transition 속성은 단순히 요소 속성의 변화에 주안점이 있다면 animation 속성은 하나의 줄거리를 구성하여 줄거리 내에서 세부 움직임을 시간 흐름 단위로 제어할 수 있고 전체 줄거리의 재생과 정지, 반복까지 제어할 수 있다.

See the Pen Loaders (WIP) by Tania LD (@TaniaLD) on CodePen.

일반적으로 CSS 애니메이션을 사용하면 기존의 JavaScript 기반 애니메이션 실행과 비교하여 더 나은 렌더링 성능을 제공한다고 알려져 있다. 그러나 경우에 따라서는 JavaScript를 사용하는 것이 나을 수도 있다. jQuery 등의 애니메이션 기능은 CSS보다 간편하게 애니메이션 효과를 가능케 한다.

  • 비교적 작은 효과나 CSS만으로도 충분한 효과를 볼 수 있는 것은 CSS를 사용한다. 예를 들어 요소의 width 변경 애니메이션은 자바스크립트를 사용하는 것보다 훨씬 간편하며 효과적이다.
  • 세밀한 제어를 위해서는 자바스크립트 사용이 바람직하다. 예를 들어 바운스, 중지, 일시 중지, 되감기 또는 감속과 같은 고급 효과는 자바스크립트가 훨씬 유용하다.

가장 중요한 것은 브라우저에서 애니메이션 효과가 부드럽게 실행되는 것이다. 그리고 애니메이션 효과 작성에 소요되는 시간과 수고이다. 여러 사항들을 고려하여 자바스크립트를 사용하여야 할지 CSS를 사용하여야 할지 결정하여야 한다.

속성 설명 기본값
animation-name @keyframes 애니메이션 이름을 지정한다  
animation-duration 한 싸이클의 애니메이션에 소요되는 시간을 초 단위로 지정한다. 0s
animation-timing-function 애니메이션 효과를 위한 수치 함수를 지정한다. ease
animation-delay 요소가 로드된 시점과 애니메이션이 실제로 시작하는 사이에 대기하는 시간을 초 단위로 지정한다 0s
animation-iteration-count 애니메이션 재생 횟수를 지정한다. 1
animation-direction 애니메이션이 종료된 이후 반복될 때 진행하는 방향을 지정한다. normal
animation-fill-mode 애니메이션 미실행 시(종료 또는 대기) 요소의 스타일을 지정한다.  
animation-play-state 애니메이션 재생 상태(재생 또는 중지)를 지정한다. running
animation 모든 애니메이션 속성을 한번에 지정한다 (shorthand syntax)  

5.1 @keyframs

CSS 애니메이션이 트랜지션과 주된 방식의 차이는 @keyframes rule에 있다. 이 rule을 사용하면 애니메이션의 흐름(sequence) 중의 여러 시점(breakpoint)에서 CSS 속성값을 지정할 수 있다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background-color: red;
      animation-name: fadeOut;
      animation-duration: 5s;
      animation-iteration-count: infinite;
    }
    /*@keyframes rule*/
    @keyframes fadeOut {
      /*keyframe*/
      from {
        opacity: 1;
      }
      /*keyframe*/
      to {
        opacity: 0;
      }
    }
  </style>
</head>
<body>
  <div></div>
</body>
</html>

@keyframes rule은 시간의 흐름에 따라 애니메이션을 정의한다. 여러 개의 키프레임을 정의하거나 애니메이션 중에 특정 CSS 속성에 값을 지정하는 지점을 정의할 수 있다.

위 예제를 보면 @keyframes 뒤에 애니메이션을 대표하는 임의의 이름를 부여하였다.

@keyframes fadeOut {}

from, to 키워드를 사용하여 애니메이션의 시작과 끝 지점을 정의하였다. 그리고 애니메이션의 시작 시점을 의미하는 from 키프레임 내에는 opacity 속성에 값 1을, 애니메이션의 끝 시점을 의미하는 to 키프레임 내에는 opacity 속성에 값 0을 지정하였다. 결과는 불투명도 상태에서 투명 상태로 애니메이션이 진행하게 된다.

@keyframes fadeOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}

from, to 키워드 대신 0, 100%를 사용할 수 있다. 또한 시작과 끝 키프레임 사이에 % 단위로 키프레임을 삽입할 수 있다.

@keyframes fadeOut {
  from { opacity: 1; }
  50%  { opacity: 0.3; }
  to   { opacity: 0; }
}

5.2 animation-name

위 예제를 보면 @keyframes 뒤에 애니메이션을 대표하는 임의의 이름를 부여하였다.

@keyframes fadeOut {}

이 이름을 animation-name 속성값으로 지정하여 사용하고자 하는 @keyframes rule을 선택한다. 하나 이상의 애니메이션 이름을 지정할 수 있다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      animation-name: fadeOut, changeColor;
      animation-duration: 5s;
      animation-iteration-count: infinite;
    }
    @keyframes fadeOut {
      from { opacity: 1; }
      to   { opacity: 0; }
    }
    @keyframes changeColor {
      from { background-color: red; }
      to   { background-color: blue; }
    }
  </style>
</head>
<body>
  <div></div>
</body>
</html>

5.3 animation-duration

한 싸이클의 애니메이션에 소요되는 시간을 초 단위로 지정한다.

animation-duration: 5s;

5.4 animation-timing-function

애니메이션 효과를 위한 수치 함수를 지정한다. 수치 함수에 대한 설명은 트랜지션 transition-timing-function 속성 을 참조하기 바란다.

5.5 animation-delay

요소가 로드된 시점과 애니메이션이 실제로 시작하는 사이에 대기하는 시간을 초 단위로 지정한다.

animation-delay: 2s;

5.6 animation-iteration-count

애니메이션 주기의 재생 횟수를 지정한다. 기본값은 1이며 infinite로 무한반복 할 수 있다.

animation-iteration-count: 3;

5.7 animation-direction

애니메이션이 종료된 이후 반복될 때 진행하는 방향을 지정한다.

속성값 설명
normal 기본값으로 from(0%)에서 to(100%) 방향으로 진행한다.
reverse to에서 from 방향으로 진행한다.
alternate 홀수번째는 normal로, 짝수번째는 reverse로 진행한다.
alternate-reverse 홀수번째는 reverse로, 짝수번째는 normal로 진행한다.
<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background: red;
      position: relative;
      animation: myAnimation 5s infinite;
      /*홀수번째는 normal로, 짝수번째는 reverse로 진행*/
      animation-direction: alternate;
    }
    @keyframes myAnimation {
      0%   { background: red;    left: 0px;   top: 0px; }
      25%  { background: yellow; left: 200px; top: 0px; }
      50%  { background: blue;   left: 200px; top: 200px; }
      75%  { background: green;  left: 0px;   top: 200px; }
      100% { background: red;    left: 0px;   top: 0px; }
    }
  </style>
  </head>
  <body>
    <div></div>
  </body>
</html>

See the Pen animation-direction by Ungmo Lee (@ungmo2) on CodePen.

5.8 animation-fill-mode

애니메이션 미실행 시(대기 또는 종료) 요소의 스타일을 지정한다.

속성값 상태 설명
none 대기 시작 프레임(from)에 설정한 스타일을 적용하지 않고 대기한다.
  종료 애니메이션 실행 전 상태로 애니메이션 요소의 속성값을 되돌리고 종료한다.
forwards 대기 시작 프레임(from)에 설정한 스타일을 적용하지 않고 대기한다.
  종료 종료 프레임(to)에 설정한 스타일을 적용하고 종료한다.
backwards 대기 시작 프레임(from)에 설정한 스타일을 적용하고 대기한다.
  종료 애니메이션 실행 전 상태로 애니메이션 요소의 속성값을 되돌리고 종료한다.
both 대기 시작 프레임(from)에 설정한 스타일을 적용하고 대기한다.
  종료 종료 프레임(to)에 설정한 스타일을 적용하고 종료한다.
<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      font: bold 1em/100px san-serif;
      text-align: center;
      color: #fff;
      background: red;
      margin-bottom: 10px;
      position: relative;
      /*name duration timing-function delay iteration-count direction fill-mode play-state*/
      animation: myAnimation 2s linear 2s;
    }
    div:nth-of-type(1) {
      animation-fill-mode: none;
    }
    div:nth-of-type(2) {
      animation-fill-mode: forwards;
    }
    div:nth-of-type(3) {
      animation-fill-mode: backwards;
    }
    div:nth-of-type(4) {
      animation-fill-mode: both;
    }
    @keyframes myAnimation {
      0%   { left: 0px;   background: yellow; }
      100% { left: 200px; background: blue; }
    }
  </style>
</head>
<body>
  <h1>animation-fill-mode</h1>

  <div>none</div>
  <p>대기 : 시작 프레임(from)에 설정한 스타일을 적용하지 않고 대기한다.</p>
  <p>종료 : 애니메이션 실행 전 상태로 애니메이션 요소의 속성값을 되돌리고 종료한다.</p>

  <div>forwards</div>
  <p>대기 : 시작 프레임(from)에 설정한 스타일을 적용하지 않고 대기한다.
  <p>종료 : 종료 프레임(to)에 설정한 스타일을 적용하고 종료한다.

  <div>backwards</div>
  <p>대기 : 시작 프레임(from)에 설정한 스타일을 적용하고 대기한다.
  <p>종료 : 애니메이션 실행 전 상태로 애니메이션 요소의 속성값을 되돌리고 종료한다.

  <div>both</div>
  <p>대기 : 시작 프레임(from)에 설정한 스타일을 적용하고 대기한다.
  <p>종료 : 종료 프레임(to)에 설정한 스타일을 적용하고 종료한다.
</body>
</html>

See the Pen animation-fill-mode by Ungmo Lee (@ungmo2) on CodePen.

5.9 animation-play-state

애니메이션 재생 상태(재생 또는 중지)를 지정한다. 기본값은 running이다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      width: 100px;
      height: 100px;
      background: red;
      position: relative;
      /*name duration timing-function delay iteration-count direction fill-mode play-state*/
      animation: move 5s infinite;
    }
    div:hover {
      background: blue;
      animation-play-state: paused;
    }
    div:active {
      background: yellow;
      animation-play-state: running;
    }
    @keyframes move {
      from { left: 0px; }
      to   { left: 200px; }
    }
  </style>
</head>
<body>
  <h1>animation-play-state</h1>
  <div></div>
</body>
</html>

5.10 animation

모든 애니메이션 속성을 한번에 지정한다. 값을 지정하지 않은 속성에는 기본값이 지정된다. 지정 방법은 다음과 같다.

animation: name duration timing-function delay iteration-count direction fill-mode play-state

animation-duration은 반드시 지정해야 한다. 지정하지 않는 경우 기본값 0이 셋팅되어 어떠한 애니메이션도 실행되지 않는다. 기본값은 아래와 같다.

none 0 ease 0 1 normal none running
Property Chrome Edge IE Firefox Safari Opera
@keyframes & animation 43.0 12.0 10.0 16.0 9.0 30.0
prefix 4.0     5.0 4.0 12.0

6. 트랜스폼 (Transform)

트랜지션은 CSS 스타일 변경을 부드럽게 표현하기 위해 duration(지속시간)을 부여하여 속도를 조절한다.

애니메이션은 하나의 줄거리(@keyframes)를 구성하여 줄거리 내에서 세부 움직임을 시간 흐름 단위로 제어하여 요소의 움직임을 표현한다.

트랜스폼은 요소의 이동(translate), 회전(rotate), 확대축소(scale), 비틀기(skew) 효과를 제공한다. 단 애니메이션 효과를 제공하지는 않기 때문에 정의된 속성이 바로 적용되어 화면에 표시된다. 트랜지션과 같이 요소의 로드와 함께 자동으로 발동되지 않는 것이다. 물론 :hover 와 같은 가상 클래스 선택자(Pseudo-Class Selector) 또는 자바스크립트의 이벤트 등의 부수적 액션에 의해 발동시킬 수 있다. 트랜스폼에 애니메이션 효과를 부여하기 위해서는 트랜지션이나 애니메이션과 함께 사용하여야 한다.

6.1 2D 트랜스폼 (2D Transform)

2D 트랜스폼은 속성값으로 변환함수(transform function)를 사용한다. 사용할 수 있는 변환함수는 다음과 같다.

transform function 설명 단위
translate(x,y) 요소의 위치를 X축으로 x만큼, Y축으로 y만큼 이동시킨다. px, %, em 등
translateX(n) 요소의 위치를 X축으로 x만큼 이동시킨다. px, %, em 등
translateY(n) 요소의 위치를 Y축으로 y만큼 이동시킨다. px, %, em 등
scale(x,y) 요소의 크기를 X축으로 x배, Y축으로 y배 확대 또는 축소 시킨다. 0과 양수
scaleX(n) 요소의 크기를 X축으로 x배 확대 또는 축소 시킨다. 0과 양수
scaleY(n) 요소의 크기를 Y축으로 y배 확대 또는 축소 시킨다. 0과 양수
skew(x-angle,y-angle) 요소를 X축으로 x 각도만큼, Y축으로 y 각도만큼 기울인다. +/- 각도(deg)
skewX(x-angle,y-angle) 요소를 X축으로 x 각도만큼 기울인다. +/- 각도(deg)
skewY(y-angle) 요소를 Y축으로 y 각도만큼 기울인다. +/- 각도(deg)
rotate(angle) 요소를 angle만큼 회전시킨다. +/- 각도(deg)

6.1.1 transform 속성

변환함수를 속성값으로 쉼표없이 나열한다. 나열순서에 따라 차례대로 효과가 적용된다.

transform: func1 func2 func3 ...;
<!DOCTYPE html>
<html>
<head>
  <style>
  .box {
    width: 95px;
    height: 95px;
    line-height: 95px;
    color: white;
    text-align: center;
    border-radius: 6px;
  }
  .original {
    margin: 30px;
    border: 1px dashed #cecfd5;
    background: #eaeaed;
    float: left;
  }
  .child {
    background: #2db34a;
    cursor: pointer;
  }
  .translate {
    transform: translate(10px, 50px);
  }
  .scale {
    transform: scale(.75);
  }
  .skew {
    transform: skew(5deg, -20deg);
  }
  .rotate {
    transform: rotate(70deg);
  }
  .complex {
    transform: scale(.5) rotate(20deg);
  }

  /*Animation Effect*/
  .translate:hover {
    transition: transform 1s linear;
    transform: translate(0px, 0px);
  }
  /*.translate:hover {
    animation: translate 1s linear forwards;
  }
  @keyframes translate {
    100% {
      transform: translate(0px, 0px);
    }
  }*/
  .scale:hover {
    transition: transform 1s linear;
    transform: scale(1);
  }
  .skew:hover {
    transition: transform 1s linear;
    transform: skew(0, 0);
  }
  .rotate:hover {
    transition: transform 1s linear;
    transform: rotate(0);
  }
  .complex:hover {
    transition: transform 1s linear;
    transform: scale(1) rotate(0);
  }
  </style>
</head>
<body>
  <div class="original box">
    <div class="child box translate">translate</div>
  </div>
  <div class="original box">
    <div class="child box scale">scale</div>
  </div>
  <div class="original box">
    <div class="child box skew">skew</div>
  </div>
  <div class="original box">
    <div class="child box rotate">rotate</div>
  </div>
  <div class="original box">
    <div class="child box complex">complex</div>
  </div>
</body>
</html>

6.1.2 transform-origin 속성

요소의 기본기준점을 설정할 때 사용된다. 기본기준점은 요소의 정중앙이다(50%,50%). 이동은 기준점을 변경하여도 일정 거리만큼 이동하므로 의미가 없다. 설정값으로 %, px, top left, bottom right을 사용할 수 있다. 0, 0은 top left, 100% 100%는 bottom right과 같은 값이다.

<!DOCTYPE html>
<html>
<head>
  <style>
  .box {
    width: 150px;
    height: 150px;
    line-height: 150px;
    color: white;
    text-align: center;
    border-radius: 6px;
  }
  .original {
    margin: 20px;
    border: 1px dashed #cecfd5;
    background: #eaeaed;
    float: left;
  }
  .child {
    background: #2db34a;
    cursor: pointer;
  }
  .scale1:hover {
    transition: transform 1s linear;
    transform-origin: 0 0;
    transform: scale(.5);
  }
  .scale2:hover {
    transition: transform 1s linear;
    transform-origin: 50% 50%;
    transform: scale(.5);
  }
  .scale3:hover {
    transition: transform 1s linear;
    transform-origin: 100% 100%;
    transform: scale(.5);
  }
  .translate:hover {
    transition: transform 1s linear;
    /*transform-origin: 100% 100%;*/
    transform: translate(10px, 10px);
  }
  </style>
</head>
<body>
  <div class="original box">
    <div class="child box scale1">scale1</div>
  </div>
  <div class="original box">
    <div class="child box scale2">scale2</div>
  </div>
  <div class="original box">
    <div class="child box scale3">scale3</div>
  </div>
  <div class="original box">
    <div class="child box translate">translate</div>
  </div>
</body>
</html>
Property Chrome Edge IE Firefox Safari Opera
transform-* 36.0 12.0 10.0 16.0   23.0
prefix 4.0   9.0 3.5 3.2 12.1

Reference

Back to top
Close