CSS3總結系列1

南賜發表於2016-06-17

過渡

通過改變CSS屬性,它提供了一種控制動畫速度的方式.屬性改變沒有立刻結束,而是需要一定的時間.你可以直接列出哪些屬性需要進行動畫過渡,可以設定when–delay,how long-duration,how–timing function等等.

有哪些屬性可以參與動畫和過渡

這裡是mdn上的一個列表,這個列表裡面的屬性可以被過渡也可以被動畫.談及一點,auto屬性值最好不要用,不同瀏覽器的實現不太一樣,這裡是一個CSS3transition demo.

定義過渡的CSS屬性

類似於動畫,過渡也可以使用簡短的過渡屬性用來配置過渡,同時也使得過渡操作變得更容易,擺脫列表屬性全同步困難的束縛: transition-property,transition-delay,transition-duration,transition-timing-function.

過渡結束的監聽

類似於animationend,transitionend,webkitTransitionEnd事件會在過渡結束時被觸發,該事件提供兩個屬性:字串propertyName, 浮點數elapsedTime,單位秒,不受transition-delay影響.

el.addEventListener("transitionend", updateTransition, true);

各個屬性值列表長度不等時如何處理

//repeat
.transition1 {
    transition-property: opacity, left, top, height;
    transition-duration: 3s, 5s;
}
//equivalents to
.transition1 {
    transition-property: opacity, left, top, height;
    transition-duration: 3s, 5s, 3s, 5s;
}

//truncate
.transition2 {
    transition-property: width, height;
    transition-duration: 1s, 2s, 3s, 4s;
}
//dealt to be
.transition2 {
    transition-property: width, height;
    transition-duration: 1s, 2s;
}

這裡略帶提一下,CSS過渡和js控制過渡做對比的話,前者顯得更和緩,js過渡要求更高的熟練度.最後分享一個有關transitions的譯文

animation,transition,transform之間的比較

之前的一篇文章講到animation,transform,今天主要討論transition.發現前面都沒怎麼抓住重點,現在我得放放招.這裡是我寫的一個demo用來較為直觀地作出比較.從demo裡面可以看出:
1. animation
首先在要施加的動畫元素上新增動畫,可以是組合的方式:

animation: animating-paragragh 3s ease-in-out 1s infinite alternate;

也可以是分離的方式:

animation-name: animating-paragragph;
animation-duration: 3s;
animation-timing-function: ease-in-out;
animation-delay: 1s;
animation-iteration-count: infinite;
animation-direction: alternate;

兩種方式都至少包括兩項name和duration.想省程式碼的話就用簡寫的組合方式,沒有必要嚴格遵守規定順序(其實保持name(property) duration timing-function delay iteration-count direction這樣的順序好一些,可以更改但是duration和delay的順序要保持不變,name的取名不要和其他屬性值重複混淆.另外transform沒有這樣的組合屬性值列表),然後動畫主幹在於關鍵幀@keyframes:

@keyframes animating-paragragh { 
  from {
      width: 500px;
      color: #b0a;
  }
  50% {
    width: 600px;
    color: #0f9;
  }
  to {
    width: 800px;
    color: #00c;
  }
}

動畫原理在於timing-function,本質是三次貝塞爾Cubic Bezier速度曲線,linear和ease類都是其特殊情況(linear從頭到尾速度不變;預設的ease以低速開始,然後加快,在結束前減速變慢;ease-in以低速開始,ease-out和ease-in-out類推,中間過程都沒有像ease那樣的加快,這裡有個特別棒的w3school上的demo用來揭示這種區別.數學果然還是計算機技術的靈魂,有興趣的可以課後去了解了解cubic-bezier.)
2. transition
transition的使用有別於animation,首先是宣告transition屬性,類似animation有組合式也有分離式,但是transition沒有animation那麼多的細分屬性,只有property, duration, timing-function, delay.然後在hover的時候再給有關的transition-properties設定新值.
3. transform
分為2D和3D,它不像animation和transition,它既可以在hover的時候把過程表現出來,也可以直接展示轉換後的結果,沒有任何動畫或者過渡.2D和3D的屬性上有較多差別.轉換是元素改變位置,尺寸,形狀的一種效果.移動translate,旋轉rotate,2d的平面傾斜skew,縮放scale,還有全力詹matrix(),matrix3d().這是zxx前輩的transform matrix文章,除了可以做到任何普通轉換還可以映象對稱等等,要把matrix計算透也是蠻複雜的一件事,zxx前輩寫的這篇文章很不錯,IE矩陣濾鏡,SVG,canvas都和矩陣相關,這貨很有戲份.

  • 2D
    transform,transform-origin屬性,屬性值當中的方法包括matrix(n, n, n, n, n, n),translate(x, y),translateX(x),translateY(y),scale(x, y),scaleX(n),scaleY(n),rotate(angle),skew(x-angle, y-angle),skewX(x-angle),skewY(y-angle)

有一點需要注意一下,單位px,deg等等比較容易遺忘.

  • 3D
    3D相對2D更為複雜一些,有關transform的屬性除去transformtransform-origin還有transform-style被巢狀元素如何在3D空間中顯示,perspective3D元素的透視效果,perspective-origin3D元素的底部位置,backface-visibility定義元素在不面對螢幕時是否可見,w3school上面有很好的demo,transform的屬性值相對2D而言,其中的方法有translate3d(x, y, z) translateX(x), translateY(y), translateZ(z),可見帶上`3D性質`,scale和rotate依此類推,還有個額外的persctive(n)方法用來定義3D轉換元素的透視檢視.

4. 綜合比較

  • animation和transition都帶有過程性質,一般從初始狀態到hover等事件觸發的結束狀態,hover後滑鼠立即離開,都有相反動畫或者相反過渡出現.講到這個,我得談談animation-fill-mode,animation-play-state,之前沒怎麼介紹到,fill-mode表示動畫結束時的狀態,play-state是指動畫執行狀態.這裡有一篇文章講解地還行,還有一篇阮老師的文章,瞭解到一些新東西,animation keyframes之間的自動推算與平滑過渡,steps函式,transition無法由頁面初始渲染出來(因為初末狀態決定了transition的具體過渡過程,初始渲染沒有確定末狀態)等等…總體上講得不錯不過有些觀點不太認同,比如說…一條transition規則,只能定義一個屬性的變化,不能涉及多個屬性…評論區比較雜還大多沒有樓主回覆與點贊反對功能,所以說還是自己思考為主,要想全面認識的話還是得多思考多實踐多查閱不同的資料.

  • 這篇文章還有w3cplus上的一篇文章瞭解到除了hover等簡單事件之外還可以通過jQuery或者原生js addClass removeClass這樣類似的方式來控制動畫與過渡.

  • animation作用於元素本身,而不是樣式屬性,可用於動畫的樣式屬性有很多,關鍵幀的使用使得動畫控制可以很靈活,幀數越多動畫細節控制得越好,但是若中間幀當中涉及需要進行動畫屬性變多的話,動畫本身也會變得更復雜.

  • transition關注的主體是樣式屬性property,而不是元素本身,需要過渡的屬性在過渡之前就需要給出定義或者以組合的形式,所以說沒有animation的關鍵幀那麼自由,更簡單實用些;transition屬性值當中的種類也更少,和animation共有的duration,timing-function,delay.transition缺點主要在於靈活性降低.

  • animation和transition都有animationEnd,transitionEnd等事件,所以都可以用js控制,但是這需要更高的熟練度和程式碼量,用得好會有很好的效果.

  • transform更關注的渲染出的2D,3D效果,而不是過程.其實完全可以把transform劃到animation名下,作為某一幀的一部分,只不過這個特殊屬性作用於整個element.

5. 相容性
就算不考慮日漸萎靡的IE,animation,transition,transform三者都推薦的做法:第一個屬性加上webkit字首,第二個不加,這樣既能相容像chrome29,safari8這樣的PC端webkit系低版本(話說其實用chrome的人還會用29嗎,早就更新成50了),還可以相容Mobile端的Android Browser,UC Mobile等等。transform也一樣,看了看Animate.css原始碼也確實是這樣.
caniuse確實是個好東西,推薦你選中relative usage,會更有幫助.
6. 有關Animate.css
既然我現在在animation,transition,transform作出比較,那肯定有辦法把三者的優勢結合起來作出更簡單更精彩更實用的動畫.Animate.css便是這樣的例子,它結合了animation和transform,沒有transition沒有派上用場因為transition與animation共存於一個element上面比較不容易控制,況且始末狀態決定過程的transition沒法做好複雜動畫,只有一個個keyframes加上能做到精細控制速度曲線的cubic-bezier數學函式才有可能做好複雜動畫.原始碼有3000多行並不算太多,但是作出的效果很有感覺,重點在於cubic-bezier的使用以及和transform各個屬性的結合,以構成可以複用動畫庫.
Animate.css使用:

  • 第一步

//firstly, you need to include this stylesheet in document`s `<head>`
<head> 
    <link rel="stylesheet" href="animate.min.css">
<head>
  • 第二步
    給需要進行動畫的元素加上animated,有需要的話加上infinite等等.

<div class="animated inifinite">A block using Animate.css.</div>   
  • 第三步
    加上`animation-name`

<div class="animated inifinite pulse">A block using Animate.css.</div>   

name列表:bounce, flash, pulse, rubberBand, shake, headShake, swing, tada, wobble, jello, bounceIn, bounceInDown, bounceInLeft, bounceInRight, bounceInUp, bounceOut, bounceOutDown, bounceOutLeft, bounceOutRight, bounceOutUp, faceIn, fadeInDown, fadeInDownBig, fadeInLeft, fadeInLeftBig, fadeInRight, fadeInRightBig, fadeInUp, fadeInUpBig, faceOut, fadeOutDown, fadeOutDownBig, fadeOutLeft, fadeOutLeftBig, fadeOutRight, fadeOutRightBig, fadeOutUp, fadeOutUpBig, flipInX, flipInY, flipOutX, flipOutY, lightSpeedIn, lightSpeedOut, rotateIn, rotateInDownLeft, rotateInDownRight, rotateInUpLeft, rotateInUpRight, rotateOut, rotateOutDownLeft, rotateOutDownRight, rotateOutUpLeft, rotateOutUpRight, hinge, rollIn, rollOut, zoomIn, zoomInDown, zoomInLeft, zoomInRight, zoomInUp, zoomOut, zoomOutDown, zoomOutLeft, zoomOutRight, zoomOutUp, slideInDown, slideInLeft, slideInRight, slideInUp, slideOutDown, slideOutLeft, slideOutRight, slideOutUp.Animate.css還可以通過addClass方法動態新增
Animate.css相關動畫樣式,one方法檢測animateEnd動畫事件等等,來和jQuery結合使用.
另外Loaders.css是一個純css載入類動畫庫,公司財務系統裡面有關表格資料的重新整理用上了它,用起來很方便,使用者體驗很棒.

CSS多背景

.multiple-backgrounds {
    background: bg1, bg2, ..., bgN;
}

之前沒聽過,竟然還有這東西,現在在mdn上看到…多個背景層是一層一層堆上去的,bg1放在最頂層,貼近螢幕,bgN放在最底層,遠離螢幕,只有bgN才可以使用有效的background-color屬性,其他層無效.background的每個子屬性順序是相互對應的.

.multi-bgs {
    width: 400px;
    height: 400px;
    background-image: url1, url2, linear-gradient(to right, #567, #fed);
    background-repeat: no-repeat repeat, repeat-y;
    background-position: bottom right, left, right;

相關文章