Sunday, July 28, 2013

How to build Rubik's Cube using CSS3 and HTML


In this post I will try to show you how create 3D Rubkik's Cube using only CSS3 and HTML. On the picture below you can see effect of my work.

Screenshot of code result.


Theory

First you should know how look X Y Z axis in web. Look on this picture below. Z axis is not visible here because when we look on page it's like arrow for this axis comes from page to user. You can ask why I mention about this. Well it very helps me to imagine and write code for Rubik's Cube.

Time for practice.

Rubik's Cube is made from 27 smallest cubes. So first we need create our first cube. For this I make one dive with class cube and inside it I put 6 div's where each will be a cube's face. Using nth-child pseudo-classes and transform property I set each faces:
.cube div:nth-child(1){ /*front*/
  transform: translateZ(50px);
  background-color  : #fff;
}
      
.cube div:nth-child(2){ /*top*/
  transform: rotateX(90deg) translateZ(50px);
  background-color  : yellow;
}

.cube div:nth-child(3){/*bottom*/
  transform: rotateX(-90deg) translateZ(50px);
  background-color  : orange;
}

.cube div:nth-child(4){ /*left*/
  transform: rotateY(-90deg) translateZ(50px);
  background-color  : red;
}

.cube div:nth-child(5){ /*right*/
  transform: rotateY(90deg) translateZ(50px);
  background-color  : green;
}

.cube div:nth-child(6){ /*back*/
  transform:  translateZ(-50px);
  background-color  : blue;
}


To see cube in 3D we need add  preserve-3d as a parameter of transform-style property. To do this I add div with id main and set these style for this div. Then I put our .cube div inside it #main. Our html should look like this:
<div id="main">
  <div class="cube">
    <div></div><div></div><div></div><div></div><div></div><div></div>
  </div>
</div>


To see effect I also rotate our cube: transform: rotateX(335deg) rotateY(335deg) rotateZ(0deg); and add some css rules for better view of result:
body {
  background: #333;
}

#main{
  width: 300px;
  height: 300px;
  margin: 0 auto;
  margin-top: 150px;
  transform: rotateX(335deg) rotateY(335deg) rotateZ(0deg);
  transform-style: preserve-3d;
  transform-origin: 50% 50%;
}

.cube{
  opacity: 1;
  position: absolute;
  height: 100px;
  width: 100px;
}

.cube div{
  position: absolute;
  height: 60px;
  width: 60px;
  padding: 18px;
  border: 3px solid #000;
  border-radius: 5px;
}

Now just 26 cubes more to finish...


Not exactly. It will be easy if we group our cubes into groups.

Columns

I start by adding 2 more cubes and also adding to each class col as a column and to each individually classes col1, col2 and col3. Now time to set each of this item (col1 in default is set in start position):
div.col2{
  transform: translateX(100px);
}

div.col3{
  transform: translateX(200px);
}
and again preserve-3d to get 3D effect for col class:
div.col{
  transform-style: preserve-3d;
}

Rows

This 3 columns makes a row. So we wrap our html code into new div with class row. Then we copy this row with content twice time more and name each row also individually (row1, row2 and row3). Now let's write CSS code for each row:
div.row1{
  transform: translateZ(-150px);
}
div.row2{
  transform: translateZ(-50px);
}
div.row3{
  transform: translateZ(50px);
}
and don't forget to make it 3D!
div.col, div.row{
  transform-style: preserve-3d;
}

Levels

And next step is wrapping rows into levels. Like before for columns that now for rows we wrap them into new div with class lvl copy them twice time more and name each level also individually (lvl1, lvl2, lvl3). And again we add CSS rules for new classes:
div.lvl2{
  transform: translateY(100px);
}
div.lvl3{
  transform: translateY(200px);
}

Demo

And now you should see 3D Rubik's Cube. You can manipulate transform values for #main to see each side of your cube. I prepare some Javascript code to do this and also small CSS3 animation which spin cubes in all axis. Below you can see my demo and here (https://github.com/lukasz-zak/rubik-cube-in-css3).

See the Pen Rubik's Cube in CSS3 by Łukasz Żak (@lukasz-zak) on CodePen

No comments :

Post a Comment