# 盒子

由于立方体只需要考虑一个尺寸，所以做起来比较容易。但是我们怎样处理一个不规则的长方体呢？也就是小孩子们讲的盒子。下面我们来做一个长300px，宽100px，高200px的长方体。

首先HTML保持不变。

```markup
<div class="scene">
  <div class="box">
    <div class="box__face box__face--front">front</div>
    <div class="box__face box__face--back">back</div>
    <div class="box__face box__face--right">right</div>
    <div class="box__face box__face--left">left</div>
    <div class="box__face box__face--top">top</div>
    <div class="box__face box__face--bottom">bottom</div>
  </div>
</div>
```

CSS与立方体的大体相同，只需要变更一些尺寸：`width: 300px`，`height: 200px`并且由于宽现在是100px，所以`.box`里需要调整一个`translateZ(-50px)`。

```css
.scene {
  width: 300px;
  height: 200px;
  perspective: 500px;
}

.box {
  width: 200px;
  height: 300px;
  position: relative;
  transform-style: preserve-3d;
  transform: translateZ(-50px);
}

.box__face--front,
.box__face--back {
  width: 300px;
  height: 200px;
}

.box__face--right,
.box__face--left {
  width: 100px;
  height: 200px;
}

.box__face--top,
.box__face--bottom {
  width: 300px;
  height: 100px;
}
```

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

在将`position: absolute`应用到每个平面后，他们都堆叠到了`.box`的左上角。

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

为了将各个平面在3D空间内从盒子的中心向外平移，我们需要将它们聚集在中心。为此我们添加`top`和`left`属性，为`.box__face--left`和`.box__face--right`添加`left: 100px`，为`.box__face--top` 和 `.box__face--bottom`添加 `top: 50px`。

```css
.box__face--right,
.box__face--left {
  width: 100px;
  height: 200px;
  left: 100px;
}

.box__face--top,
.box__face--bottom {
  width: 300px;
  height: 100px;
  top: 50px;
}
```

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

为了让长方体的各个平面在3D空间内正确定位，旋转的值与立方体一样保持不变，但是平移的值是不同的。由于立方体宽是`100px`，所以前、后面各向外平移`50px`。长是`300px`，所以左、右侧面分别向两边平移`150px`。高是`200px`，所以上、下面分别移动`100px`。

```css
.box__face--front  { transform: rotateY(  0deg) translateZ( 50px); }
.box__face--back   { transform: rotateY(180deg) translateZ( 50px); }

.box__face--right  { transform: rotateY( 90deg) translateZ(150px); }
.box__face--left   { transform: rotateY(-90deg) translateZ(150px); }

.box__face--top    { transform: rotateX( 90deg) translateZ(100px); }
.box__face--bottom { transform: rotateX(-90deg) translateZ(100px); }
```

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

就像正方体的例子，为了可以露出某一个面，需要在`#box`上添加与各平面变换值相反的样式，取每个相应平面的`translateZ`和`rotate`的相反数。

```css
.box.show-front  { transform: translateZ( -50px) rotateY(   0deg); }
.box.show-back   { transform: translateZ( -50px) rotateY(-180deg); }
.box.show-right  { transform: translateZ(-150px) rotateY( -90deg); }
.box.show-left   { transform: translateZ(-150px) rotateY(  90deg); }
.box.show-top    { transform: translateZ(-100px) rotateX( -90deg); }
.box.show-bottom { transform: translateZ(-100px) rotateX(  90deg); }
```

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