> For the complete documentation index, see [llms.txt](https://css3d.mikey.wang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://css3d.mikey.wang/ying-yong/card_flip.md).

# 卡片翻转

## 卡片翻转

我们已经做好了操作一个3D物体的所有准备，让我们开始第一个基础应用，翻转一张卡片。

下面是我们需要的HTML代码片段：

```markup
<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>
```

![](https://830053722-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lf-8lnONg_WNTsQvlGE%2F-Lf-8pdAznbHZWNAmurg%2F-Lf-8suSMbBbEsh55fjl%2F%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202018-11-11%20%E4%B8%8B%E5%8D%885.56.57.png?generation=1558001980751281\&alt=media)

`.scene`这个元素构建了一个3D的空间容器，`.card`元素是具体的3D对象，两个独立的`.card__face`元素分别作为卡片的正反面。我很推荐用这样的结构模型来做3D变换：scene，object，和faces。下面我们用3D空间容器和两个分开的平面来建立一个易于理解、简化样式的范例。

我们准备了一些3D样式。首先，给3D空间的容器元素一个必须的`perspective`属性，同时添加一些大小、定位的样式。

```css
.scene {
  width: 200px;
  height: 260px;
  perspective: 600px;
}
```

现在`.card`元素可以在它父元素创建的3D空间里做transform变换了。我们添加`width: 100%;`和`height: 100%;`，这样卡片的`transform-origin`被设置在了容器的中心位置，更多关于`transform-origin`的内容我们稍后再谈。`position: relative`是用来绝对定位卡片的正反面的。

我们来添加一些CSS3的过渡效果，这样用户便可以看到变换的效果了。

```css
.card {
  width: 100%;
  height: 100%;
  position: relative;
  transition: transform 1s;
  transform-style: preserve-3d;
}
```

一个元素的`perspective`属性只能应用在它的直接子元素上，在这个例子中，就是`.card`元素。为了使后代所有的子元素都可以继承父元素的`perspective`，并且处在同一个3D空间下，父元素可以通过`transform-style: preserve-3d`来传递它的透视关系。如果没有3D的`transform-style`属性，那么卡片的立面将会被父元素压扁，同时背面旋转也将没有任何效果。

为了定位3D空间中的平面，我们需要在二维上用`position: absolute`重设他们的位置。为了隐藏远离观察者的背面，我们需要用到`backface-visibility: hidden`。

```css
.card__face {
  position: absolute;
  height: 100%;
  width: 100%;
  backface-visibility: hidden;
}
```

为了翻转`.card__face--back`，我们添加了一个基础的3D变换属性`rotateY(180deg)`。

```css
.card__face--front {
  background: red;
}

.card__face--back {
  background: blue;
  transform: rotateY( 180deg );
}
```

现在各个平面各就其位，当翻转卡片时，每个`.card`都需要有对应的样式。

```css
.card.is-flipped {
  transform: rotateY(180deg);
}
```

现在我们有了一个可以使用的3D对象。当翻转卡片，我们切换`is-flipped`类，当设置`.is-flipped`时，`.card`元素将会旋转180度，这样`.card__face--back`便被翻转到了正面。

{% embed url="<https://codepen.io/LaughingSir/pen/BGwdmy/>" %}

![](https://830053722-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lf-8lnONg_WNTsQvlGE%2F-Lf-8pdAznbHZWNAmurg%2F-Lf-8suhHq3lgjC4Jy5O%2Fcard-flip01.png?generation=1558001980798664\&alt=media)

## 平滑翻转

如果你仔细观察1.1中天气App的3D效果，那么你会注意到它的效果和我们前边例子所实现的有些不一样。 请注意它卡片右侧的边缘，你会发现它与容器平齐，边缘并不会超出容器，它是围绕右侧边缘进行转动的，而不是绕着水平中心进行转动。并且这个过渡效果其实并不是旋转，它的边缘是在水平方向上的从右向左的移动。我们可以在前边的卡片翻转例子中，仅仅修改几行CSS来实现这个过渡效果。

转动的中心点要在卡片的右侧。一个元素的`transform-origin`默认值是在水平和垂直方向的中心（`50% 50%` 或者 `center center`）。`transform-origin`是会影响到元素变换过程的，我们来把它设置为右侧：

```css
.card { transform-origin: center right; }
```

此时翻转需要用`translateX`设置水平运动，同时把旋转设置为`-180deg`，这样就可以向右翻转了。

```css
.card.is-flipped {
  transform: translateX(-100%) rotateY(-180deg);
}
```

{% embed url="<https://codepen.io/LaughingSir/pen/xQPPzO/>" %}

![](https://830053722-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lf-8lnONg_WNTsQvlGE%2F-Lf-8pdAznbHZWNAmurg%2F-Lf-8sulZ4Dpw751jG1q%2Fcard-flip02.png?generation=1558001980801996\&alt=media)
