1. 程式人生 > 實用技巧 >CSS過渡時間

CSS過渡時間

CSS過渡時間

基礎知識

  在瞭解CSS過渡時間之前,你應該先了解一下CSS的變形動畫,可以參考之前的一篇部落格。

  我們的元素在屬性發生變化時,如果沒有特地的為它設定過渡時間,整個變化過程其實是以毫秒級別進行的,過程非常快,肉眼不易察覺。

  故我們要學習CSS過渡時間,來讓它的變化過程更加平滑。

動畫屬性


  不是所有css屬性都有過渡效果,檢視支援動畫的CSS屬性 ,一般來講有中間值的屬性都可以設定動畫如寬度、透明度等。

  可以看一下下面這個例子,比如邊框就不支援過渡效果,而其他的諸如背景顏色,高度寬度等等都是支援過渡效果的。

  可以看到,在滑鼠放上去的瞬間,邊框的樣式就發生變化了,而不是再跟隨過渡時間進行漸變。

  而其他的屬性,諸如背景顏色,圓角等都是跟隨過渡時間進行漸變的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
}

div{
height: 50px;
width: 50px;
background: #747d8c;
border: 10px solid #ff6348;
/* 新增過渡時間 1s */
transition: 1s;
}
body:hover div{
background: #5352ed;
border: 10px dotted #ffa502;
width: 100px;
height: 100px;
border-radius: 50%;
transform: translate(100px,100px);
}
</style>
</head>
<body>
<div></div>
</body>
</html>

程式碼示例

元素狀態

初始形態


  指當頁面載入後的樣式狀態,下面是表單設定的初始樣式。

變化形態


  指元素由初始狀態變化後的狀態,比如滑鼠放上、表單獲得焦點後的形態。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
} body {
background: #2c3e50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
• padding: 20px;
} input {
border: solid 5px #e67e22;
height: 60px;
width: 400px;
margin-bottom: 20px;
transition: 2s;
} input:hover {
border: solid 5px #000 !important;
} input:focus {
background: #e67e22;
} input:checked {
position: relative;
width: 60px;
height: 60;
border: none;
} input:checked::before {
content: '⩗';
color: white;
display: flex;
justify-content: center;
align-items: center;
font-size: 3em;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
box-sizing: border-box;
background: #3498db;
}
</style>
</head>
<body> <input type="text">
<input type="checkbox" checked> </body>
</html>

程式碼示例

transition-property

  用於設定哪些屬性應用過渡效果。

  預設值為all 即所有屬性都發生過渡效果

  多個屬性使用逗號分隔

  當我們使用該選項時,注意要和transition-duration搭配使用才能生效,這個才是非簡寫的過渡時間。

  transition只是一種簡寫形式,如果使用transition-durationtransition進行搭配使用,則不會生效transition-duration

屬性設定


  注意看,下面的這張圖片裡transition-duration只設定了圓角與透明度,其他的諸如寬度高度背景顏色等均未設定,所以在滑鼠放上去的一瞬間未設定的屬性立刻產生了變化,而圓角和透明度是隨著過渡時間漸漸變化的。

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
main{
width: 400px;
height: 400px;

display: flex;
justify-content: center;
align-items: center;

}

div{
width: 100px;
height: 100px;
background: #f39c12;
transition-property:border-radius,opacity;
/* 這個才是真正的設定過渡時間,
transition只是簡寫形式 */
transition-duration: 1s;
opacity: .5; }
main:hover div{
border-radius: 50%;
width: 150px;
height: 150px;
background: #2ecc71;
opacity: 1;
}
</style>
</head>

<body>
<main>
<div></div>
</main>
</body>

</html>

程式碼示例

禁用屬性


  當設定transition-property:none;後,所有的變化形態均不會跟隨過渡時間發生變化。

  也就是說全部都是瞬發完成。

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
main{
width: 400px;
height: 400px;

display: flex;
justify-content: center;
align-items: center;

}

div{
width: 100px;
height: 100px;
background: #f39c12;
transition-property:none;
/* 這個才是真正的設定過渡時間,
transition只是簡寫形式 */
transition-duration: 1s;
opacity: .5; }
main:hover div{
border-radius: 50%;
width: 150px;
height: 150px;
background: #2ecc71;
opacity: 1;
}
</style>
</head>

<body>
<main>
<div></div>
</main>
</body>

</html>

程式碼示例

transitionend

  用於控制過渡結束後執行的JS事件,簡寫屬性會觸發多次如 border-radius 會觸發四次事件,不難理解因為可以為border-bottom-left-radius 等四個屬性獨立設定過渡,所以就會有四次事件。

屬性 說明
propertyName 結束過渡樣式
elapsedTime 過渡需要的時間
pseudoElement 過渡的偽元素
isTrusted true:使用者觸發,false:指令碼觸發

  我們只需要有JS來監聽該事件即可,如下圖。

  當我們檢測的<div>標籤過渡時間結束後觸發了transitionend事件,然後才顯示出了恭候多時的字樣。

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh; }

main {
width: 400px;
height: 400px;

display: flex;
justify-content: center;
align-items: center;

}

div {
width: 100px;
height: 100px;
background: #f39c12;

transition-duration: 1s;

position: relative;


}

div:after {
content: "恭候多時";
color: #fff;
width: 100%;
font-size: 1.4em;

display: flex;
justify-content: center;
align-items: center;

position: absolute;
bottom: -50px;
transform: scale(0);
transition-duration: 1s;

}

main:hover div {
transform: rotate(360deg);
}

main:hover div.show-after::after {
transform: scale(1) skew(360deg);
}
</style>
</head>

<body>
<main>
<div></div>
</main>
</body>

<script>
// 檢測div的 transitionend 事件
document.querySelector('div').addEventListener('transitionend', function (e) {
console.log(e);
// 給div新增class為show-after
document.querySelector('div').className = 'show-after';
})
</script>

</html>

程式碼示例

  此時檢視一下瀏覽器控制檯,正好對應上表中的屬性。

transition-duration

  用於設定過渡時間,需要注意以下幾點

  可使用單位為 ms毫秒、s秒

  預設值為0s不產生過渡效果

  一個值時,所有屬性使用同樣的時間

  二個值時,奇數屬性使用第一個,偶數屬性使用第二個

  變化屬性數量大於時間數量時,後面的屬性再從第一個時間開始重複使用

統一時間


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
} body {
background: #2c3e50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
padding: 80px;
} main {
width: 400px;
height: 400px;
} div {
width: 150px;
height: 150px; border-radius: 50%;
opacity: 0.2;
transition-property: background-color, transform, opacity, border-radius;
transition-duration: 3s;
} div:hover {
opacity: 1;
border-radius: 0;
transform: scale(2) rotate(180deg); }
</style>
</head>
<body>
<main>
<div></div>
</main>
</body>
</html>

程式碼示例

兩個時間


  下面共有四個屬性並設定了兩個時間值,1,3屬性使用第一個值,2,4屬性使用第二個值。

...
div {
width: 150px;
height: 150px; border-radius: 50%;
opacity: 0.2;
transition-property: background-color, transform, opacity, border-radius;
transition-duration: 200ms, 5s;
}
...

多個時間


  下面共有四個屬性並設定了三個時間值,1,2,3屬性使用1,2,3時間值,第四個屬性再從新使用第一個時間值。

...
div {
width: 150px;
height: 150px; border-radius: 50%;
opacity: 0.2;
transition-property: background-color, transform, opacity, border-radius;
transition-duration: 200ms, 5s, 2s;
}
...

不同時間


  可以為初始與變化狀態設定不同的時間。

  下面是將hover 設定為3s,當滑鼠放上時變化時間為3s。為初始設定為1s即表示變化到初始狀態需要1s。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
} body {
background: #2c3e50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
padding: 80px;
} main {
width: 400px;
height: 400px;
} div {
width: 150px;
height: 150px;
background-color: #e67e22;
border-radius: 50%;
transition-property: background-color, transform, opacity, border-radius;
/* 結束時間,變回初始狀態 如果只有該時間,則過渡時間也採用它 */
transition-duration: 1s;
} div:hover {
border-radius: 0;
transform: scale(2) rotate(180deg);
background-color: #e67e22;
/* 過渡時間 */
transition-duration: 3s;
}
</style>
</head>
<body>
<main>
<div></div>
</main>
</body>
</html>

程式碼示例

transition-timing-function

  用於設定整體過渡效果的速度,可在 https://cubic-bezier.com 網站線上體驗效果差異。

預設引數


描述
linear 規定以相同速度開始至結束的過渡效果(等於 cubic-bezier(0,0,1,1))。預設值
ease 開始慢,然後快,慢下來,結束時非常慢(cubic-bezier(0.25,0.1,0.25,1))
ease-in 開始慢,結束快(等於 cubic-bezier(0.42,0,1,1))
ease-out 開始快,結束慢(等於 cubic-bezier(0,0,0.58,1))
ease-in-out 中間快,兩邊慢(等於 cubic-bezier(0.42,0,0.58,1))
cubic-bezier(n,n,n,n) 在 cubic-bezier 函式中定義自己的值

差異對比


  我們用linearease來做一個對比,左邊是linear,右邊是ease

  其實他們的過渡時間都是一模一樣的,只是視覺上有所差異。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw; display: flex;
justify-content: center;
align-items: center;
} main{
height: 400px;
width: 400px; display: flex;
justify-content: center;
align-items: center; border:1px solid #ddd;
}
main div{
height: 100px;
width: 100px;
margin: 20px;
transition-duration: 3s;
}
main div:nth-child(1){
background-color: #ff4757;
transition-timing-function:linear;
} main div:nth-child(2){
background-color: #3742fa;
transition-timing-function:ease;
} main:hover div{
width: 150px;
height: 150px;
border-radius: 50%;
} </style> </head>
<body>
<main>
<div></div>
<div></div>
</main>
</body>
</html>

程式碼示例

貝塞爾曲線


  其實不管是linear或者是ease都是由貝塞爾曲線來完成的。

  我們需要設定四個值 cubic-bezier(<x1>, <y1>, <x2>, <y2>)來控制曲線速度,可在 https://cubic-bezier.com 網站線上體驗效果。

  如以下是我自己調的一個數值,右邊的那個,對比的是linear這個預設的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw; display: flex;
justify-content: center;
align-items: center;
} main{
height: 400px;
width: 400px; display: flex;
justify-content: center;
align-items: center; border:1px solid #ddd;
}
main div{
height: 100px;
width: 100px;
margin: 20px;
transition-duration: 3s;
}
main div:nth-child(1){
background-color: #ff4757;
transition-timing-function:linear;
} main div:nth-child(2){
background-color: #3742fa;
transition-timing-function:cubic-bezier(.17,.67,.88,-0.47);
} main:hover div{
width: 150px;
height: 150px;
border-radius: 50%;
} </style> </head>
<body>
<main>
<div></div>
<div></div>
</main>
</body>
</html>

程式碼示例

步進速度


  過渡使用階梯化呈現,有點像現實生活中的機械舞,下面是把過渡分3步完成。

選項 說明
steps(n,start) 設定n個時間點,第一時間點變化狀態
steps(n,end) 設定n個時間點,第一時間點初始狀態
step-start 等於steps(1,start),可以理解為從下一步開始
step-end 等於steps(1,end),可以理解為從當前步開始

  start總是先走,end總是後走。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw; display: flex;
justify-content: center;
align-items: center;
} main{
height: 400px;
width: 800px; display: flex;
border:1px solid #ddd; position: relative;
}
main div{
width: 200px;
height: 100%;
border: 1px solid #ddd;
}
main::after{
content: "START";
height: 30%;
width: 25%;
background: #ff4757;
color: #fff;
font-size: 2em;
/* 過渡時間2s */
transition: 2s;
/* 相當於把2s分成三步走 */
transition-timing-function: steps(3, start); position: absolute;
top: 0; display: flex;
justify-content: center;
align-items: center; } main::before{
content: "END";
height: 30%;
width: 25%;
background: #70a1ff;
color: #fff;
font-size: 2em;
/* 過渡時間2s */
transition: 2s;
/* 相當於把2s分成三步走 */
transition-timing-function: steps(3, end); position: absolute;
bottom: 0; display: flex;
justify-content: center;
align-items: center;
} main:hover::before{
transform: translateX(600px);
} main:hover::after{
transform: translateX(600px);
} </style> </head>
<body>
<main>
<div></div>
<div></div>
<div></div>
<div></div>
</main>
</body>
</html>

程式碼示例

時鐘效果


  其實步進這樣一幀一幀的來走非常時候做時鐘,那麼這裡就做一個非常簡chou陋的時鐘吧。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw; display: flex;
justify-content: center;
align-items: center;
} main{
height: 400px;
width: 400px;
display: flex;
position: relative;
background:#ffa502;
box-shadow: 3px 3px 3px #2f3542;
border-radius: 50%;
}
main::after{
content: "";
height: 20px;
width: 20px;
border-radius: 50%;
position: absolute;
left: 50%;
top: 50%;
transform:translate(-50%,-50%);
background: #1e90ff;
}
main::before{
content: "";
height: 48%;
width: 6px;
position: absolute;
left: 50%;
bottom: 50%;
transform:translate(-50%,0);
background: #1e90ff;
transition-duration: 60s;
transition-timing-function:steps(60,start);
transform-origin: bottom;
} main:hover::before{ transform:translateX(-50%) rotate(360deg); } </style> </head>
<body>
<main></main>
</body>
</html>

程式碼示例

transition-delay

  用於設定延遲過渡的時間。

  預設為0s即立刻開始過渡

  值可以為負數

  變化屬性數量大於時間數量時,後面的屬性再從第一個時間開始重複使用

基本使用


  下面設定了延遲時間為1s,當滑鼠放上時產生變化。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
} body {
background: #2c3e50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
padding: 80px;
} main {
width: 400px;
height: 400px;
} div {
width: 150px;
height: 150px;
background-color: #e67e22;
border-radius: 50%;
transition-property: background-color, transform, opacity, border-radius;
transition-duration: 1s;
transition-delay: 1s;
} div:hover {
border-radius: 0;
transform: scale(2) rotate(180deg);
background-color: #e67e22;
}
</style>
</head>
<body>
<main>
<div></div>
</main>
</body>
</html>

程式碼示例

多值延遲


  可以設定不同屬性的延遲時間。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
} body {
background: #2c3e50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
padding: 80px;
} main {
width: 400px;
height: 400px;
} div {
width: 150px;
height: 150px;
background-color: #fff;
/* 一一對應 */
transition-property: background-color, transform, border-radius;
transition-duration: 1s, 2s, 3s;
transition-delay: 1s, 3s, 5s;
} div:hover {
border-radius: 50%;
transform: scale(2) rotate(180deg);
background-color: #e67e22;
}
</style>
</head>
<body>
<main>
<div></div>
</main>
</body>
</html>

程式碼示例

使用負值


  下例圓角屬性的過渡時間為4s,設定延遲為 -4s,表示滑鼠放上時直接顯示在4s上的效果。如果設定為-2s顯示圓角變形一半的效果。

  即對圓角來說不產生過渡,是瞬發的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
} body {
background: #2c3e50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
padding: 80px;
} main {
width: 400px;
height: 400px;
} div {
width: 150px;
height: 150px;
background-color: #fff; transition-property: background-color, transform, border-radius;
transition-duration: 1s, 2s, 4s;
transition-delay: 1s, 2s, -4s;
} div:hover {
border-radius: 50%;
transform: scale(2) rotate(180deg);
background-color: #e67e22;
} </style>
</head>
<body>
<main>
<div></div>
</main>
</body>
</html>

程式碼示例

transition

  可以使用transition 指令將過渡規則統一設定,需要注意以下幾點。

  必須設定過渡時間

  延遲時間放在逗號或結束前

  如果只設定一個數值,那麼該數值會認為是過渡時間

transition: border-radius linear 2s 0s,
background 2s 2s,
width linear 2s 4s,
height linear 2s 4s;
/* 參與過渡的動畫 貝塞爾曲線 過渡時間 延遲時間 */

點贊案例


<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src='https://blog-static.cnblogs.com/files/Yunya-Cnblogs/jQuery.js'></script>
<style>
body {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: #ecf0f1;
} div {
position: relative;
width: 100px;
height: 100px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
} div i.fa {
font-size: 100px;
position: absolute;
transition: all .5s;
color: #ddd;
} div.heart i.fa {
font-size: 400px;
color: #e74c3c;
opacity: 0;
} div.heart i.fa:nth-child(2) {
font-size: 80px;
color: #e74c3c;
opacity: 1;
}
</style>
</head> <body> <div onclick="heart()">
<i class="fa fa-heart" aria-hidden="true"></i>
<i class="fa fa-heart" aria-hidden="true"></i>
</div> </body>
<script>
function heart() {
$("div").toggleClass('heart');
}
</script> </html>

程式碼示例