css過渡 取消過渡
Prompted by a question from a 2nd year student, I was inspired to explore the visual effect you can see above. Variations on this transition have long been a mainstay of JQuery carousels; I was interested in working out if it could be achieved in pure CSS, with the condition that the result should also be responsive: most JavaScript solutions are not.
在第二年級學生提出的一個問題的提示下,我受到啟發去探索上面可以看到的視覺效果。 長期以來,這種過渡的變體一直是JQuery輪播的主體。 我有興趣研究是否可以在純CSS中實作,條件是結果也應該響應 :大多數JavaScript解決方案都不能。
It’s certainly doable, albeit with a bit of markup: the solution requires as many copies of the image as we would like “shutters” at the bitmap’s maximum dimensions. In this case, I wanted 10 vertical “blinds” for images that would have a maximum width of 1000 pixels. This required 10 copies of each photograph, arranged inside a
<figure>
container. At the same time, I needed 10 copies of the alternate image on the reverse side. Each image set would have a different class:
盡管有一點标記,但它當然是可行的:該解決方案需要在位圖的最大尺寸上像我們希望的“快門”一樣多的圖像副本。 在這種情況下,我要為最大寬度為1000像素的圖像設定10個垂直“盲點”。 每張照片需要10份副本,并放置在
<figure>
容器中。 同時,我需要在背面列印10張備用圖檔。 每個圖像集将具有不同的類:
<figure id="blinds">
<img src="autumn-face.jpg" alt class="first">
<img src="autumn-face.jpg" alt class="first">
…
<img src="autumn-face.jpg" alt class="first">
…
<img src="julia.jpg" alt class="second">
<img src="julia.jpg" alt class="second">
…
<img src="julia.jpg" alt class="second">
</figure>
In reality, only two images will be loaded, with copies duplicated in the browser. All images are exactly the same size, in the same absolute position. The
<figure>
element will be 100% of the width of its container, with the correct height provided by using the same trick I use for responsive video:
實際上,将僅加載兩個圖像,并且副本在浏覽器中重複。 所有圖像在相同的絕對位置上均具有完全相同的尺寸。
<figure>
元素将是其容器寬度的100%,并使用與響應視訊相同的技巧提供正确的高度:
#blinds {
margin: 0;
position: relative;
padding-bottom: 56.5%;
perspective: 1800px;
transform-style: preserve-3d;
max-width: 1000px;
}
#blinds img {
top: 0; left: 0;
position: absolute;
transition: 1s;
}
Every copy of the second image is rotated 180 degrees and placed behind the others by using a slight
translate
value:
第二個圖像的每個副本都旋轉180度,并使用輕微的
translate
值放置在其他圖像的後面:
#blinds img.first {
transform: rotateY(0deg);
}
#blinds img.second {
transform: rotateY(-180deg) translateZ(1px);
}
To create the slices, I use
clip
, with
nth-child
as a selector. As you can see, both image’s
clip
left and right values increase by 100 after each iteration:
要建立切片,我使用
clip
,将
nth-child
作為選擇器。 如您所見,每次疊代後,圖像的
clip
左右值都增加了100:
#blinds img:nth-child(1),
#blinds img:nth-child(11) {
clip: rect(0px, 100px, 840px, 0px);
}
#blinds img:nth-child(2),
#blinds img:nth-child(12) {
clip: rect(0px, 200px, 840px, 100px);
}
#blinds img:nth-child(3),
#blinds img:nth-child(13) {
clip: rect(0px, 300px, 840px, 200px);
}
…
#blinds img:nth-child(10n) {
clip: rect(0px, 1000px, 840px, 900px);
}
Even after using
clip
, the image’s
transform-origin
– the point around which the image will be transformed – remains the center of the element. To counter that, we set the
transform-origin
for each slice so that it is at the halfway point. Think of the position of the central axes in a set of vertical blinds:
即使在使用
clip
,圖像的
transform-origin
(将在其周圍
transform-origin
圖像的點)仍然是元素的中心。 為了解決這個問題,我們為每個切片設定了
transform-origin
,以使其位于中間點。 考慮一下一組垂直百葉窗中軸的位置:

transform-origin
for clipped “venetian blind” images
transform-origin
邏輯位置
In CSS:
在CSS中:
#blinds img:nth-child(1),
#blinds img:nth-child(11) {
clip: rect(0px, 100px, 840px, 0px);
transform-origin: 50px 0px;
}
#blinds img:nth-child(2),
#blinds img:nth-child(12) {
clip: rect(0px, 200px, 840px, 100px);
transform-origin: 150px 0px;
}
#blinds img:nth-child(3),
#blinds img:nth-child(13) {
clip: rect(0px, 300px, 840px, 200px);
transform-origin: 250px 0px;
}
…
#blinds img:nth-child(10n) {
clip: rect(0px, 1000px, 840px, 900px);
transform-origin: 950px 0px;
}
Then we can rotate the image sets 180° on
:hover
, distinguished by their
class
:
然後我們可以将圖像集在
:hover
上旋轉180°,按其
class
區分:
#blinds:hover img.first {
transform: rotateY(180deg);
}
#blinds:hover img.second {
transform: rotateY(0deg) translateZ(1px);
}
As written, all the “blinds” will rotate at the same time. To create a “ripple” effect, we delay the transition of each slice:
如所寫,所有“百葉窗”将同時旋轉。 要建立“漣漪”效果,我們延遲每個切片的過渡:
#blinds img:nth-child(1),
#blinds img:nth-child(11) {
clip: rect(0px, 100px, 840px, 0px);
transform-origin: 50px 0px;
}
#blinds img:nth-child(2),
#blinds img:nth-child(12) {
clip: rect(0px, 200px, 840px, 100px);
transform-origin: 150px 0px;
transition-delay: 100ms;
}
#blinds img:nth-child(3),
#blinds img:nth-child(13) {
clip: rect(0px, 300px, 840px, 200px);
transform-origin: 250px 0px;
transition-delay: 200ms;
}
…
#blinds img:nth-child(10n) {
clip: rect(0px, 1000px, 840px, 900px);
transform-origin: 950px 0px;
transition-delay: 900ms;
}
One nice feature of using
clip
is that the result is automatically responsive: if the image narrows, the number of slices is reduced also. Try narrowing your browser window: if the viewport is 500px wide, the images are animated as five even slices.
使用
clip
一個不錯的功能是結果是自動響應的:如果圖像變窄,切片的數量也會減少。 嘗試縮小浏覽器視窗的範圍:如果視口為500px寬,則圖像将被動畫化為五個偶數切片。
替代方法 (Alternative Approaches)
The repetitive nature of the code cries out for a more efficient approach: either a pre-processor, or some JavaScript to automatically create the CSS. I’ll tackle both approaches in the very near future. For right now, this is a good start, although not yet perfect: due to browser rendering issues, it’s possible to see the occasional “kinked” or overlapping image slice during the transition.
代碼的重複性要求更有效的方法:預處理器或一些JavaScript自動建立CSS。 我将在不久的将來解決這兩種方法。 目前,這是一個不錯的開始,盡管還不是很完美:由于浏覽器渲染問題,過渡期間偶爾會出現“扭曲”或重疊的圖像切片。
翻譯自: https://thenewcode.com/776/3D-Venetian-Blind-Image-Transition-In-Pure-CSS
css過渡 取消過渡