圖片翻轉切換,在不使用CSS3的情況下,一般都是使用JS實現動畫,同時操作元素的width和left,或者height和top以模擬翻轉的效果,並在適當時候改變src或者z-index實現圖片切換。
無意中發現CSS3的方案, http://www.webhek.com/css-flip/ 趕緊學習並總結如下
先上代碼(多數照搬自上述鏈接,有很大兼容問題,小心使用)
HTML:
<div class="flip-container"> <div class="flipper"> <div class="front">here is content : AA</div> <div class="back">here is content : BB</div> </div> </div>
CSS:
.flip-container { margin: 30px; display: inline-block; border: 1px solid #aaa; -webkit-perspective: 500; -moz-perspective: 500; -ms-perspective: 500; perspective: 500; -ms-transform: perspective(500px); -moz-transform: perspective(500px); /*重要*/ transform-style: preserve-3d; /*重要*/ } .flipper { position: relative; width: 200px; height: 200px; transition: 0.6s; transform-style: preserve-3d; /*重要*/ } /* 觸發翻轉 */ .flip-container:hover .flipper{ transform: rotateY(180deg); } .front ,.back{ position: absolute; left: 0; top: 0; backface-visibility: hidden; /*重要*/ width: 100%; height: 100%; } .front { transform: rotateY(0deg); z-index: 2; background: red; } .back { transform: rotateY(-180deg); background: green; }
- 在最外層的容器元素上設置整個動畫區域的透視(perspective)屬性。
- 當外層容器元素遇到鼠標懸停事件時,內部存放卡片的容器旋轉180度。這里也是控制旋轉速度的地方。如果將旋轉值設置為-180deg,是反向旋轉。
- 表示卡片正面和背面的元素都要絕對定位,這樣它們才能在相同的位置相互遮擋。它們的背面可視性(backface-visibility)屬性設置為隱藏,這樣每個卡片的背面在翻轉時都是看不見的。
- 將卡片的正面設置為一個比背面要高的z-index值,這樣保證卡片的正面在最上面。
- 將背面卡片旋轉180度,這樣讓它扮演背面的角色。
照搬結束,其中CSS中注釋了重要的需要特別注意。
perspective 屬性定義 3D 元素距視圖的距離,以像素計。直觀現象就是內層的元素在翻轉時會溢出外層邊框,如果不寫,或者屬性值為0,則只在外層邊框內變化。
且屬性值需要特別注意和需要翻轉的元素的寬高相適應,太少溢出很誇張,太多了和設為0的區別不大。區別效果如下圖所示
transform-style: preserve-3d; transform-style 屬性規定如何在 3D 空間中呈現被嵌套的元素(照抄自w3cschool)。
flip-container 和 flipper 都需要設置,flip-container不設置會導致溢出的3D效果缺少,flipper 不設置則容器翻轉后,我們看到的還是front的背面,backface-visibility: hidden不能體現效果。
比較坑的是transform-style即使在IE11中都是不支持的。
所以還有一個兼容IE的方案,就是不翻轉容器,而是同時翻轉front和back,幸好IE還是支持backface-visibility: hidden的,所以翻轉效果和上一個方案一致。
HTML如下:
<div class="flip-container"> <div class="front">here is content : AA</div> <div class="back">here is content : BB</div> </div>
由於直接翻轉front和back,flipper就顯得多余了,去掉了flipper。
CSS代碼如下(經過多方試驗,盡量支持各個瀏覽器,並降級處理了不支持CSS3翻轉的瀏覽器,保留了切換效果)
.flip-container { -webkit-perspective: 500; -moz-perspective: 500; -ms-perspective: 500; perspective: 500; -ms-transform: perspective(500px); -moz-transform: perspective(500px); -moz-transform-style: preserve-3d; -ms-transform-style: preserve-3d; margin: 30px; display: inline-block; border: 1px solid #aaa; position: relative; } /*由於內層絕對定位導致高度缺少,這里顯式設置了寬高*/ .flip-container, .front, .back { width: 200px; height: 200px; } .flip-container:hover .front { -webkit-transform: rotateY(180deg); -moz-transform: rotateY(180deg); -o-transform: rotateY(180deg); -ms-transform: rotateY(180deg); transform: rotateY(180deg); } .flip-container:hover .back { -webkit-transform: rotateY(0deg); -moz-transform: rotateY(0deg); -o-transform: rotateY(0deg); -ms-transform: rotateY(0deg); transform: rotateY(0deg); z-index: 3; /* 降級處理不支持CSS3的瀏覽器,只是簡單的將back上升蓋住front */ } .front, .back { -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden; -webkit-transition: 0.6s; -moz-transition: 0.6s; -o-transition: 0.6s; -ms-transition: 0.6s; transition: 0.6s; position: absolute; top: 0px; left: 0px; } .front { background: red; z-index: 2; } .back { background: green; -webkit-transform: rotateY(-180deg); -moz-transform: rotateY(-180deg); -o-transform: rotateY(-180deg); -ms-transform: rotateY(-180deg); transform: rotateY(-180deg); }
以上也許有許多不必要的兼容代碼,水平有限了,歡迎交流更簡練的寫法。
還有一個小TIPS,在其他情況使用hover觸發元素翻轉時應如下使用,固定寬高的父元素觸發,子元素翻轉
.outer { width: 200px; height: 200px; } .inner { transition: 0.6s; } .outer:hover .inner{ transform: rotateY(180deg); }
如下直接對元素hover觸發翻轉會有很大的使用問題,因為元素翻轉過程中,元素區域變小,光標就脫離元素了,於是元素還原,又觸發hover變小,造成不順暢
.inner { width: 200px; height: 200px;
transition: 0.6s; } .inner:hover{ transform: rotateY(180deg); }
關於CSS3 transform的更詳細介紹,參見大神文章好吧,CSS3 3D transform變換,不過如此!