[CSS] 전환, 애니메이션 및 변형
1. 전환 사용
전환 효과는 일반적으로 브라우저에서 요소의 CSS 속성을 직접 변경하여 얻을 수 있습니다. 예를 들어 :hover 선택기를 사용하는 경우 사용자가 요소 위로 마우스를 가져가면 브라우저는 선택기와 관련된 속성을 적용합니다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> p { padding: 5px; border: medium double black; background-color: lightgray; font-family: sans-serif;} #banana { font-size: large; border: medium solid green;} #banana:hover { font-size: x-large; border: medium solid white; background-color: #1fa6e6; color: white; padding: 4px;} </style> </head> <body> <p> There are lots of different kinds of fruit - there are over 500 varieties of <span id="banana">banana</span> alone. By the time we add the countless types of apples, oranges, and other well-know fruit, we are faced with thousands of choices. </p> </div> </body> </html>
사용자가 범위 요소 위에 마우스를 올리면 브라우저가 응답하고 새 속성을 직접 적용합니다. 변경 사항은 다음과 같습니다.
CCS 전환 속성을 사용하면 새 속성 값이 적용되는 속도를 제어할 수 있습니다. 예를 들어, 바나나라는 단어 위로 마우스를 이동하는 효과가 더욱 조화롭게 되도록 예제에서 범위 요소의 모양을 점진적으로 변경하도록 선택할 수 있습니다.
전환 지연 및 전환 기간 속성은 ms(밀리초) 또는 s(초) 단위의 숫자인 CSS 시간으로 지정됩니다.
전환 약어 속성의 형식은 다음과 같습니다.
transition: <transition-property> <transition-duration> <transition-timing-function> <transition-delay>
이전 예시의 CSS 코드를 다음과 같이 수정합니다.
p { padding: 5px; border: medium double black; background-color: lightgray; font-family: sans-serif;} #banana { font-size: large; border: medium solid green;} #banana:hover { font-size: x-large; border: medium solid white; background-color: #1fa6e6; color: white; padding: 4px; transition-delay: 100ms; transition-property: background-color,color,padding,font-size,border; transition-duration: 500ms; }
이 예시에서는 전환이 스타일에 추가되고 #banana:hover 선택기를 통해 적용됩니다. 사용자가 범위 요소 위로 마우스를 가져간 후 100ms 후에 전환이 시작되고 500ms 동안 지속됩니다. 전환은 배경색, 색상, 패딩, 글꼴 크기 및 테두리 속성에 적용됩니다. 아래 렌더링은 이 전환의 점진적인 진행을 보여줍니다.
이 예에서 여러 속성이 어떻게 지정되는지 확인하세요. 전환 속성의 값은 전환 효과가 동시에 나타나도록 쉼표로 구분됩니다. 지연 시간과 지속 시간에 대해 여러 값을 지정할 수 있습니다. 즉, 서로 다른 속성이 서로 다른 시점에서 전환을 시작하고 지속 시간도 달라집니다.
1.1 역방향 전환 만들기
전환은 해당 스타일이 적용될 때만 적용됩니다. :hover 선택기는 예제 스타일에 사용되었습니다. 즉, 사용자가 범위 요소 위로 마우스를 가져갈 때만 스타일이 적용됩니다. 사용자가 범위 요소에서 마우스를 떼면 #banana 스타일만 남습니다. 기본적으로 요소의 모양은 즉시 원래 상태로 돌아갑니다.
이러한 이유로 대부분의 전환은 쌍으로 발생합니다. 임시 상태로의 전환과 반대 방향의 역전환입니다. 다른 전환 스타일을 적용하여 원래 스타일로 원활하게 돌아가는 방법을 보여주기 위해 이전 예제의 CCS 코드를 수정합니다.
p { padding: 5px; border: medium double black; background-color: lightgray; font-family: sans-serif;} #banana { font-size: large; border: medium solid green; transition-delay: 100ms; transition-duration: 500ms;} #banana:hover { font-size: x-large; border: medium solid white; background-color: #1fa6e6; color: white; padding: 4px; transition-delay: 100ms; transition-property: background-color,color,padding,font-size,border; transition-duration: 500ms; }
1.2 중간값 계산 방법 선택
전환을 사용할 때 브라우저는 초기값과 최종값 사이에서 계산해야 합니다. 각 속성은 중간 값을 나타냅니다. 네 점으로 제어되는 3차 베지어 곡선으로 표현되는 중간 값을 계산하는 방법을 지정하려면 전환 타이밍 함수 속성을 사용하세요. 선택할 수 있는 사전 설정된 곡선은 5개이며 다음 값으로 표시됩니다.
* 완화(기본값)
* 선형
* 완화
* 이즈 아웃
* 이즈 인 아웃
아래 그림에서 이 5개의 곡선을 볼 수 있는데, 시간이 지남에 따라 중간 값이 최종 값으로 변경되는 비율을 보여줍니다. .
이러한 값을 알아내는 가장 쉬운 방법은 자신의 HTML 문서에서 실험해 보는 것입니다. 사용자 정의 곡선을 지정하는 데 사용할 수 있는 또 다른 값인 큐빅 베지어(cubic-bezier)가 있습니다.
전환 타이밍 기능 속성의 적용을 보여주기 위해 이전 예제의 CSS 스타일을 다음과 같이 수정합니다.
p { padding: 5px; border: medium double black; background-color: lightgray; font-family: sans-serif;} #banana { font-size: large; border: medium solid green; transition-delay: 10ms; transition-duration: 250ms;; } #banana:hover { font-size: x-large; border: medium solid white; background-color: #1fa6e6; color: white; padding: 4px; transition-delay: 100ms; transition-property: background-color,color,padding,font-size,border; transition-duration: 500ms; transition-timing-function: linear; }
2. 애니메이션 사용
CSS 애니메이션 본질적으로 향상된 전환입니다. 한 스타일에서 다른 스타일로 전환하는 방법에 있어 더 많은 선택, 더 많은 제어 및 더 많은 유연성이 제공됩니다.
애니메이션 약어 속성의 형식은 다음과 같습니다.
animation: <animation-name> <animation-duration> <animation-timing-function> <animation-delay> <animation-iteration-count>
이러한 속성은 애니메이션할 CSS 속성을 지정하는 데 사용되지 않습니다. 애니메이션은 두 부분으로 정의되기 때문입니다. 첫 번째 부분은 스타일 선언에 포함되어 있으며 위 표에 나열된 속성을 사용합니다. 애니메이션 스타일을 정의하지만 애니메이션이 적용되는 속성은 정의하지 않습니다. 두 번째 부분에서는 @key-frames 규칙 창을 사용하여 애니메이션을 정의하는 속성을 정의합니다. 아래 코드에서 애니메이션을 정의하는 두 부분을 볼 수 있습니다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> #ball{ width: 180px; height: 180px; background-color:green; margin:20px auto;border-radius: 90px; -webkit-animation-delay: 100ms; -webkit-animation-duration: 2000ms; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; } @-webkit-keyframes GrowQuare { to { background-color: yellow; border-radius: 0; } } </style> </head> <body> <div id="ball"></div> </body> </html>
要明白在这个示例中做了什么,应该仔细研究一下动画的两部分。第一部分是在样式中定义动画属性,是跟#ball选择器一起的。先看看基本属性:选择器样式应用100ms后开始播放动画属性,持续时间2000ms,无限重复播放,中间值使用linear函数计算。除了重复播放动画,这些属性在过渡中都有对应属性。
这些基本的属性并没有指出为哪些CSS属性应用动画。为此,要使用 animation-name 属性给动画属性起个名字,这里叫 GrowsQuare 。这样,就相当于告诉浏览器找一组名为 GrowQuare 的关键帧,然后将这些基本属性的值应用到 @keyframes指定的动画属性上。下面是此例代码中关键帧的声明(这里省略了-webkit前缀):
@-webkit-keyframes GrowQuare { to { background-color: yellow; border-radius: 0; } }
声明的开始是@keyframes,接着指定了这组关键帧的名字 GrowQuare。声明内部指定了一组要应用的动画效果。to 声明定义了一组设置动画样式的属性,同时也定义了动画结束时这些属性的最终值。动画的初始值来自进行动画处理的元素在应用样式之前的属性值。
此例的效果是一个大小为180像素的圆形,渐变成正方形。其显示效果如下图所示:
2.1 使用关键帧
CSS动画的关键帧机器灵活,非常值得研究。
(1) 设置初始状态
在前面的示例中,要处理为动画的属性的初始值来自元素自身。可以使用from子句指定另一组值。修改前面示例的CSS文件如下:
#ball{ width: 180px; height: 180px; background-color:green; margin:20px auto;border-radius: 90px; -webkit-animation-delay: 1000ms; -webkit-animation-duration: 2000ms; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; } @-webkit-keyframes GrowQuare { from { background-color: black; width: 90px; height: 180px; border-radius: 45px/90px; } to { background-color: yellow; border-radius: 0; } }
在这个例子中修改了动画延迟为1000ms,并为背景色、宽度、高度、圆角边框属性提供了初始值,在to句子中指定的其他属性在动画开始时的初始值来自元素自身。从下面的显示效果可以看出来。最开始是一个绿色的圆形,然后一秒后直接变成一个竖立的黑色椭圆,再经过两秒逐渐改变成黄色的正方形。
(2) 指定中间关键帧
也可以添加其他关键帧定义动画的中间阶段。这是通过添加百分数子句实现的,修改前面示例CSS代码如下:
#ball{ width: 200px; height: 200px; background-color:green; margin:20px auto;border-radius: 100px; -webkit-animation-delay: 1000ms; -webkit-animation-duration: 2000ms; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; } @-webkit-keyframes GrowQuare { from { background-color: black; width: 100px; height: 200px; border-radius: 50px/100px; } 50% { background-color: red; width: 50px;height: 100px; border-radius: 25px/50px;margin:70px auto; } 75%{ background: blue; width: 25px;height: 50px; border-radius: 12.5px/25px;margin:95px auto; } to { background-color: yellow; border-radius: 0; } }
对于每一个百分数子句,在动画中定义了一个点,这时子句中指定的属性和值会完全应用到样式上。此例中,定义了50%和75子句。
中关键帧有两个用途。一是为属性定义新的变化速率。浏览器会使用animation-timing-function 属性指定的调速函数计算由一个关键帧移动到下一个关键帧需要的中间值,以确保关键帧与关键帧之间流畅地播放。二则是定义属性值,以便创建更为复杂的动画。可以看到此例显示效果如下:
2.2 设置重复方向
动画结束后浏览器可以选择接下来动画以何种方式重复。使用 animation-direction属性指定首先方式。
修改前面示例CSS代码如下:
#ball{ width: 50px; height: 50px; background-color:green;border-radius: 25px; -webkit-animation-delay: 100ms; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: 2; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; -webkit-animation-direction: alternate; } @-webkit-keyframes GrowQuare { 50%{ margin-top: 200px; } to { margin-left:200px; } }
2.3 理解结束状态
CSS动画的一个局限是关键帧为属性定义的值只能在动画中应用。动画结束后,动画元素的外观回到初始状态。
2.4 初始布局时应用动画
跟过渡相比,动画的一个优势是可以将其应用到页面的初始布局。当把 animation-delay 属性的值设为0 (默认值),当页面一旦加载就会自动应用样式,这就意味着浏览器一旦显示HTML就有了动画效果。
PS:使用上诉方法要谨慎。如果要在页面中使用动画,而动画效果不是邀请用户只需某一动作,这种情况更应该慎之又慎。如果确实要使用动画,要保证动画效果缓和一些,不要妨碍用户阅读或者与页面其他部分交互。
2.5 重用关键帧
我们可以对同一组关键帧应用多个动画,从而动画属性配置不同的值。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> #ball{ width: 50px; height: 50px; background-color:green;border-radius: 25px; -webkit-animation-delay: 100ms; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; -webkit-animation-direction: alternate; } #ball_second { width: 50px; height: 50px; background-color:green; -webkit-animation-delay: 100ms; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; -webkit-animation-direction: alternate; } @-webkit-keyframes GrowQuare { to { margin-left:200px; } } </style> </head> <body> <div id="ball"></div> <div id="ball_second"></div> </body> </html>
代码中展示了两个样式,它们都使用了GrowQuare 关键帧。效果图如下:
2.6 为多个元素应用多个动画
前面例子的一个变体是为多个元素应用同一个动画。在包含动画细节的样式中,扩展选择器的范围即可实现这一点。
(1)为多个元素应用一个动画
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> #ball, #ball_second { width: 50px; height: 50px; background-color:green;border-radius: 25px; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; -webkit-animation-direction: alternate; } @-webkit-keyframes GrowQuare { to { margin-left:200px; } } </style> </head> <body> <div id="ball"></div> <div id="ball_second"></div> </body> </html>
(2)为一个元素应用多个关键帧
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> #ball{ width: 50px; height: 50px; background-color:green;border-radius: 25px; -webkit-animation-delay: 500ms; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -webkit-animation-name:'Grow1','Grow2'; -webkit-animation-direction: alternate; } @-webkit-keyframes Grow1 { to { margin-left:200px; } } @-webkit-keyframes Grow2 { to { margin-top:200px; } } </style> </head> <body> <div id="ball"></div> </body> </html>
2.7 停止和启动动画
aniamation-play-state 属性可以用来停止和启动动画。如果这个属性的值为paused,动画就会停止。如果换成 playing。动画就会开始播放。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> #ball { width: 50px; height: 50px; background-color:red;border-radius: 25px; -webkit-animation-delay: 500ms; -webkit-animation-duration: 5s; -webkit-animation-direction: alternate; -webkit-animation-iteration-count: infinite;; -webkit-animation-timing-function: linear; -webkit-animation-name:'GrowQuare'; } @-webkit-keyframes GrowQuare { to { width:200px; } } </style> </head> <body> <div id="ball"></div> <br /> <div> <button>Running</button> <button>Paused</button> </div> <script> var buttons = document.getElementsByTagName("button"); for(var i = 0; i < buttons.length; i++){ buttons[i].onclick = function(e){ document.getElementById("ball").style.webkitAnimationPlayState = e.target.innerHTML; } } </script> </body> </html>
3. 使用变换
我们可以使用CSS变换为元素应用线性变换,也就是说可以旋转、缩放、倾斜和平移某个元素。
3.1 应用变换
下面代码是一个变换的例子。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> img{ border: medium double green; background-color: lightgray;} #banana2 { transform: rotate(-45deg) scaleX(1.2); } </style> </head> <body> <p> <img src="imgs/banana-small.png" alt="【CSS】전환, 애니메이션 및 변형" id="banana1"></p> <p> <img src="imgs/banana-small.png" alt="【CSS】전환, 애니메이션 및 변형" id="banana2"></p> </body> </html>
此例中,为#banana2 选择器添加了一个transform 属性声明,指定了两个变换。第一个是旋转-45°(即逆时针旋转45°);第二个是沿x轴进行因子为1.2的缩放。这些变换的效果如下图所示:
3.2 指定元素变换的起点
transform-origin属性允许我们指定应用变换的起点。默认情况下,使用元素的中心作为起点,不过,可以使用下表中的值选择其他起点。
要定义起点,需要为x轴和y轴各定义一个值。如果只提供一个值,另一个值会被认为是中心位置。下面代码展示了 transform-origin属性的用法。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> img{ border: medium double green; background-color: lightgray;} #banana2 { transform: rotate(-45deg) scaleX(1.2); transform-origin: right top;} </style> </head> <body> <p> <img src="imgs/banana-small.png" alt="【CSS】전환, 애니메이션 및 변형" id="banana1"></p> <p> <img src="imgs/banana-small.png" alt="【CSS】전환, 애니메이션 및 변형" id="banana2"></p> </body> </html>
此例中,将变换的起点已到了元素的右上角,从下面的显示效果图可以看到:
3.3 将变换作为动画和过渡处理
我们可以为变换应用动画和过渡,就和其他CSS属性一样。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Example</title> <style type="text/css"> img{ border: medium double green; background-color: lightgray;} #banana2:hover { transform: rotate(360deg); transition-duration: 5s; } </style> </head> <body> <p> <img src="imgs/banana-small.png" alt="【CSS】전환, 애니메이션 및 변형" id="banana1"></p> <p> <img src="imgs/banana-small.png" alt="【CSS】전환, 애니메이션 및 변형" id="banana2"></p> </body> </html>
此例中,定义了一个过渡,它会经过5秒完成一次360°旋转变换。当用户将鼠标悬停在 #banana2 元素上,就会应用过渡,效果如下图所示: