Opening a Box with CSS

Exploring CSS Transforms and Animations

CSS is more powerful than ever. Before CSS3, if you wanted to build a box with flaps that opened like a box in real life would, you most likely needed Javascript or Flash to get the job done. Luckily for us, we can now get this done using just CSS with transforms and animations. Before we start looking at code, we should know a little about the css properties we’ll be using.

Perspective -

The perspective property allows you to move the focal point further or closer to the Z plane of the object. The smaller the value, the closer you are to the Z plane.

Perspective Origin -

This element, used along with perspective let’s you define the start point or vanishing point for the perspective property.

Transform -

The transform property lets you manipulate elements using different functions, like rotate, scale and skew. This article goes into detail on each.

Transform Style -

This property only takes one of two values, either flat or preserve-3d. We’ll be using preserve-3d to set up a 3d environment for our box.

Animation and @keyframe -

Animation is used to call animations on an element. You can also declare how long the animation should run and at which speed. These animations are defined with @keyframe.

Alright let’s make this box. First we need to setup a container for our box.

For readability reasons, I’m leaving vendor prefixes out but on actual projects you should be aware of the lack of support in legacy browsers and use vendor prefixes for best results.

<section class="container">  
</section>  

and also set our box’s perspective/perspective-origin.

.container {
  perspective: 500;
  perspective-origin: 50% -150px;
}

This sets us up to be looking down at the box from a slightly higher point.

The next step is to setup our box div, and all 6 sides of our box. The box needs the transform-style property of preserve-3d.

<section class="container">  
  <div class="box">
    <div class="side-1"></div>
    <div class="side side-2"></div>
    <div class="side side-3"></div>
    <div class="side side-4"></div>
    <div class="side side-5"></div>
    <div class="side side-6"></div>
  </div>
</section>  
.box {
  width: 100px;
  height: 100px;
  position: relative;
  margin: 180px auto;
  transform-style: preserve-3d;
}
.side {
  width: 100px;
  height: 100px;
  background: #c3834c;
  border: 1px solid #000;
  position: absolute;
}
.side-1 {
  width: 100px;
  height: 100px;
  position: absolute;
  transform: rotateX(90deg) translateZ(50px);
  transform-style: preserve-3d;
}
.side-2 {
  transform: translateZ(50px);
}
.side-3 {
  transform: rotateY(90deg) translateZ(50px);
}
.side-4 {
  transform: rotateX(-90deg) rotate(180deg) translateZ(50px);
}
.side-5 {
  transform: rotateY(180deg) translateZ(50px);
}
.side-6 {
  tranform: rotateY(-90deg) translateZ(50px);
}

Now we have a box. To be sure we set up our 3d perspective correctly, let’s add a spin animation and watch our box spin. Add this line to the .box class.

animation: spin 3s;  

and add the @keyframe spin animation at the end of our style sheet.

@keyframes spin {
  to {
    transform: rotateY(360deg);
  }
}

If you save that an refresh your browser, the box should spin a full turn.

Our 3d box is setup and now we need to add flaps to be able to open them. You probably noticed that we left the .side class off on side-1, so the box had a clear top. This was done so that we could see into the box and know that we had setup our 3d transforms correctly. Let’s add the flaps in by nesting two new divs in the div with the class of .side-1.

<div class="side-1">  
  <div class="side inner-side flap-1"></div>
  <div class="side inner-side flap-2"></div>
</div>  
.inner-side {
  transition: 1s all linear;
}
.flap-1, .flap-2 {
  width: 100px;
  height: 50px;
}
.flap-1 {
  top: 50px;
  transform-origin: 0px 50px;
}
.flap-2 {
  transform-origin: 100px 0px;
}

We setup both of our flaps with the appropriate transform origins so that they open opposite of each other, as a real box would. Now let’s open the flaps when we hover the box.

.box:hover {
  animation: spin 3s infinite linear;
}
.box:hover .flap-1 {
  transform: rotateX(-120deg);
}
.box:hover .flap-2 {
  transform: rotateX(120deg);
}

In addition to opening the flaps when we hover the box, we also set the spin animation on infinite so that it will keep spinning to show 3d perspective on the box, as long as we are hovering it.

You can download the code here if you need a reference.

Want to go further?

Try making some SVG vector graphics in Illustrator or whatever you use for vector illustration. Then write some css animations or transitions to animate specific nodes of the SVG. SVG files are code and you can actually write the animations in the SVG file itself. To animate a specific part of your graphic, give that node a class just like you would in HMTL. You could, for example make a face and then make the eyes roll while the rest of the face stays in place. The sky is the limit once you combine css animations/transitions with SVG graphics.

Send me cool stuff you do with css on Twitter, I’m @stides303.