目录

CSS 3D 转换

卡片翻转

目录

我们现在拥有开始制作 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

在 CodePen 上编辑此演示

滑动翻转

再看一下苹果的天气 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);
}

在 CodePen 上编辑此演示

原文: https://3dtransforms.desandro.com/card-flip

翻译: 若愚@饥人谷