Create Opening Doors in CSS

’Tis the time of the year again when doors are opened, so I thought, “Well, would be nice, if we could open some doors with CSS only.” And lo and behold, modern CSS is equipped with everything necessary.

First we need a door frame and a door, that we can open:

<div class="doorframe" tabindex="0">
<div class="door"></div>

Then we sprinkle a little bit of CSS magic onto it, and the door will open:

.doorframe {
/* 1 */ display: flex;
/* 2 */ perspective: 1200px;
/* 3 */ transform-style: preserve-3d;

.door {
/* 1 */ flex-grow: 1;
/* 3 */ transform-style: preserve-3d;
/* 4 */ transform-origin: left center;
/* 4 */ transition: all 0.5s;
/* 5 */ backface-visibility: hidden;
/* 6 */ position: relative;

.door:before {
/* 6 */ content: '';
/* 6 */ position: absolute;
/* 6 */ top: 0;
/* 6 */ left: 0;
/* 6 */ right: 0;
/* 6 */ bottom: 0;
/* 7 */ backface-visibility: hidden;
/* 7 */ transform-style: preserve-3d;
/* 7 */ transform: rotateY(180deg);

.doorframe:focus .door,
.doorframe:hover .door
/* 8 */ transform: rotate3d(0, 1, 0, -130deg);

A little explanation won’t do any harm.

  1. First, we tell .doorframe, that it should lay out its child in a flexbox. This is a quick way to ensure, that the door will be spanned to cover the entire door frame.

  2. The browser should handle the door frame, as if it were 1200px away from the visitor. This is needed to calculate, how exactly the opening door will be rendered. A lower value will create an effect of a closer door leaf, if swung open, a higher value will make it seem as if it were farer away.

  3. The transform-style makes sure, that the children of this element are considered for 3D transformations. Otherwise they would be put flat on the same virtual plane as the element.

  4. The transform-origin and transition properties make the animation of the swinging door more natural. The first anchors transforms to the left edge of the door, the second makes it animate smoothly over half a second.

  5. backface-visibility determines, whether one can see an element’s back, if it is rotated in 3D. We will have it hidden in order to show the door’s back side and not simply its mirrored front side.

  6. The door’s back side is generated by the :before pseudo-element. We position it flush to the whole area of the door. However...

  7. ...with these properties we rotate it 180 degrees, so that it is, in 3D space, on the backside of our door leaf.

  8. Finally, the interaction: If the doorframe is hovered or focused, the door will swing open by 130 degrees.

And here is a fully functioning example. Hover over the door or click it to make it open.

The photo of the door is by abigail low, the photo of the garden is by Kilyan Sockalingum.