Have you ever come across a rather complex 3D creation while surfing the internet and your curiosity leads you to click on it to see if it has been rendered in 
Flash? These days, the features that come with modern browsers give you the power to create amazing projects without needing an external animating tool.
In fact, there are a handful of techniques: 
JavaScript, 
Canvas, which can be used to get this done. But in this article, I would like to introduce how to manage 
animations and 
transformations to the elements of a website using only CSS features.
CSS also for 3D?
Yes, even for 3D. In this post, we will create a 3D animated wooden-house model with CSS. 
Take a look at the 
DEMO here.
As a result, we will get a scene that is tilted at a 45-degree and viewed at a 2000-pixels viewpoint using the 
perspective
 property.
The objects positioned in this model are normal HTML elements. They have widths, heights, and are rectangular. This means that as you build a 3D object, you place each rectangle in place. The HTML elements are placed within the 3D scene using the 
transform
 property to move them in 3-dimensional spaces and also, the 
border
 and 
gradient
 properties are applied to the objects to create the illusion of depth.
CSS Transform
The 
transform
 property uses a value of 
translate3d
 with three dimensions. It is used to translate the element by a vector 
[tx, ty, tz], where 
tx is the translation along the x-axis, 
ty for the y-axis, and 
tz for the z-axis. Positive translation values will move the element along the positive direction of the axis, and negative values will move it in the opposite direction. Read more 
here.
Also, note that 
translate3d
 is one of the values that can be applied to the 
transform
 property. There are also  
rotate
 , 
skew
, 
scale
, 
matrics
 values and we will be using a combination of all or some in this tutorial. You should also note that the ordering of these values matter. When an element is applied more than one value, it starts its transformation from the last applied value to the first in that order. So, you can have similar values of transformation for two elements but they will be positioned differently if their orders are not the same.
In particular, this is the scene that will be created: The first is its static view while the other is its animated view.
A quick note
This project has been developed and tested primarily in Chrome and so, supports all properties used. Hence, I’ve removed the prefixed versions of rules in the following CSS. I would recommend either using compilers like LESS or SASS to manage these for you. Otherwise, be aware that most browser prefixes will need to be applied. Full versions of the CSS and SASS can be found on this 
pen, including the HTML.
Let’s get started!
We need to set a scene in which we can build our 3D creation. To do this, we’ll need to use an HTML element as the parent element and give it the needed properties that tell the browser to expect 3D content within it. Let’s start with some HTML:
<article class="scene">...</article>
In this case, the 
scene container is an 
article
 tag. You can use any other semantic tag and still achieve the same result. But I decided to use the 
article
 tag because in HTML5, 
article
 represents a standalone piece of content that could be reproduced elsewhere and still make sense.
The first property to apply is 
perspective. This property takes a value in pixels and represents the depth of the 3D scene. The 
perspective
 property defines how far the object is away from the viewer. So, a lower value will result in a more intensive 3D effect than a higher value.
For this view to feel like a wide scenery and with our model structure seated fully, we will set the perspective value quite high at 2,000 pixels. We could also establish the scene viewing angle by adjusting the 
perspective-origin
 property. This will determine whether we’re looking down at the object or from the side. The 
perspective-origin
 property takes two values, a horizontal and a vertical offset. And in our case, we want it centered with a 
50% 50%
 value and which is the default, so we don’t need to specify it.
article.scene {
   transform: translate(0, 50px);
   perspective: 2000px;
}
Let’s Build!
With the scene set, we can start putting together our 3D masterpiece. When beginning to build 3D objects with HTML and CSS, it’s worth taking a moment to understand how these properties work. Before we start building, we will create a 
house section inside our 
article tag, which will contain the different features of our house model as a set of 
div
 elements and form the main parts of our model.
<section class="house"> 
   <div class="deck"></div> 
   <div class="walls"></div> 
   <div class="roof"></div> 
   <div class="staircase"></div> 
   <div class="wedges"></div> 
   <div class="person"></div> 
</section>
The elements in the section above will take the form of the deck, the wall-frames and ceiling, the staircase attached at the top-left of the deck, the veranda and the animated persons.
With that in mind, we adjust our 
house class by rotating the entire scene by 45-degrees. We will have to set that now so as not to give us any issue with positioning our 
divs
 later. Next, we need to apply a 
transform
 property and 
transform-style
 to the 
house section and also give the 
divs
 some shared properties.
.house {
  margin: 0 auto;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateY(-45deg);
  width: 460px;
}
.house div {
  position: absolute;
  transform-style: preserve-3d;
}
Each 
div
 will be positioned absolutely in order to control and fix them easily, and the transform-style property set to 
preserve-3d
 to instruct the browser that 3D transforms are to be applied in relation to the 
perspective
 property we set earlier.
With this done, we can create our children elements inside our parent 
div
 and start positioning them. I should also note that I used the 
rem
 unit for my positioning. You can use other units you desire but I find 
rem
 quite handy. The values are not as high as pixels or percent and it takes fewer adjustments to reach your targeted positions.
Creating the deck
The key concept of CSS drawing is to creatively use 
border-radius
 to create curves and shapes. Then rotate and place them in the right position. And how do I know the exact degrees or pixels to put into my values? Well, I don’t! The trick is to use the browser dev tools to help you with a live adjustment. Then copy the styles into your source file when you get the right value. And the most important thing that would help you with a good judgment of deciding what values to use or values closest to the one you want is to know the directions of the dimensions. With that, you’ll have fewer adjustments to make.
Let’s continue then, shall we?
<div class="deck">
  <div class="covering"></div>
  <div class="left"></div>
  <div class="right"></div>
  <div class="back"></div>
  <div class="front"></div>
</div>
.deck *:not(.covering),
.deck *::before,
.deck *::after {
  border-right: 3px solid #78552c;
  border-top: 2px solid #b5854a;
}
.deck .left {
  width: 33.75rem;
  height: 2.06rem;
  background: #8a693d;
  transform: translate3D(7.4rem, 19.6rem, 38.3rem);
}
.deck .right {
  width: 61.3rem;
  height: 2.9rem;
  background: #4e3b23;
  transform: translate3D(-38.4rem, 29.1rem, -38.4rem);
}
.deck .back {
  width: 53rem;
  height: 2.9rem;
  background: #4e3b23;
  transform: translate3D(-66rem, 29.3rem, -12.8rem) rotateY(90deg);
}
.deck .front {
  width: 25.3rem;
  height: 2.2rem;
  background: #9c7645;
  transform: translate3d(32.1rem, 21.2rem, 9rem) rotateY(90deg);
}
The above rules assign a border-right and left to all sides of the deck except the covering to create a nice depth effect. It also describes a 
width
 of 33.75rem (540px), a 
height
 of 2.06rem and a dark-brown 
background color
 for the left side. The 
div
 is then positioned at 7.4rem along its x-axis, 19.6rem along its y-axis and 38.3rem at its z-axis.
Next, we create the other sides of the deck. Since it has four corners, I created two more sides — right and back sides and applied similar properties. You may have noticed I used a 
rotateY
 of 90-degrees on the 
.deck .back
 and 
.deck .front
 . We want them to be perpendicular to the 
.deck .right
 and 
.deck .left
 . The front side will be a little more complicated since we have to make a dent to fit in our staircase. I created a single 
div
 for this and also used pseudo-elements 
::before, ::after
 for carving out this space.
To complete the deck, we will be creating a covering for it. We will create a large L-shape from a rectangular shape. This is to create room for the stairs which we will be building later. I could have made this shape using the clip-path property but I wanted the shapes used for this project to be built solely with backgrounds and sizes. And again, not all browsers support the clip-path property yet. With this, I use the stacking linear-gradient background below to achieve the L-shape for the covering.
background: linear-gradient(#7a5d37, #7a5d37) calc(100% — 124px) no-repeat, linear-gradient(#7a5d37, #7a5d37) 0 188px/100% no-repeat;
We will also give it a 
translate3d
 value and 
rotate
 it negative 90-degrees along it x-axis to make it lap onto the four corners of the deck stands.
The result of all this should be a scene that looks like this:
Erecting the wall frames
The HTML structure for the walls will be a little intricate, but we can always manage it, right? We will be inserting a window div inside the walls 
div
 for all four sides of the wall. And inside the windows  
div
, we will be creating two 
rim class divs
 for the two windows, and each with a louvre and a lower bar div . And the end, we’ll be adding a door 
div
 to the front wall.
First, each of the walls will be given a value of 
12.5rem
 and we will start with the left wall. The left wall should be created first to determine where we want the length of the house to begin and end and also to determine how well to fit and align it to the adjoining walls. We will begin by giving it a 
translate3d
, 
width
 as usual.
To complete this wall, we will give it a brown color; a little darker than the front wall. They are the only two walls that will be exposed to the viewer and we want to make it appear that the light reflects more on the front wall than the left wall.
Next, we will create the right wall by giving it similar properties. For the 
transform
 property, we will give it a 
translate3d(-17.7rem, 6.25rem, -9.06rem)
 . The negative values for the x-axis and z-axis are because the wall will be further away from our view. We will also add a 
rotateY
 of 180-degrees since we want it to be perpendicularly aligned to the left wall.
To finish up this section, we will create the back and front walls in the same fashion but give them a 
rotateY
 of 90-degrees for the front wall and 3-degrees off 90 for the back wall. This will form perpendicular walls and hence the four-corner or cuboidal shape of the house.
<div class="front">
  <div class="windows">
    <div class="rim first-rim">
      <div class="louvres"></div>
      <div class="bar"></div>
    </div>
    <div class="rim second-front-rim">
      <div class="louvres"></div>
      <div class="bar"></div>
    </div>
  </div>
  <div class="doors">
    <div class="door-open"></div>
    <div class="door-close">
      <div class="door-knob"></div>
      <div class="door-bars"></div>
    </div>
  </div>
</div>
.right, .left, .back, .front {
    height: 12.5rem;
}
.walls .left {
    width: 22rem;
    background: #c3964f;
    transform: translate3d(18.4rem, 6.2rem, 38.3rem);
}
.walls .right {
    width: 22.2rem;
    background: #8c682f;
    transform: translate3d(18.1rem, 6.2rem, 9.4rem);
}
.walls .back {
    width: 29.2rem;
    background: #9f7636;
    transform: translate3d(2.2rem, 6.3rem, 22.7rem) rotateY(90deg);
}
.walls .front {
    width: 28.75rem;
    background: #c79d5a;
    transform: translate3d(26rem, 6.2rem, 23.9rem) rotateY(90deg);
}
At the end, we will have a nice-looking shape as the one below.
The windows and door
The windows will be created by giving the rim 
div
 a weight and height of 4.3rem and height: 3.75rem respectively and also move it 30px away from the top of the walls. Then, we add a border of 
9px solid #dac29a
 for both left and right sides of the rims 
div
 and a 
7px solid #dac29a
 to the top and bottom. The offset of 3px on both values is to make up for the width of one to the other since the 
perspective
 value we gave to its first parent 
div
 slightly distorted that.
Afterward, we will be adding an extra class-names to the rims 
div
. This is because both window rims will be stacked up together, so we need to create a distance between them by applying a 
left
 value. All first rims will take a 
left
 value of 
40px
, and while the second rims of the left and right walls take a 
215px
 value, the second rims of the front and back walls will take a left value of 
330px
. This is because the front and back walls are longer in width compared to the left and right walls.
Next, we create a 
::before
 and 
::after
 pseudo-class from the rim 
div
. These classes will be used to create the crossed dividers inside the window frames. We will give the 
::before
 class a left value of 
45%
 and the 
::after
 class a top value of 45%. Instead of using a border here, I will be using a gradient background color to simulate a fine inward distance. We will also create a louvre 
div
 which will be used to form the window glasses. We will give it a 
background
 , a 
border-top
 and an 
opacity
 of 0.7 to give it a glassy look.
.windows .rim {
  top: 30px;
  width: 4.3rem;
  height: 3.75rem;
  border-left: 9px solid #dac29a;
  border-right: 9px solid #dac29a;
  border-top: 7px solid #dac29a;
  border-bottom: 7px solid #dac29a;
}
.windows .rim::before {
  background: linear-gradient(to left, #dac29a, #bda886);
  left: 45%;
  width: 0.62rem;
  height: 3.75rem;
  content: '';
  position: absolute;
}
.windows .rim::after {
  background: linear-gradient(to left, #dac29a, #bda886);
  top: 45%;
  width: 4.3rem;
  height: 0.45rem;
  content: '';
  position: absolute;
}
.windows .first-rim {
  left: 40px;
}
.windows .second-left-rim,
.windows .second-right-rim {
  left: 215px;
}
.windows .second-front-rim,
.windows .second-back-rim {
  left: 330px;
}
.windows .louvres {
  background: linear-gradient(to left, #dac29a, #b5a181);
  border-top: 2px solid #7a5d37;
  width: 4.3rem;
  height: 3.75rem;
  z-index: -1;
  opacity: 0.7;
}
.windows .bar {
  background: linear-gradient(to left, #dac29a, #b5a181);
  border-top: 2px solid #7a5d37;
  width: 6rem;
  height: 0.5rem;
  bottom: -15px;
  right: -15px;
  border-radius: 20px;
}
.doors .door-open {
  width: 5.5rem;
  height: 7.5rem;
  bottom: 0%;
  left: 40%;
  border-right: 3px solid #a58152;
  background: linear-gradient(12deg, #7a5d37 40%, #a07c43 0 70%);
}
.doors .door-close {
  width: 5.5rem;
  height: 7.5rem;
  bottom: 0%;
  left: 40%;
  border-left: 8px solid #dac29a;
  border-right: 8px solid #dac29a;
  border-top: 8px solid #dac29a;
  background: #fff;
}
.doors .door-knob {
  width: 0.5rem;
  height: 0.5rem;
  background: linear-gradient(to top, #dac29a, #dac29a);
  border-radius: 50%;
  top: 50%;
  left: 5px;
  border-left: 2px solid #a28658;
}
.doors .door-bars {
  width: 7rem;
  height: 0.5rem;
  background: linear-gradient(to top, #dac29a, #dac29a);
  border-radius: 20px;
  top: -15px;
  left: -12px;
  border-bottom: 2px solid #7a5d37;
}
Styling the door requires two features. The first door-open 
div
 is to create what looks like an opening in the front wall, which will come in handy when we animate our 
person to move in through the door. We will give it a 
linear-gradient
 to simulate this; sharp contrast colors going from the floor color to the right wall color and tilted at a degree of 12 and also some borders that will make it look like its inset. Secondly, we will create the door by giving the door-close 
div
 a 
background-color
 of white and borders that will form the door-frames. We will give the door, a knob and top bar using 
background
, 
border-radius
 and sizes.
Roofing the house structure
<div class="roof">
  <div class="left"></div>
  <div class="right"></div>
  <div class="front"></div>
  <div class="back"></div>
</div>
<div class="porch">
  <div class="bottom"></div>
  <div class="left"></div>
  <div class="right"></div>
  <div class="front"></div>
  <div class="first_bar bar"></div>
  <div class="second_bar bar"></div>
</div>
We will start this section by creating the HTML structure. Creating the upper compartments may look pretty straight-forward but it seemed to me to be the toughest part of this project. This is because I had to make several tilting and positioning points to get the shape I needed. We will be starting this section by creating the HTML 
divs
 for the roof and porch structures.
The styling for the front side of the roof will be achieved by using borders to create a triangular shape. This could be done by using the clip-path property too but I’m opting for borders instead. First, we will give the 
border-left:220px solid transparent
, 
border-right:246px solid transparent
 and 
border-bottom:110px solid #e7b565
 . We will also give it a rotation of 90 degrees along its y-axis which is the same degree as the front wall. Next, we will give it a 
translate3d
 values. We will do the same to the backside and give it similar properties.
.roof .front {
    border-left: 220px solid transparent;
    border-right: 246px solid transparent;
    border-bottom: 110px solid #c79d5a;
    transform: translate3d(25.6rem, -0.6rem, 23.7rem) rotateY(90deg);
}
.roof .back {
    border-left: 203px solid transparent;
    border-right: 203px solid transparent;
    border-bottom: 98px solid #9f7636;
    transform: translate3d(15.85rem, -0.6rem, 31.7rem) rotateY(90deg);
}
.roof .left {
    width: 24.25rem;
    height: 8.4rem;
    background-image: repeating-linear-gradient(to left, #795f35, #a68349, 10%, #a68349, #795f35 10%);
    border-right: 5px solid #86693b;
    border-bottom: 3px solid #927340;
    transform: translate3d(29.5rem, -1.8rem, 42rem) rotateX(45deg) skewX(-35deg);
}
.roof .right {
    width: 41.25rem;
    height: 12.5rem;
    background-image: repeating-linear-gradient(to left, #8e734b, #65502d, 10%, #65502d, #8e734b 10%);
    border-right: 5px solid #b38f55;
    border-bottom: 3px solid #927340;
    transform: translate3d(-12.3rem, -3.1rem, -0.7rem) rotateX(131deg) skewX(-35deg);
}
The right and left roofs will also be created in the same fashion but with a twist. We will add a 
rotateX(45deg)
 to the left roof and since the scene we are building is to be viewed at 45-degrees, this effect works to our advantage in this case. Subsequently, a 
rotateX(45deg + 90deg)
 which is calculated as 
rotateX(135deg)
 will be given to the right roof. This is to create an opposite tilting of both roofs. 
Next, we also add a 
skewX
 value of negative 35-degrees to both roofs. This is also to make the bottom-end side of the roof planes stick out more than the top-end. The idea behind this is that looking at our view, we should be able to put up a better judgment on the appearance and placing of the structure. We will also be adding a nice repeating-linear-gradient to make them appear ridged-like.
background: repeating-linear-gradient(to left, #8e734b, #65502d, 10%, #7b561a, #655235 10%)
Next, we will be creating a porch that will be placed directly above the front door. The bottom-porch will be styled first to enable proper alignments of other sides of the porch. A 
width
 and 
height
 of 
2.6rem
 and 
11rem
 will be assigned to it, a 
translate3d
 and a 
rotateX(89deg)
 . We slightly offset the rotate value off 1 degree since we are viewing the scene from a higher viewpoint, an 89-degrees will completely tilt the bottom-side of the porch and still make it visible.
Subsequently, we will also create the left and right side of the porch similarly but completely tilting them and make them steeper. For the front side, we will be creating a triangular shape using borders just like we did for the front and back sides of the roof. We will also adjust the sides and positions until it laps perfectly unto the other sides of the porch.
To complete the porch, we will create two pillars that will hold the porch and stretch from the bottom of the porch to the flooring.
.porch *:not(.front) {
  background: linear-gradient(to top, #795f35, #b18c50);
  border-right: 3px solid #9a7944;
}
.porch .bottom {
  width: 2.6rem;
  height: 11rem;
  transform: translate3d(52rem, 0.4rem, 36rem) rotateX(90deg);
}
.porch .left {
    width: 3rem;
    height: 6rem;
    transform: translate3d(51.1rem, 1.6rem, 38rem) rotateX(63deg);
}
.porch .right {
    width: 3rem;
    height: 5.9rem;
    transform: translate3d(51.3rem, 1.6rem, 32.8rem) rotateX(-63deg);
}
.porch .front {
    border-left: 70px solid transparent;
    border-right: 70px solid transparent;
    border-bottom: 36px solid #866a3c;
    transform: translate3d(58rem, 2.7rem, 44.2rem) rotateY(90deg);
}
.porch [class*='bar'] {
    height: 155px;
    width: 10px;
    border-radius: 0 0 5px 3px;
    background: linear-gradient(to bottom, #795f35, #b18c50);
    border-right: 3px solid #9a7944;
}
.porch .first_bar {
    transform: translate3d(52rem, 6rem, 37rem);
}
.porch .second_bar {
    transform: translate3d(51.8rem, 6rem, 31.5rem);
}
Walking up the staircase
<div class="staircase">
  <div class="vertical-step"></div>
  <div class="horizontal-step"></div>
  <div class="back-cover vertical"></div>
  <div class="bottom-cover horizontal"></div>
  <div class="side-cover"></div>
</div>
Building the stairs was not as difficult as I thought it would. What I had to do was to create div class — 
horizontal-steps
, 
vertical-steps
 , make pseudo-elements from them to make-up the three numbers of stairs. Then, I made a back, bottom and side coverings for them too.
For the pseudo-elements, I did not have to use 
transform
 properties for them, thankfully. This was because I did not need them to be transformed by their z-axes. All I needed to do was to use the positional properties — 
top
 , 
bottom
 , 
left
 and 
right
 to align them properly and since we already have all divs at absolute positioning, it was quite easy to accomplish.
First, we will start with the vertical-step 
div
 by giving it 
width
, 
height
 and 
transform
 properties. With the 
transform
 properties set, we will not need to set the positions of its pseudo-elements because they will automatically inherit them. 
All we have to do is to use 
top
 and 
left
 properties to push them to the positions we want them to be. A similar procedure will be followed for the horizontal-steps as well.
Below are the CSS rules:
.staircase [class*='vertical'],
.staircase [class*='vertical']::before,
.staircase [class*='vertical']::after {
  background-color: #7a5d37;
  border-right: 3px solid #78552c;
  border-top: 2px solid #b5854a;
}
.staircase .vertical-step {
  width: 5.62rem;
  height: 0.93rem;
  transform: translate3D(46.8rem, 18.3rem, 33.3rem) rotateY(-4deg);
}
.staircase .vertical-step::before {
  width: 6.2rem;
  height: 0.93rem;
  content: '';
  position: absolute;
  top: 24px;
  left: -40px;
}
.staircase .vertical-step::after {
  width: 6.2rem;
  height: 0.93rem;
  content: '';
  position: absolute;
  top: 48px;
  left: -65px;
}
.staircase [class*='horizontal'],
.staircase [class*='horizontal']::before,
.staircase [class*='horizontal']::after {
  background-color: #8a683d;
  border-right: 4px solid #78552c;
}
.staircase .horizontal-step {
  width: 5rem;
  height: 1.3rem;
  width: 80px;
  height: 21px;
  transform: translate3D(47.8rem, 17.5rem, 33.3rem) rotateX(90deg) rotateY(2deg);
}
.staircase .horizontal-step::before {
  width: 5rem;
  height: 1.3rem;
  content: '';
  position: absolute;
  top: 63px;
  left: 35px;
}
.staircase .horizontal-step::after {
  width: 5rem;
  height: 1.3rem;
  content: '';
  position: absolute;
  top: 116px;
  left: 63px;
}
.staircase .vertical-back {
  width: 6.25rem;
  height: 3.13rem;
  content: '';
  position: absolute;
  transform: translate3D(40rem, 20.6rem, 25rem) rotateY(-5deg);
}
.staircase .horizontal-back {
  width: 6.25rem;
  height: 3.55rem;
  content: '';
  position: absolute;
  transform: translate3D(39.2rem, 22.2rem, 27rem) rotateX(82deg) rotateY(1deg) skewX(-25deg);
}
.staircase .side {
  width: 1.25rem;
  height: 2.56rem;
  background: #674e2e;
  transform: translate3D(56.5rem, 16.68rem, 38rem) rotateY(90deg);
}
.staircase .side::before {
  width: 1.63rem;
  height: 1.71rem;
  background: #674e2e;
  content: '';
  position: absolute;
  transform: translate3D(-1.6rem, 0.8rem, 0rem);
}
.staircase .side::after {
  width: 1.31rem;
  height: 0.85rem;
  background: #674e2e;
  content: '';
  position: absolute;
  transform: translate3D(-2.9rem, 1.6rem, 0rem);
}
Subsequently, we create the bottom and back coverings by copying the properties for the horizontal and vertical steps, enlarge their widths and heights and place them accordingly. And for the side covering, I used a 
clip-path
 when I created it at first but I had wanted clip-path to be out of the scope of this tutorial, I had to recoup another method to achieve that shape. 
So, I created a 
div
, made pseudo-elements from it again, gave them appropriate shapes and aligned them to the three sides of the stairs each.
Framing the veranda
The HTML structure for the veranda will be pretty lengthy but needful because we will be placing bars and adjoining planks at all sides of the deck. 
<div class="veranda">
  <div class="wedges">
    <div class="wedge1 border-left"></div>
    <div class="wedge2 border-left"></div>
    <div class="wedge3 border-left"></div>
    <div class="wedge4 border-right"></div>
    <div class="wedge5 border-right"></div>
    <div class="wedge6 border-right"></div>
    <div class="wedge7 border-right"></div>
    <div class="wedge8 border-left"></div>
    <div class="wedge9 border-left"></div>
  </div>
  <div class="planks">
    <div class="plank1 border-right"></div>
    <div class="plank2 border-right"></div>
    <div class="plank3 border-left"></div>
    <div class="plank4 border-left"></div>
    <div class="plank5 border-left"></div>
    <div class="plank6 border-right"></div>
    <div class="plank7 border-left"></div>
    <div class="plank8 border-left"></div>
  </div>
</div>
Erecting the veranda was my favorite part of this project. The positionings were quite straight-forward. The wedges lie at every corner of the deck, so once I got a wedge’s position rightly, I can only adjust an axis or two to get the opposite wedge’s position. This also applies to the planks which will be used to join the wedges together.
We will start with the wedges, and first, we will be creating nine wedges which are the total numbers to be fitted at every corner including the edges of the staircase as well. We will assign a general styling of 6px 
border-radius
 to the top-left and right and a border-top of 
1px solid #b5854a
.  And after then, we will add extra class names to the wedges and planks — some will take a border-left position while others will take a border-right. 
The reason for this is the following. We want every wedge attached to the stairs to have a rotation of 90-degrees while the others remain at 0-degree. The stair wedges will be used to build the stair-rails, and so they will need to be rotated to perfectly form this shape and then only 
border-left
 properties will be needed while we give a 
border-right
 class to the others.
A similar procedure will be done for the planks 
divs
. We will give them a general styling of 
border-top
 ;   a 
border-right
 to the planks directly facing the view and a border-left to the planks facing a different view other than the front. At the end of this, we will be left with nicely drawn wooden bars and planks attaching them and we will do the magic by using the borders properties.
Viewing the images below will give a better visualization. 
After giving them general styling, we can then begin to work on the positioning. Once we place a wedge at the corner, we can use good judgment to decide how far the opposite one can be. We will perform similar actions to the plank 
divs
. 
And just like how we created the deck, we will give the front and back planks a 
rotateY
 of 90-degrees, so as to be right-angled with the side planks. We will also give a 
rotateY(90deg)
 to the planks that form the stair-rails and as well as a
 rotateZ
 values to make them slanted.
.veranda [class*='wedge'] {
  border-top-left-radius: 6px;
  border-top-right-radius: 6px;
  border-top: 1px solid #b5854a;
}
.veranda .wedges [class*='border-right'] {
  border-right: 3px solid #8a683d;
}
.veranda .wedges [class*='border-left'] {
  border-left: 3px solid #8a683d;
}
.veranda .wedge1 {
  width: 0.6rem;
  height: 2rem;
  background: linear-gradient(to bottom, #7a5d37, #523e25);
transform: translate3D(57.8rem, 14rem, 46.3rem) rotateY(90deg);
}
.veranda .wedge2 {
  width: 0.7rem;
  height: 2.3rem;
  background: linear-gradient(to bottom, #7a5d37, #523e25);
  transform: translate3D(54rem, 13.3rem, 38rem) rotateY(90deg);
}
.veranda .wedge3 {
  width: 0.8rem;
  height: 2.6rem;
  background: linear-gradient(to bottom, #8a683d, #b78549);
  transform: translate3d(45.8rem, 15rem, 32rem) rotateY(90deg);
}
.veranda .wedge4 {
  width: 1rem;
  height: 2.8rem;
  background: linear-gradient(to bottom, #8a683d, #b78549);
  transform: translate3D(40rem, 16.5rem, 38.5rem);
}
.veranda .wedge5 {
  width: 1.3rem;
  height: 2.8rem;
  background: linear-gradient(to bottom, #8a683d, #b78549);
  transform: translate3D(10rem, 16.5rem, 38.5rem);
}
.veranda .wedge6 {
  width: 1rem;
  height: 2.8rem;
  background: linear-gradient(to bottom, #7a5d37, #523e25);
  transform: translate3D(10rem, 16.5rem, 5.5rem);
}
.veranda .wedge7 {
  width: 1rem;
  height: 3rem;
  background: linear-gradient(to bottom, #7a5d37, #523e25);
  transform: translate3D(48rem, 16.3rem, 5.5rem);
}
.veranda .wedge8 {
  width: 0.7rem;
  height: 2.3rem;
  background: linear-gradient(to bottom, #8a683d, #b78549);
  transform: translate3D(58.5rem, 13.3rem, 38rem) rotateY(90deg);
}
.veranda .wedge9 {
  width: 0.6rem;
  height: 1.7rem;
  background: linear-gradient(to bottom, #8a683d, #b78549);
  transform: translate3D(61.8rem, 14.4rem, 46.5rem) rotateY(90deg);
}
.veranda .planks [class*='border-right'] {
  border-right: 2px solid #78552c;
  border-top: 2px solid #b5854a;
}
.veranda .planks [class*='border-left'] {
  border-left: 3px solid #78552c;
  border-top: 2px solid #b5854a;
}
.veranda .plank1 {
  width: 4.7rem;
  height: 0.7rem;
  background-color: #795b36;
  transform: translate3D(55rem, 13.6rem, 43.7rem) rotateY(90deg) rotateZ(-19deg);
}
.veranda .plank2 {
  width: 1.7rem;
  height: 0.7rem;
  background-color: #806139;
  transform: translate3D(53.5rem, 13.5rem, 39.2rem) rotateZ(-3deg);
}
.veranda .plank3 {
  width: 8.8rem;
  height: 0.7rem;
  background-color: #8a683d;
  transform: translate3D(52rem, 12.7rem, 46.7rem) rotateY(90deg);
}
.veranda .plank4 {
  width: 30rem;
  height: 0.9rem;
  background-color: #8a683d;
  transform: translate3D(12.7rem, 16.5rem, 40rem);
}
.veranda .plank5 {
  width: 34rem;
  height: 1rem;
  background-color: #46341f;
  transform: translate3D(-11rem, 17.7rem, 18.7rem) rotateY(90deg);
}
.veranda .plank6 {
  width: 38rem;
  height: 0.9rem;
  background-color: #46341f;
  transform: translate3D(10rem, 17rem, 5rem);
}
.veranda .plank7 {
  width: 17rem;
  height: 0.8rem;
  background-color: #8a683d;
  transform: translate3D(52rem, 13.2rem, 31.7rem) rotateY(90deg);
}
.veranda .plank8 {
  width: 4.5rem;
  height: 0.7rem;
  background-color: #8a683d;
  transform: translate3D(63rem, 12.5rem, 47.7rem) rotateY(90deg) rotateZ(-19deg);
}
Building our characters
With the structure in place, we need some persons to move in and out of the house to show it is habitable. In the initial draft of this project, creating the characters was not in the picture but afterward, when the idea popped up, I thought it was a good one. Creating the characters and their animations gave the house scene a livelier look. 
To build the characters, we need both persons to walk into the house with their starting point at the foot of the stairs. The first person will be going in through the door and this is where the door-open 
div
 we created earlier comes in handy. The second person will be moved to the end of the front-side of the house and both persons will return to their starting points and move past that point a little further.
Both character shapes are made up of 2 main parts, the heads and bodies. The legs are added using pseudo-elements on the body. So, both characters take one styling.
<div class="person">
  <div class="person-one">
    <figure class="head"></figure>
    <figure class="body"></figure>
  </div>
  <div class="person-two">
    <figure class="head"></figure>
    <figure class="body"></figure>
  </div>
</div>
Each of the parts is absolutely positioned and 
border-radius
 is used to create the round shapes. The leg pseudo-elements are described at once then each positioned in separate rules. The CSS rules are as follows:
.person .person-one figure,
.person .person-two figure {
  background-color: black;
  display: block;
  position: absolute;
}
.person .person-one .head,
.person .person-two .head {
  border-radius: 22px;
  width: 20px;
  height: 20px;
  left: 3px;
  top: 0;
}
.person .person-one .body,
.person .person-two .body {
  border-radius: 30px 30px 0 0;
  height: 30px;
  top: 21px;
  width: 26px;
}
.person .person-one .body:before,
.person .person-one .body:after,
.person .person-two .body:before,
.person .person-two .body:after {
  content: "";
  position: absolute;
  background-color: black;
  width: 9px;
  height: 15px;
  top: 30px;
}
.person .person-one .body:before,
.person .person-two .body:before {
  left: 3px;
}
.person .person-one .body:after,
.person .person-two .body:after {
  left: 14px;
}
With the character shape of person-one and person-two specified, we will position them at the starting position. The person-one at the foot of the staircase, and the person-two a little further away from person-one. And we will also want to make person-two appear just right after person-one is being animated or start climbing the stairs. To set this up, we will give a scale of 0 to person-two and delay its animation for 5.5 seconds.
.person .person-one {
  transform: translate3d(935px, 179px, 780px) rotateY(0deg);
  animation: move-person-one 20s 3s infinite;
}
.person .person-two {
  transform: translate3d(935px, 179px, 790px) rotateY(0deg) scale(0);
  animation: move-person-two 15s 5.5s infinite;
}
Keyframe animation
With the characters in place, the scene is ready for some animation.
If you 
view the demo you’ll see a few animations taking place. Rather than go through all the animations that set up the scene, I’ll focus on the animation of the character walking in and out of the house and also on the opening and closing of the door.
Timing and animating the HTML elements is achieved by using 
keyframes and then attaching the set of keyframes to an element using the 
animation property.
The first thing is to animate the first character, to have it walk up the stairs and into the front door, walk into the house and out and approach the stairs again. Here’s a set of keyframes that achieves this:
@keyframes move-person-one {
  0%, 10%, 90% {
    transform: translate3d(935px, 179px, 780px) rotateY(0deg);
  }
  20%, 85% {
    transform: translate3d(870px, 169px, 610px) rotateY(0deg);
  }
  30%, 80% {
    transform: translate3d(870px, 175px, 610px) rotateY(86deg);
  }
  40%, 45%, 70% {
    transform: translate3d(635px, 215px, 415px) rotateY(86deg);
  }
  55%, 50% {
    transform: translate3d(620px, 215px, 405px) rotateY(86deg);
  }
  91% {
    transform: translate3d(945px, 179px, 810px) rotateY(0deg);
  }
  100% {
    transform: translate3d(945px, 179px, 990px) rotateY(0deg);
  }
}
Keyframes are a series of steps, described using percentages. The percentage relates to the animation time, so that if an animation was to last 10 seconds, 10% would be the 1-second mark. 90% would be the 9-second mark.
Next, we animate the door that opens each time the first character goes inside the house and closes when it leaves the house. The timing of when the first character approaches the front door and the time the door opens and vice-versa should be properly calculated. First, we will establish the same duration time of 20 seconds for both the first character and the door. 
Afterward, we delay the first-character for 3 seconds and the door for 8 seconds, so this corresponds to the interaction described above. Next, immediately the door animation starts, we will transform its z-axis to 20-degrees and rotate its y-axis at 20-degrees and move the degrees higher at 4 seconds into the animation. 
This animates the door by opening it wide enough for the character to pass through and close it at about the 9th second. I repeated the same animation after the 10th second till the end of it.
.doors .door-close {
  animation: door-open 20s 8s infinite;
}
@keyframes door-open {
  0% {
     transform: translate3d(0px, 0px, 20px) rotateY(20deg);
  }
  8%, 50% {
     transform: translate3d(0px, 0px, 53px) rotateY(53deg);
  }
  35%, 70%, 100% {
     transform: translate3d(0px, 0px, 0px) rotateY(0deg);
  }
}
Having done that, let’s set up the corresponding 
animation
 keyframes for the second character. It will start its movement just like first-character, climbs the stairs and move to to the far end of the house’s front view and make its return.
@keyframes move-person-two {
  0%, 10%, 80% {
    transform: translate3d(935px, 179px, 790px) rotateY(0deg) scale(1);
  }
  20%, 75% {
    transform: translate3d(870px, 169px, 610px) rotateY(0deg);
  }
  30%, 70% {
    transform: translate3d(860px, 169px, 380px) rotateY(0deg);
  }
  35%, 65% {
    transform: translate3d(860px, 169px, 380px) rotateY(89deg);
  }
  40%, 60% {
    transform: translate3d(795px, 169px, 380px) rotateY(89deg);
    opacity: 1;
  }
  41%, 50% {
    opacity: 0;
  }
  81% {
    transform: translate3d(965px, 179px, 820px) rotateY(0deg);
    opacity: 1;
  }
  82% {
    transform: translate3d(995px, 189px, 855px) rotateY(89deg);
  }
  100% {
    transform: translate3d(1200px, 179px, 860px) rotateY(89deg);
  }
}
In this way, the two animations are being applied. The first character taking five more seconds later than the first to go through the animated cycle.
With the following animations and keyframes in place, the final result will be this:
Demo and source code