在做前端開發時,常常會覺得「想做出讓人忍不住想點的按鈕」「想讓使用者能直覺操作」。
這時候就能派上用場的,就是 CSS 動畫。
透過組合 transition、transform 等 CSS 屬性,可以替 UI 加上各種動態效果。
我把至今使用過的 CSS 動畫,順便也當作整理自己的知識,統整在這篇文章裡。
transition、transform 屬性用法的人:hover 的基本概念這次介紹的 CSS 動畫主要會使用 transition 和 transform。
先來說明各自的基本效果。
transition 是用來讓 CSS 變化更平滑的屬性。
當 CSS 值改變時,可以讓它在指定時間內逐漸變化。
例如在按鈕 hover 時改變文字顏色或背景色,只要加上 transition,顏色就會慢慢過渡,看起來更柔和自然。
我們來比較一下有無 transition 時,按鈕顏色變化的速度。
▼有無 transition 的比較
See the Pen transitionの比較 (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<!-- transition あり -->
<div class="item">
<span>有(平滑變化)</span>
<div class="btn1">按鈕</div>
</div>
<!-- transition なし -->
<div class="item">
<span>無(瞬間變化)</span>
<div class="btn2">按鈕</div>
</div>
CSS
/* -- 有 transition -- */
.btn1 {
max-width: 120px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 32px;
font-size: 16px;
font-weight: bold;
text-decoration: none;
border-radius: 6px;
cursor: pointer;
color: #ffffff;
background-color: #D20B08;
border: 2px solid #D20B08;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.btn1:hover {
color: #D20B08;
background-color: #ffffff;
}
/* -- 無 transition -- */
.btn2 {
max-width: 120px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 32px;
font-size: 16px;
font-weight: bold;
text-decoration: none;
border-radius: 6px;
cursor: pointer;
color: #ffffff;
background-color: #D20B08;
border: 2px solid #D20B08;
}
/* hover 時 */
.btn2:hover {
color: #D20B08;
background-color: #ffffff;
}
・說明
有 transition 的按鈕加上了 transition: all 0.4s ease;。
這表示讓 CSS 在 0.4 秒內變化。
指定值意義all 將所有會變化的屬性都納入 0.4s 以 0.4 秒進行變化ease 讓變化的開始與結束較為柔和本例中,hover 時 color 與 background-color 會一起變化,因此使用 all 讓所有變化中的屬性都套用過渡效果。
另外,ease 是指定變化方式的值,會讓開始與結束較緩和。
還有很多其他指定值,這裡為了易懂起見使用 all 與 ease。
.btn1 {
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.btn1:hover {
color: #D20B08;
background-color: #ffffff;
}
透過設定 transition,CSS 的變化就能變成平滑的動畫。
transform 是用來移動、放大、縮小、旋轉元素的屬性。
可以讓元素從目前位置移動,也能改變大小與角度。
這裡介紹使用 transform 的以下範例:
▼transform 使用範例
See the Pen transformの例 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<!-- translateY -->
<div class="item">
<span>稍微往上浮起(translateY)</span>
<a class="btn __y">按鈕1</a>
</div>
<!-- translateX -->
<div class="item">
<span>讓箭頭往右移動(translateX)</span>
<a class="btn __x">按鈕2<span class="arrow">→</span></a>
</div>
<!-- scale -->
<div class="item">
<span>放大一圈(scale)</span>
<a class="btn __scale">按鈕3</a>
</div>
CSS
/* -- 按鈕共用樣式 -- */
.btn {
max-width: 120px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 32px;
font-size: 16px;
font-weight: bold;
text-decoration: none;
border-radius: 6px;
cursor: pointer;
color: #ffffff;
background-color: #D20B08;
border: 2px solid #D20B08;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* -- translateY -- */
/* hover 時 */
.btn.__y:hover {
transform: translateY(-6px); /* 沿 Y 軸移動 -6px */
}
/* -- translateX -- */
/* 箭頭 */
.btn.__x .arrow {
padding-left: 16px;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.btn.__x:hover .arrow {
transform: translateX(6px); /* 沿 X 軸移動 6px */
}
/* -- scale -- */
/* hover 時 */
.btn.__scale:hover {
transform: scale(1.1); /* 放大為原本的 1.1 倍 */
}
・說明
transform 可以使用 translate()、scale() 等,來改變元素的位置與大小。
translate()translate() 會把元素從目前位置移動指定的距離。
X 軸方向使用 translateX(),Y 軸方向使用 translateY()。
如果要同時指定 X 軸與 Y 軸,就使用 translate()。
指定值動作translateX(6px) 沿 X 軸移動 6px,向右translateX(-6px) 沿 X 軸移動 -6px,向左translateY(-6px) 沿 Y 軸移動 -6px,向上translateY(6px) 沿 Y 軸移動 6px,向下translate(6px, -6px) 沿 X 軸移動 6px、沿 Y 軸移動 -6px,向右上方▼按鈕1:往上移動
.btn {
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn.__y:hover {
transform: translateY(-6px); /* 沿 Y 軸移動 -6px */
}
translateY() 是沿 Y 軸(垂直)方向移動。
因為指定的是 -6px,所以會從原本位置往上移動 6px。
▼按鈕2:往右移動
/* 箭頭 */
.btn.__x .arrow {
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn.__x:hover .arrow {
transform: translateX(6px); /* 沿 X 軸移動 6px */
}
translateX() 是沿 X 軸(水平)方向移動。
因為對箭頭指定了 6px,所以會從原本位置往右移動 6px。
scale()scale() 是以元素原本的大小為基準來放大或縮小。
原本大小視為 1,指定大於 1 的值就是放大,小於 1 的值就是縮小。
▼按鈕3:放大 1.1 倍
.btn.__scale:hover {
transform: scale(1.1); /* 放大為原本的 1.1 倍 */
}
因為指定了 scale(1.1),所以會從原本大小放大 1.1 倍。
若要縮小,可改成 scale(0.9),就能縮小到原本的90%。
接下來會將 transition 與 transform 結合,介紹更豐富的 UI 動畫點子。
這次會以容易活用的按鈕與卡片介面為主來介紹。
滑過時,按鈕底線會從左往右延伸的動畫。
同時也讓箭頭稍微往右移動,讓畫面在簡單中帶有動感。
【使用的 CSS】
transition: all 0.4s ease; 讓底線與箭頭的變化更平滑
transform: translateX(6px); 讓箭頭往右移動
See the Pen btn02 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<div class="item">
<span>線由左往右延伸</span>
<a class="btn">
<span class="btn_text">view more</span>
</a>
</div>
CSS
.btn {
position: relative;
max-width: 120px;
display: flex;
padding: 12px 20px;
font-size: 16px;
font-weight: bold;
text-decoration: none;
cursor: pointer;
color: #D20B08;
text-decoration: none;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn::after {
content: '';
position: absolute;
width: 0;
height: 2px;
bottom: 0;
left: 0;
background-color: #D20B08;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn_text::after {
content: '→';
display: inline-block;
margin-left: 12px;
transition: transform 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.btn:hover::after {
width: 100%;
}
.btn:hover .btn_text::after {
transform:translateX(6px); /* 向右移動 6px */
}
滑過時,圓形按鈕會放大,同時箭頭也會往右移動的動畫。
透過結合 scale() 與 translateX(),讓按鈕整體擴張的同時,箭頭也跟著移動。
【使用的 CSS】
transition: all 0.4s ease; 讓變化更平滑
transform: translateX(6px); 讓箭頭往右移動
transform: scale(1.1) 讓按鈕放大
See the Pen btn02 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<div class="item">
<span>圓形按鈕放大</span>
<a class="btn">
<span class="btn_text">view more</span>
<span class="arrow">→</span>
</a>
</div>
CSS
.btn {
position: relative;
max-width: 120px;
aspect-ratio: 1/1;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: bold;
box-shadow: 0 2px 10px rgb(153, 153, 153);
text-decoration: none;
background-color: #D20B08;
color: #ffffff;
text-decoration: none;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn .arrow{
font-size: 24px;
font-weight: normal;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.btn:hover {
opacity: 0.6;
transform: scale(1.1);
}
.btn:hover .arrow {
transform:translateX(6px); /* 向右移動 6px */
}
滑過時,背景色會由左往右變化。
將背景色設為偽元素 ::before,再使用 transform: scaleX() 讓它在水平方向伸縮來呈現。
【使用的 CSS】
transition: all 0.4s ease; 讓變化更平滑
transform: scaleX(0); 將水平方向尺寸設為 0,隱藏背景色
transform: scaleX(1); 將水平方向尺寸恢復為原本寬度,顯示背景色
transform: translateX(6px); 讓箭頭往右移動
transform: rotate(45deg); 旋轉 45 度
(透過指定 rotate() 旋轉 45 度,來重現箭頭「>」)
See the Pen btn03 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<div class="item">
<span>背景色由左向右變化</span>
<a class="btn">
<span class="btn_text">view more</span>
</a>
</div>
CSS
.btn {
position: relative;
max-width: 120px;
display: inline-flex;
align-items: center;
justify-content: space-around;
padding: 12px 32px;
font-size: 16px;
font-weight: bold;
text-decoration: none;
border-radius: 6px;
cursor: pointer;
color: #D20B08;
background-color: #ffffff;
border: 2px solid #D20B08;
overflow: hidden;
text-decoration: none;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 110%;
height: 110%;
background-color: #D20B08;
transform: scaleX(0); /* 將寬度縮小為 0 */
transform-origin: left;
transition: transform 0.4s ease; /* 0.4 秒內平滑變化 */
z-index: 0;
}
.btn_text {
position: relative;
z-index: 1;
}
.btn_text::after {
content: '';
display: inline-block;
margin-left: 6px;
width: 8px;
height: 8px;
border-top: 2px solid;
border-right: 2px solid;
transform: rotate(45deg); /* 旋轉 45 度,做成「>」 */
transition: transform 0.3s ease-out;
}
/* hover 時 */
.btn:hover {
color: #ffffff;
}
.btn:hover::before {
transform: scaleX(1); /* 將寬度設為 1,完整顯示 */
}
.btn:hover .btn_text::after {
transform:translateX(6px) rotate(45deg); /* 加上 translateX(6px) 讓箭頭往右移動 */
}
滑過時,背景色的漸層會改變的動畫。
透過結合色彩變化與箭頭移動,可以讓按鈕更有質感。
【使用的 CSS】
transition: all 0.4s ease; 讓變化更平滑
transform: translateX(6px); 讓箭頭往右移動
background: linear-gradient(75deg, #D20B08 0%, #fdff71 35%, #fcff2e 60%, #D20B08 100%); 調整漸層色彩與角度
background-size: 300% 100%; 調整漸層尺寸
background-position: 100% 0; 調整漸層顯示位置
overflow: hidden; 隱藏溢出部分
See the Pen btn04 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<div class="item">
<span>漸層變化</span>
<a class="btn">
<span class="btn_text">view more</span>
<span class="arrow">→</span>
</a>
</div>
CSS
.btn {
position: relative;
max-width: 120px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 42px;
/* 漸層色彩調整 */
background: linear-gradient(75deg, #D20B08 0%, #fdff71 35%, #fcff2e 60%, #D20B08 100%);
background-size: 300% 100%;
/* 漸層顯示位置調整 */
background-position: 100% 0;
border-radius: 50px;
overflow: hidden;
font-size: 16px;
font-weight: bold;
box-shadow: 0 2px 10px rgb(153, 153, 153);
text-decoration: none;
color: #ffffff;
text-decoration: none;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn .btn_text{
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.btn .arrow{
font-size: 24px;
font-weight: normal;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.btn:hover {
/* 調整漸層顯示位置 */
background-position: 0% 0;
}
.btn:hover .btn_text{
transform:translateX(6px); /* 向右移動 6px */
}
.btn:hover .arrow {
transform:translateX(6px); /* 向右移動 6px */
}
滑過時,卡片會出現框線與陰影的動畫。
透過結合 border 與 box-shadow 的變化,可以讓卡片看起來像是浮出前景般,帶有立體感。
【使用的 CSS】
transition: all 0.4s ease; 讓變化更平滑
transform: translateX(6px); 讓箭頭往右移動
See the Pen card01 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<p>透過框線與陰影營造立體感</p>
<div class="card_container">
<a class="card">
<div>
<h4 class="card_head">標題</h4>
<p class="card_body">文字文字文字文字文字</p>
</div>
<div class="view-more">
<span class="view-more__text">view more</span>
<span class="view-more__arrow">→</span>
</div>
</a>
<a class="card">
<div>
<h4 class="card_head">標題</h4>
<p class="card_body">文字文字文字文字文字</p>
</div>
<div class="view-more">
<span class="view-more__text">view more</span>
<span class="view-more__arrow">→</span>
</div>
</a>
</div>
CSS
.card {
background: #ffffff;
padding: 24px;
border-radius: 12px;
text-decoration: none;
display: flex;
flex-direction: column;
gap: 16px;
border: 2px solid #e2e8f0;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.view-more{
display: inline-block;
color: #D20B08;
font-weight: bold;
text-align: right;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.card:hover {
border-color: #D20B08;
box-shadow: 0 2px 10px rgb(153, 153, 153); /* hover 時加上陰影 */
}
.card:hover .view-more {
transform: translateX(6px); /* 向右移動 6px */
}
/* 其他樣式 */
.card_container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 16px;
}
.card_head{
font-size: 20px;
margin-bottom: 6px;
}
.card_body{
font-size: 12px;
color: #adadad;
}
滑過時,底線會延伸,卡片也會往上移動的動畫。
透過上移能讓卡片有浮起的感覺,再搭配線條、陰影變化與文字移動,可以提升點擊意圖。
【使用的 CSS】
transition: all 0.4s ease; 讓變化更平滑
transform: translateY(-8px); 讓卡片往上移動
transform: translateX(6px); 讓箭頭往右移動
See the Pen card02 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<p>底線與向上浮起</p>
<div class="card_container">
<a class="card">
<div>
<h4 class="card_head">標題</h4>
<p class="card_body">文字文字文字</p>
</div>
<div class="view-more">
<span class="view-more__text">view more</span>
<span class="view-more__arrow">→</span>
</div>
</a>
<a class="card">
<div>
<h4 class="card_head">標題</h4>
<p class="card_body">文字文字文字</p>
</div>
<div class="view-more">
<span class="view-more__text">view more</span>
<span class="view-more__arrow">→</span>
</div>
</a>
<a class="card">
<div>
<h4 class="card_head">標題</h4>
<p class="card_body">文字文字文字</p>
</div>
<div class="view-more">
<span class="view-more__text">view more</span>
<span class="view-more__arrow">→</span>
</div>
</a>
</div>
CSS
.card {
position: relative;
overflow: hidden;
background: #ffffff;
padding: 24px;
text-decoration: none;
display: flex;
flex-direction: column;
gap: 16px;
box-shadow: 0 1px 10px rgba(153, 153, 153, 0.5);
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.card::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 3px;
background-color: #D20B08;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.view-more{
display: inline-block;
color: #D20B08;
font-weight: bold;
text-align: right;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.card:hover {
box-shadow: 0 2px 10px rgb(153, 153, 153); /* 讓陰影更明顯 */
transform: translateY(-8px); /* 往上移動 8px */
}
.card:hover::after {
width: 100%; /* 讓底線從 0 變成 100% */
}
.card:hover .view-more {
transform: translateX(6px); /* 向右移動 6px */
}
/* 其他樣式 */
.card_container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 16px;
}
.card_head{
font-size: 20px;
margin-bottom: 6px;
}
.card_body{
font-size: 12px;
color: #adadad;
}
滑過時,圖片會從單色變成彩色,同時圖片也會稍微放大。
使用 filter 改變圖片色調,再用 scale() 讓圖片在父層內放大。
這種表現很適合用在圖片圖庫或文章列表。
【使用的 CSS】
transition: all 0.4s ease; 讓變化更平滑
transform: scale(1.1); 讓圖片放大
filter: grayscale(0%); 由單色變成彩色
(grayscale 100%:完全黑白,0%:恢復原色)
See the Pen card03 by y-maeda (@Maeda-Yoshie) on CodePen.
範例程式如下HTML
<p class="label">單色圖庫</p>
<div class="gallery">
<a class="gallery-item">
<img src="https://lh3.googleusercontent.com/d/1_QUDgFv8a3Lund9zRgj233amum3yLMW6" alt="sea">
<div class="gallery-box">
<span class="gallery-text">view more</span>
</div>
</a>
<a class="gallery-item">
<img src="https://lh3.googleusercontent.com/d/1UzvY8iYshkvJx8zcXk_O0fiwoY5zhNb8" alt="mountain">
<div class="gallery-box">
<span class="gallery-text">view more</span>
</div>
</a>
<a class="gallery-item">
<img src="https://lh3.googleusercontent.com/d/1IHiGU8T1DmDV3TAHTWu57X0rSpcnTxyA" alt="forest">
<div class="gallery-box">
<span class="gallery-text">view more</span>
</div>
</a>
</div>
CSS
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 16px;
}
.gallery-item {
flex: 1;
position: relative;
height: 160px;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
text-decoration: none;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
filter: grayscale(100%); /* 轉為黑白 */
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.gallery-item .gallery-box {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.25);
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
.gallery-text {
color: #D20B08;
font-size: 0.85rem;
font-weight: 700;
border: 2px solid #D20B08;
padding: 6px 16px;
border-radius: 6px;
transition: all 0.4s ease; /* 0.4 秒內平滑變化 */
}
/* hover 時 */
.gallery-item:hover img {
filter: grayscale(0%); /* 恢復為標準色彩 */
transform: scale(1.1);
}
.gallery-item:hover .gallery-box {
background: transparent;
}
.gallery-item:hover .gallery-text {
background-color: #ffffff;
border-color: #ffffff;
}
這次介紹了如何透過組合 transition、transform 等 CSS 屬性,替按鈕和卡片加入動態效果。
如果你是「知道 transition 和 transform,但其實很少用」的人,只要有意識地把它們加進設計中,我想 UI 表現的可能性會大幅提升。
不只是直接套用這次介紹的動畫,也很歡迎你嘗試調整色彩、移動距離、動畫速度等,做出更符合網站或 App 氛圍的表現。
感謝你讀到最後!
原文出處:https://qiita.com/nt_y-maeda112/items/48d124a11623b4f9e7c6