我们现在拥有开始制作 3D 对象的所有工具。让我们从基础开始,翻转卡片。
这是我们的HTML标签结构:
<div class="scene"> <div class="card"> <div class="card__face card__face--front">front</div> <div class="card__face card__face--back">back</div> </div> </div>
.scene
做为三维空间的容器,.card
充当3D对象。两个单独的.card__face
元素用于卡片的正面和背面。我建议对任何 3D 变换使用相同的套路:场景(.scene
)、对象(.card
)和面(card__face
),设置起来会比较方便。
首先,给.scene 设置 perspective
。
.scene { width: 200px; height: 260px; perspective: 600px; }
现在该.card
元素可以在其父元素的 3D 空间中进行转换。添加width: 100%; ,height: 100%;
因此卡片transform-origin将出现在容器的中心。更多关于transform-origin的使用会在以后介绍。position: relative
用于给绝对定位的面(card__face
)设置参考点。
让我们添加一个 CSS3 过渡(transition),以便让3D转换能看到效果。
.card { width: 100%; height: 100%; position: relative; transition: transform 1s; transform-style: preserve-3d; }
元素的 perspective
仅应用于直接子元素,在本例中为.card
。为了让多层嵌套的子元素继承父级的视角,并存在于同一个 3D 空间中,父级可以用transform-style: preserve-3d
传递它的视角。如果不设置transform-style
,卡片的表面将与它的父级一起展平,背面的旋转将无效。
要在 3D 空间中定位面,我们需要使用position: absolute
重置它们在 2D 中的位置。当用户在观察时为了隐藏背面,我们使用 backface-visibility: hidden
.
.card__face { position: absolute; height: 100%; width: 100%; backface-visibility: hidden; }
为了翻转.card__face--back
,我们添加了一个基本的 3D 变换 rotateY(180deg)
。
.card__face--front { background: red; } .card__face--back { background: blue; transform: rotateY( 180deg ); }
两个面设置好后,.card
翻转时需要相应的样式。
.card.is-flipped { transform: rotateY(180deg); }
现在我们有了一个可用的 3D 对象。要翻转卡片,我们可以切换class is-flipped
。当拥有.is-flipped
class 时,.card
将旋转 180 度,从而暴露.card__face--back
。
再看一下苹果的天气 App 3D过渡。你会注意到它与我们上面的演示效果不太一样。仔细观察苹果天气APP的右边缘(可在下方看简化的Demo效果),你会发现它在运动时始终保持和容器高度一致。它不是从水平中心旋转,而是在右边缘旋转。但过渡不仅仅是旋转,边缘还从右向左水平移动。我们可以修改上面的代码范例来演示这个效果。
旋转的枢轴点出现在卡片的右侧。默认情况下,元素的transform-origin
位于其水平和垂直中心(50% 50%
或center center
)。元素从它的transform-origin
变换的, 让我们将其更改为右侧:
.card { transform-origin: center right; }
该翻转现在需要使用 translateX
进行一些水平移动。我们将旋转设置为-180deg
使其向右翻转。
.card.is-flipped { transform: translateX(-100%) rotateY(-180deg); }
原文: https://3dtransforms.desandro.com/card-flip
翻译: 若愚@饥人谷