CSS 3學習——transition 過渡

來源:互聯網
上載者:User

標籤:proc   block   應該   目標   同時存在   移動   text   draft   多次   

以下內容根據官方規範翻譯以及自己的理解整理。

1.介紹

這篇文檔介紹能夠實現隱式過渡的CSS新特性。文檔中介紹的CSS新特性描述了CSS屬性的值如何在給定的時間內平滑地從一個值變為另一個值。

2.過渡transitions

通常情況下,當CSS屬性發生改變時,對應元素的CSS屬性值立即從舊值變為新值,渲染結果也是立即更新。這部分介紹一種方法,可以通過使用新的CSS屬性指定過渡的過程。這些新屬性讓元素以平滑動畫的形式逐漸地從舊狀態過渡到新狀態。

比如,假設一個元素的left屬性和background-color屬性被設定了1s的過渡:位置從左至右,背景顏色從紅色到藍色(其他的過渡參數為預設值)。下面的圖展示了這個元素的過渡過程。

left和background-color的過渡

過渡是一個視覺效果。被設定了過渡的屬性的值逐漸地從舊值變為新值,因此如果一個指令碼查詢了正處在過渡過程中的元素的屬性值,那麼它將得到一個表示當前動畫狀態的中間值。

只有可動畫的CSS屬性才能設定過渡,具體看Properties from CSS,瞭解哪些屬性是可動畫屬性。

給一個屬性設定過渡要使用幾個新的CSS屬性。比如:

例1

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

上面這個例子在opacity屬性上定義了一個過渡(transition)。如果一個新值被指定給opacity,那麼舊值就會用兩秒鐘的時間逐漸地變為新值。

transition的每個分屬性都可指定一個以逗號分隔的值列表,允許指定多個屬性的過渡,每個過渡對應不同的屬性。在下面的例子中,每個過渡按照其在列表中的順序匹配參數。

例2

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

這個例子中opacity屬性對應的過渡時間為2s,left屬性對應的過渡時間為4s。

在下面的例子中,transition的分屬性的值列表長度不一樣長。當過渡(transitions)開始時,transition-property屬性的列表長度決定了其他分屬性的值列表的條目數。值列表的匹配從第一個值開始,最後多餘的值被忽略。如果有分屬性的以逗號分隔的值不足以匹配transition-property屬性的值列表,那麼使用者代理程式必須重複該分屬性的值列表,以使他的值列表足以匹配transition-property屬性的值列表。這些值的截斷或重複不會影響最終值的計算。注意:這類似於背景樣式的相關屬性,transition-property屬性類似於background-image屬性。

例3

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

上面的例子中定義了opacity屬性過渡的期間為2s;left屬性過渡的期間為1s;top屬性過渡的期間為2s;width屬性過渡的期間為1s。

注意:開發人員可以利用過渡建立動態變化地內容,而動態變化地內容可能導致某些使用者的癲癇發作。

2.1. transition-property 屬性

值:none | <single-transition-property> #;

其中<single-transition-property> = all | <custom-ident>;

預設值:all

不可繼承

適用於:all elements, ::before and ::after pseudo elements。

none

  表示沒用屬性會過渡

all

  表示所有可動畫的屬性都會表現出過渡動畫。

如果transition-property的值列表中有標識符不是一個可識別的屬性名稱或者不是一個可動畫(animatable)的屬性,瀏覽器在具體實現時必須仍舊從transition-duration屬性, transition-delay屬性和 transition-timing-function屬性的值列表的第一項開始匹配。也就是說,不可識別的屬性名稱或不可動畫的屬性必須仍然佔據他們在值清單項目中的位置以參與值的匹配。

例4

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

這個例子中opacity屬性匹配到2s;nothing是不可識別的屬性名稱,仍然匹配到3s;width匹配到4s。

<single-transition-property>產生的<custom-ident>要排除關鍵字“none”,另外也要排除其他非法的關鍵字。也就是說,關鍵字“none”,“inherit”,“initial”是不允許出現在值列表中的,使用了上述關鍵字的值列表將是文法無效的(文法無效,即整個transition-property無效。無效後,瀏覽器用了預設值all。其他分屬性同理)。

對於關鍵字“all”或者簡寫速記屬性,瀏覽器在實現時必須給速記簡寫屬性的所有可動畫的分屬性添加過渡,匹配transition-duration,transition-delay,和 transition-timing-function參數時使用速記簡寫屬性匹配。

如果一個屬性在transition-property屬性中指定了多次(不管是用它自身的屬性名稱還是用“all”關鍵字,還是用包含它的簡寫屬性),那麼使用其在transition-property值列表中最後一個位置匹配到的參數進行過渡。

注意:all關鍵字與簡寫速記屬性以相似的方式起作用,所以說,all關鍵字可以看做所有可動畫的屬性的簡寫形式。

2.2. transition-duration 屬性

transition-duration屬性定義一次過渡所花費的時間長度(過渡時間)。

取值: <time> #

以s或ms為單位。

預設值:0s

不可繼承

適用於:all elements, ::before and ::after pseudo elements

這個屬性指定過渡從舊值變為新值所花費的時間。預設值是“0s”,表示

舊值立即變為新值,沒有動畫效果。如果是負值,則整個transition-duration無效,使用預設值。

2.3. transition-timing-function屬性

transition-timing-function屬性描述在過渡期間中間值如何計算。它允許在過渡期間改變過渡的速度,這些效應稱為easing 函式。不管那種情況,一個可提供平滑曲線的數學函數可以被使用。

Timing functions可以被指定為stepping function(步進函數)或者cubic Bézier curve(三次貝茲路徑)。指定的這個timing function把當前經過的過渡時間的百分數當做他的輸入值,輸出從開始值到結束值的百分比。至於如何使用這個輸出結果,參見interpolation rules。

Stepping function用一個數字(相當於總的步數或分成的區間數)把範圍(過渡時間)分成相同大小的區間。每經過一個區間,就向最終的目標狀態前進相等的一步。這個函數也可以指定輸出百分比的變化是發生在區間的起始點還是發生在區間的結束點(in other words, if 0% on the input percentage is the point of initial change,實在看不懂這句啥意思)。

我的理解:start表示區間結束點的狀態(主要畫面格)插入到區間開始點(值立即變為區間結束點對應的值);end表示區間結束點的狀態(主要畫面格)出現在他原本應該出現的位置。所以start立即發生,end延遲一個區間的時間發生。

 

Step timing functions

一個三次貝茲路徑由4個控制點定義:P0,P1,P2,P3(如)。P0和P3通常設定為(0,0)和(1,1)。transition-timing-function屬性可以用來指定點P1和P2的值。可以使用預設的關鍵字(後面內容中會列舉),或者也可以用cubic-bezier()函數。在cubic-bezier()函數中,P1和P2都用一個X值和一個Y值指定。

Bézier Timing Function Control Points

transition-timing-function屬性

取值:<single-transition-timing-function> #;

<single-transition-timing-function> = ease | linear | ease-in | ease-out | ease-in-out | step-start | step-end | steps(<integer>[, [ start | end ] ]?) | cubic-bezier(<number>, <number>, <number>, <number>)

預設值:ease

適用於:all elements, ::before and ::after pseudo elements

Timing functions可以用下面的值定義:

關鍵字:

ease

    與ease-in-out有點類似,剛開始速度急劇增加,到接近中間點時速度開始降低,相當於cubic-bezier(0.25, 0.1, 0.25, 1)。

linear

   從開始狀態勻速地過渡到最終狀態,相當於cubic-bezier(0, 0, 1, 1)。

ease-in

   剛開始過渡速度很慢,然後逐步加速直到到達最終狀態,同時動畫立即停止相當於cubic-bezier(0.42, 0, 1, 1)。

ease-out

    過渡動畫剛開始速度很快,然後逐步減速,直到過渡到最終狀態,相當於cubic-bezier(0, 0, 0.58, 1)。

ease-in-out

    從開始到中間點類似於ease-in,從中間點到最終狀態類似於ease-out,相當於cubic-bezier(0.42, 0, 0.58, 1)。

step-start

    相當於steps(1, start)。使用這個值時,元素立即從開始狀態跳轉到最終狀態,然後在最終狀態停留transition-duration設定的時間。

step-end

    相當於steps(1, end)。使用這個值時,元素先在其初始狀態停留transition-duration設定的時間,然後再直接跳轉到最終狀態。

函數:

steps()

文法:steps(number_of_steps, direction)

numbers of steps必須是一個大於0的正整數,表示步數或等分的區間數。

direction可以取“start”或“end”中的一個,表示值的改變發生在區間中的哪一點。如果省略,則作為 “end”處理。

cubic-bezier()

文法:cubic-bezier(<number>, <number>, <number>, <number>)

指定一個三次貝茲路徑。前兩個值是點P1的橫座標和縱座標,後兩個值是點P2的橫座標和縱座標,(x1,y1, x2,y2)。橫座標必須在[0, 1]區間內否則無效,縱座標可以超出這個區間範圍。如果指定一個無效的三次貝茲路徑,則整個transition-timing-function屬性無效,瀏覽器使用預設值。

2.3.1. 序列化timing function

使用在[CSSOM]中定義的常用的序列化模式序列化Timing function,另外還要加上以下要求:

  • l  序列化之前,ease, linear, ease-in, ease-out,和ease-in-out這些關鍵字值不轉換為等價的cubic-bezier()函數。
  • l  步進時間函數(Step timing functions),不管用的是steps()還是關鍵字step-start或step-end都按以下規則序列化:
  1. 如果值的改變發生在結束點(相當於steps()函數的第二個參數為end),按照steps(<integer>)序列化
  2. 否則的話按照steps(<integer>, start)序列化。
2.4. transition-delay屬性

transition-delay屬性定義了過渡什麼時候開始。當一個過渡被應用時,通過該屬性可以指定該過渡開始之前所要等待的時間(也就是延遲時間)。如果值為0s,說明被指定了過渡效果的屬性的值改變時,過渡動畫馬上開始。否則的話,當被指定了過渡效果的屬性的值改變時,過渡動畫要延遲指定的時間後才開始。

如果transition-delay屬性的值為負值,過渡動畫會在被指定了過渡效果的屬性的值發生改變時立即開始。

transition-delay

可取值:<time> #,單位s或ms

適用於:all elements, ::before and ::after pseudo elements

預設值:0s

不可繼承。

例5 transition-delay為負值的情況 點這裡看線上demo。

transition-delay為負值時,過渡的實現過程:

當transition-delay的絕對值大於等於transition-duration的值時,沒有過渡動畫效果。觸發過渡時,立即從開始狀態變為結束狀態。

當transition-delay的絕對值小於transition-duration的值時,有過渡動畫效果。觸發過渡時,瀏覽器認為過渡動畫已經經過了transition-delay的絕對值的時間,過渡實際上是花費了transition-duration - (-transition-delay)的時間從中間狀態逐漸層為結束狀態,具體看例5中transition-delay為-1s時的情形。

2.5.transition屬性

transition屬性是前面介紹的4個屬性的簡寫屬性。

可取值: <single-transition> #

<single-transition> = [ none | <single-transition-property> ] || <time> || <single-transition-timing-function> || <time>

也就是transition-property + transition-duration + transition-timing-finction + transition-delay,中間用空格分隔,省略的取分屬性的預設值。如果指定多個屬性的過渡效果,不同屬性值的過渡效果用逗號隔開。

預設值:參見前面的4個分屬性。

不可繼承。

適用於:all elements, ::before and ::after pseudo elements

在使用transition屬性指定可動畫屬性的過渡效果時,如果在值列表中存在代表transition-property屬性的值為none,則整個transition聲明將無效,瀏覽器轉而使用預設值all。

3. 過渡的開始

瀏覽器(implementations,下同)在實現過渡時必須維持一個正在進行中的過渡(running transitions)的集合,這些過渡被應用於特定的元素及其非簡寫的屬性。這些過渡都有各自的開始時刻(start time),結束時刻(end time),開始值(start value),結束值(end value),回動調整開始值(reversing-adjusted start value),和回動縮短係數(reversing shortening factor)。瀏覽器在實現過渡時按照該部分內容所描述的那樣給每一個過渡添加上述一些列的參數,以及當過度完成或要取消過渡時移除這一系列的參數。對於回動調整開始值(reversing-adjusted start value),和回動縮短係數(reversing shortening factor)。

瀏覽器當然也必須要維持一個已完成的過渡(completed transitions)的集合。就像running transitions一樣,completed transitions也被應用於特定的元素及其非簡寫的屬性。本規範聲明對於同一個元素以及同一個屬性而言,永遠不會同時存在一個running transition和一個completed transition。

如果一個元素不再存在於document中,瀏覽器必須移除應用在該元素上的所有running transitions,同時也必須從completed transitions的集合中將其移除。

為了在某些特定情況下阻止重複地過渡,一個completed transitions的集合需要被維持。本規範同時聲明不相關的樣式的改變不會觸發過渡。

例6 過渡效果的繼承

在這個例子中,一個可繼承的屬性被指定了過渡,completed transitions集合的維持是有必要的。父元素在一個屬性上指定了較長期間的過渡(如:transition: 4s text-indent;)同時子項目的這個屬性的值繼承自父元素,而且子項目在這個屬性上指定了較短期間的過渡(如:transition: 1s text-indent;)。

如果是後代元素的可繼承屬性設定了過渡,那麼如果祖先元素該屬性的值發生了改變同樣會觸發後代元素上設定的過渡。

如果後代元素過渡的完成先於祖先元素的過渡,那麼後代元素將會重新開始從他的父元素繼承相應的屬性值(繼續過渡)。這樣的效果可能不是預期想要的效果,但是對於開發人員的要求來說這是必要的。(我測試的結果是,Firefox中是這種效果,Chrome中不是這種效果。Chrome中是先讓祖先元素到達最終狀態,後代元素的過渡才開始)。

 1 p{ 2     border:1px solid black; 3     transition:4s text-indent; 4 } 5 p:hover{ 6     text-indent:50px; 7 } 8 quote{ 9     display:block;10     transition:1s text-indent;11 }12 quote:hover{13 text-indent:inherit;    14 }15 <p>16     Maintain that unrelated style changes do not trigger transitions.17     <quote>This set of completed transitions needs to be maintained。</quote>18 </p>

具體效果點這裡。

下面這段內容理解不了。

許多東西都能引起一個元素的屬性的計算值的改變,包括從文檔樹中移除和插入元素,改變文檔樹引起的選取器匹配到的元素的改變,修改樣式表或者樣式屬性以及其他一些東西。本規範沒有定義什麼時候更新計算值,除了說瀏覽器禁止使用,呈現或顯示來源於無計算值更新的CSS cascading、value computation和inheritance process (這意味著瀏覽器不可避免地會遇到把規範聲稱的無計算值變更的情形作為樣式變更的一部分處理)。然而,當瀏覽器為了反映這些改變而更新一個元素的屬性的計算值時,或者計算新添加進文檔中的元素的屬性的計算值時,瀏覽器必須同一時間更新所有元素以及所有屬性的計算值以反映這些變化(或者至少說雖然瀏覽器在不同時間更新了這些變化,但是讓使用者察覺不到這些更新不是同時發生的,而是讓使用者感覺到這些更新是同時發生的)。一組樣式同步更改的過程稱為樣式變更事件(style change event)。瀏覽器通常都有一個style change event與他們所要求的螢幕重新整理率(screen refresh rate)相一致。同時,計算樣式或者布局資訊的及時更新對於依賴於此的指令碼API是必要的。

因為規範沒有規定style change event具體什麼時候發生,所以只要是計算值的變更都被認為是同步發生的。開發人員應該清楚,在計算值改變後,不同的瀏覽器對過渡屬性的值的更新時間存在差異,有的瀏覽器認為這些變更是同步的,而有些則不這麼認為。

當一個style change event發生時,瀏覽器必鬚根據本次事件中計算值的變更開始實現過渡。如果在style change event發生期間或發生之前(previous style change event),有元素不在文檔中,那麼對於本次style change event這個元素的過渡就不會開始。另外,定義before-change style作為previous style change event的元素的所有屬性的計算值(computed values),衍生自聲明式動畫(animations)的樣式除外,比如CSS Transitions, CSS Animations ([CSS3-ANIMATIONS]), and SMIL Animations ([SMIL-ANIMATION], [SVG11]),這些樣式的更新是即時更新的(updated to the current time)。同樣地,定義after-change style作為style change event開始時元素的所有屬性的計算值,但是源自CSS Transitions的計算樣式以及繼承自父元素的after-change style除外。

對於每一個有before-change style和after-change style的元素,並且對於該元素的每一個屬性(非簡寫屬性),定義matching transition-property value作為該元素after-change style中transition-property的最終值(當然是按照2.1小節的描述計算最終值)。與其相一致地,定義matching transition duration,matching transition delay,和matching transition timing function作為該元素在after-change style中transition-duration,transition-delay,和transition-timing-function的最終值。定義過渡的combined duration作為max(matching transition duration, 0s)和matching transition delay。對於每一個元素和屬性,瀏覽器必須按以下規則執行:

具體看規範:https://drafts.csswg.org/css-transitions/#matching-transition-duration

 

注意:當一個可動畫屬性的計算值(computed value)改變時,過渡根據transition-property,transition-duration,transition-timing-function和transition-delay屬性當前最新的計算值開始。也就是說當一個指定了過渡效果的屬性的值改變的同時,其對應的transition-*屬性也發生了改變,那麼該屬性的過渡效果由當前最新的transition-*屬性的值控制。

這可以讓開發人員分別給過渡的兩個不同狀態(前進:forward和回動:reverse)指定不同的transition-*屬性值。開發人員可以在觸發過渡的同時給transition-property,transition-duration,transition-timing-function和transition-delay屬性指定另外的值。因為transition-*屬性的當前最新值控制過渡,所以這些觸發過渡後新指定transition-*的值將覆蓋觸發過渡前transition-*的值控制過渡。

上面兩段內容說的是一個意思。

例7

li {  transition: background-color linear 1s;  background: blue;}li:hover {  background-color: green;  transition-duration: 2s; /* applies to the transition *to* the :hover state */}

上面例子中,清單項目進入懸停狀態時背景顏色變為綠色,同時transition-duration的值變為2s,所以清單項目的背景色從藍色過渡到綠色用了2s,而不是1s;當清單項目從懸停狀態恢複到原來狀態時,transition-duration的值變為1s,所以背景色從綠色過渡到藍色用了1s而不是2s。

點我看demo

注意:

一旦一個屬性開始過渡(包括進入延遲期間),其過渡效果仍然基於原來的timing function,duration和delay,即使在過渡完成前transition-timing-function,transition-duration或者transition-delay屬性的值被修改(注意這裡不是前文例子中的情形,前文例子中timing function,duration和delay是同步被修改的,這裡是延遲修改)。見上面demo中的例8

但是,如果是transition-property的值被修改,那麼原來指定了過渡效果的屬性的過渡會立即停止,其值會立即變為最終的值。見上面demo中的例9

注意:上述規則意味著聲明式動畫(declarative animation,與指令碼式動畫(scripted animation)相反)引起的屬性計算值的改變不會觸發過渡。因為對於聲明式動畫來說,before-change style包含up-to-date style。

3.1. 快速回動過渡

對於過渡來說,在他完成之前插值改變屬性的值,就會重設過渡的開始值。比如當滑鼠指標懸停在元素上時,元素的過渡效果開始,然後在過渡效果完成前滑鼠指標從元素中退出。如果滑鼠移出和移進的過渡使用的是原來指定的durations和timing functions,那麼最終的過渡的效果將會是錯亂的,因為第二次過渡使用了完整的duration移動了一個縮短的距離。作為替代,規範聲明讓第二次過渡相應地也縮短。

上述規則中的機制用於導致reversing shortening factor和reversing-adjusted start value的回動過渡。特別是回動階段reversing shortening factor小於1的時候。

 

4. 轉換事件

過渡的建立、開始、完成和取消會產生相應的DOM事件。對於指定了過渡效果的元素的屬性實際上是該屬性的分屬性觸發了轉換事件。比如通過border-width屬性指定元素邊框寬度從0px過渡到20px,那麼border-top-width,border-right-width,border-bottom-width和border-left-width都觸發了轉換事件。前進階段可以觸發轉換事件,回動階段同樣也可以觸發轉換事件。

4.1. 轉換事件介面4.1.1. 轉換事件屬性

propertyName

  唯讀,字串類型,返回與過渡綁定的CSS屬性名稱。

elapsedTime

  唯讀,浮點數,返回過渡觸發後已經啟動並執行時間,包括延遲時間,單位s。

pseudoElement

  唯讀,字串類型,返回傳生過渡的CSS虛擬元素的名字(這種情況下,事件的目標target是與該虛擬元素相對應的元素)或者返回一個Null 字元串(也就是說發生過渡的元素不是虛擬元素)。

TransitionEvent(type, transitionEventInitDict)

   是一個事件構造器,用給定的參數建立一個轉換事件。具體參見MDN。

4.2.  轉換事件的類型

transitionrun

   目前還沒有瀏覽器支援該事件。

    當一個過渡被建立的時候觸發(或者說當過渡被添加到running transitions集合中時觸發)。

    對於transitionrun,如果transition-delay值為負,則elapsedTime屬性傳回值等於: min(max(-transition-delay, 0), transition-duration)。

transitionstart

    目前只有IE10+支援該事件。

    當過的延遲時間走完時觸發。

    對於transitionstart,elapsedTime返回的值與transitionrun一樣。

transitionend

    所有現代瀏覽器都支援該事件。

    當過渡完成時觸發。如果在過渡完成之前該過渡被移除了,比如transition-property被移除,那麼,不會觸發transitionend。

    對於transitionend,elapsedTime返回的值等於transition-duration的值。

    如果過渡延遲時間為負值,且絕對值大於等於過渡期間時,不會產生過渡效果,也不會觸發轉換事件

transitioncancel

    目前還沒有瀏覽器支援該事件。

    當過渡被取消時觸發。

    對於transitioncancel,elapsedTime返回過渡延遲結束時刻到過渡被取消時刻的秒數。

如果transition-delay的值為負,過渡開始的時刻等於過渡真正觸發時刻之前transition-delay絕對值的秒數。

如果transition-delay的值為正,而且transitioncancel在過渡的延遲時間結束前觸發,那麼其elapsedTime返回0。

 

轉換事件通過DOM的 addEventListener() 方法添加。

點我查看demo。

 

參考資料和相關文章:

1、規範原文

2、深入理解CSS過渡transition

3、CSS3 Transition的唯一事件:TransitionEnd

4、MDN

CSS 3學習——transition 過渡

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.