HTML5 Rubik’s Cube

html5 css3 rubiks cube The Rubik’s Cube is a three-dimensional mechanical twisty puzzle, invented more than 40 yars ago in Hungary by Erno Rubik. It is estimated that more than 350.00 cubes were sold, making this simple yet so hard toy the most famous puzzle game of the World so I think there’s no need to describe it in more detail.
When it comes to modelling this cube on the web we can use a canvas or simply build the 54 little colored faces using rotated and transformed div elements in HTML5 and CSS3. There are for example online Rubik’s Cube solvers where the visitor inputs the colors of the scrambled cube and the program throws out the rotations needed to get the cube fixed. A HTML5 Rubik’s Cube can be used to demonstrate nice patterns, scrambles or we might want to build our own online Magic Cube to play with.

To start building our HTML5 Rubik’s Cube we have to define the “stickers of the cube” as 54 divs. We will have to position them one by one so we assign a custom field ID to each one of them and a color marker. According to the color scheme of the Rubik’s Cube, there are 6 different colors.

<div id="cubeFields">
    <div class="field1 color6"><span>1</span></div>
    <div class="field2 color6"><span>2</span></div>
    <div class="field3 color6"><span>3</span></div>
    <div class="field4 color6"><span>4</span></div>
    <div class="field5 color6"><span>5</span></div>
    <div class="field6 color6"><span>6</span></div>
    <div class="field7 color6"><span>7</span></div>
    <div class="field8 color6"><span>8</span></div>
    <div class="field9 color6"><span>9</span></div>
    <div class="field10 color3"><span>10</span></div>
    <div class="field11 color3"><span>11</span></div>
    <div class="field12 color3"><span>12</span></div>
    <div class="field13 color3"><span>13</span></div>
    <div class="field14 color3"><span>14</span></div>
    <div class="field15 color3"><span>15</span></div>
    <div class="field16 color3"><span>16</span></div>
    <div class="field17 color3"><span>17</span></div>
    <div class="field18 color3"><span>18</span></div>
    <div class="field19 color2"><span>19</span></div>
    <div class="field20 color2"><span>20</span></div>
    <div class="field21 color2"><span>21</span></div>
    <div class="field22 color2"><span>22</span></div>
    <div class="field23 color2"><span>23</span></div>
    <div class="field24 color2"><span>24</span></div>
    <div class="field25 color2"><span>25</span></div>
    <div class="field26 color2"><span>26</span></div>
    <div class="field27 color2"><span>27</span></div>
    <div class="field28 color5"><span>28</span></div>
    <div class="field29 color5"><span>29</span></div>
    <div class="field30 color5"><span>30</span></div>
    <div class="field31 color5"><span>31</span></div>
    <div class="field32 color5"><span>32</span></div>
    <div class="field33 color5"><span>33</span></div>
    <div class="field34 color5"><span>34</span></div>
    <div class="field35 color5"><span>35</span></div>
    <div class="field36 color5"><span>36</span></div>
    <div class="field37 color4"><span>37</span></div>
    <div class="field38 color4"><span>38</span></div>
    <div class="field39 color4"><span>39</span></div>
    <div class="field40 color4"><span>40</span></div>
    <div class="field41 color4"><span>41</span></div>
    <div class="field42 color4"><span>42</span></div>
    <div class="field43 color4"><span>43</span></div>
    <div class="field44 color4"><span>44</span></div>
    <div class="field45 color4"><span>45</span></div>
    <div class="field46 color1"><span>46</span></div>
    <div class="field47 color1"><span>47</span></div>
    <div class="field48 color1"><span>48</span></div>
    <div class="field49 color1"><span>49</span></div>
    <div class="field50 color1"><span>50</span></div>
    <div class="field51 color1"><span>51</span></div>
    <div class="field52 color1"><span>52</span></div>
    <div class="field53 color1"><span>53</span></div>
    <div class="field54 color1"><span>54</span></div>
</div>

To set up the stylesheet let’s define the colors of the stickers first:

.color1{    background-color: #FFFFFF;  }   
.color2{    background-color: #FF6907;  }   
.color3{    background-color: #00A75D;  }   
.color4{    background-color: #B60101;  }
.color5{    background-color: #213DFD;  }
.color6{    background-color: #FFD500;  }

Define the size of the fields, setting the black border.

#cubeFields > div {
    position: absolute;
    width: 26px;
    height: 26px;
    border: 2px solid #000;
}

I marked every field with a number which makes the items distinguishable, you can either delete these span tags from the HTML or just simply set them to display:none.

#cubeFields span {
    display: none;
}

It’s time to define the inidividual position of each little field and translate/rotate them accordingly. I have added the browser prefixes only for the first fiels to keep this article short.

.field1 {
    transform: rotateX(-90deg) translateX(0px) translateY(30px) translateZ(-60px);
    -moz-transform: rotateX(-90deg) translateX(0px) translateY(30px) translateZ(-60px);
    -webkit-transform: rotateX(-90deg) translateX(0px) translateY(30px) translateZ(-60px);
}
.field2 {   transform: rotateX(-90deg) translateX(30px) translateY(30px) translateZ(-60px); }
.field3 {   transform: rotateX(-90deg) translateX(60px) translateY(30px) translateZ(-60px); }
.field4 {   transform: rotateX(-90deg) translateX(0px) translateY(0px) translateZ(-60px); }
.field5 {   transform: rotatex(-90deg) translateX(30px) translateY(0px) translateZ(-60px); }
.field6 {   transform: rotateX(-90deg) translateX(60px) translateY(0px) translateZ(-60px); }
.field7 {   transform: rotateX(-90deg) translateX(0px) translateY(-30px) translateZ(-60px); }
.field8 {   transform: rotateX(-90deg) translateX(30px) translateY(-30px) translateZ(-60px); }
.field9 {   transform: rotateX(-90deg) translateX(60px) translateY(-30px) translateZ(-60px); }
.field10 {  transform: rotateY(-90deg) translateX(-30px) translateY(-45px) translateZ(15px); }
.field11 {  transform: rotateY(-90deg) translateX(0px) translateY(-45px) translateZ(15px); }
.field12 {  transform: rotateY(-90deg) translateX(30px) translateY(-45px) translateZ(15px); }
.field13 {  transform: rotateY(-90deg) translateX(-30px) translateY(-15px) translateZ(15px); }
.field14 {  transform: rotateY(-90deg) translateX(0px) translateY(-15px) translateZ(15px); }
.field15 {  transform: rotateY(-90deg) translateX(30px) translateY(-15px) translateZ(15px); }
.field16 {  transform: rotateY(-90deg) translateX(-30px) translateY(15px) translateZ(15px); }
.field17 {  transform: rotateY(-90deg) translateX(0px) translateY(15px) translateZ(15px); }
.field18 {  transform: rotateY(-90deg) translateX(+30px) translateY(15px) translateZ(15px); }
.field19 {  transform: translateX(0px) translateY(-45px) translateZ(45px); }
.field20 {  transform: translateX(30px) translateY(-45px) translateZ(45px); }
.field21 {  transform: translateX(60px) translateY(-45px) translateZ(45px); }
.field22 {  transform: translateX(0px) translateY(-15px) translateZ(45px); }
.field23 {  transform: translateX(30px) translateY(-15px) translateZ(45px); }
.field24 {  transform: translateX(60px) translateY(-15px) translateZ(45px); }
.field25 {  transform: translateX(0px) translateY(15px) translateZ(45px); }
.field26 {  transform: translateX(30px) translateY(15px) translateZ(45px);  
.field27 {  transform: translateX(60px) translateY(15px) translateZ(45px); }
.field28 {  transform: rotateY(-90deg) translateX(30px) translateY(-45px) translateZ(-75px); }
.field29 {  transform: rotateY(-90deg) translateX(0px) translateY(-45px) translateZ(-75px); }
.field30 {  transform: rotateY(-90deg) translateX(-30px) translateY(-45px) translateZ(-75px); }
.field31 {  transform: rotateY(-90deg) translateX(30px) translateY(-15px) translateZ(-75px); }
.field32 {  transform: rotateY(-90deg) translateX(0px) translateY(-15px) translateZ(-75px); }
.field33 {  transform: rotateY(-90deg) translateX(-30px) translateY(-15px) translateZ(-75px); }
.field34 {  transform: rotateY(-90deg) translateX(30px) translateY(15px) translateZ(-75px); }
.field35 {  transform: rotateY(-90deg) translateX(0px) translateY(15px) translateZ(-75px); }
.field36 {  transform: rotateY(-90deg) translateX(-30px) translateY(15px) translateZ(-75px); }
.field37 {  transform: translateX(60px) translateY(-45px) translateZ(-45px); }
.field38 {  transform: translateX(30px) translateY(-45px) translateZ(-45px); }
.field39 {  transform: translateX(0px) translateY(-45px) translateZ(-45px); }
.field40 {  transform: translateX(60px) translateY(-15px) translateZ(-45px); }
.field41 {  transform: translateX(30px) translateY(-15px) translateZ(-45px); }
.field42 {  transform: translateX(0px) translateY(-15px) translateZ(-45px); }
.field43 {  transform: translateX(60px) translateY(15px) translateZ(-45px); }
.field44 {  transform: translateX(30px) translateY(15px) translateZ(-45px); }
.field45 {  transform: translateX(0px) translateY(15px) translateZ(-45px); }
.field46 {  transform: rotateX(-90deg) translateX(0px) translateY(-30px) translateZ(30px); }
.field47 {  transform: rotateX(-90deg) translateX(30px) translateY(-30px) translateZ(30px); }
.field48 {  transform: rotateX(-90deg) translateX(60px) translateY(-30px) translateZ(30px); }
.field49 {  transform: rotateX(-90deg) translateX(0px) translateY(0px) translateZ(30px); }
.field50 {  transform: rotateX(-90deg) translateX(30px) translateY(0px) translateZ(30px); }
.field51 {  transform: rotateX(-90deg) translateX(60px) translateY(0px) translateZ(30px); }
.field52 {  transform: rotateX(-90deg) translateX(0px) translateY(30px) translateZ(30px); }
.field53 {  transform: rotateX(-90deg) translateX(30px) translateY(30px) translateZ(30px); }
.field54 {  transform: rotateX(-90deg) translateX(60px) translateY(30px) translateZ(30px); }

Rendering error in Mozzilla Firefox:
html5-rubiks-cube-mozzilla

The lates Internet Explorer 11 doesn’t support the CSS3 rotate transformation and this is how it renders the cube. Fortunately this has been fixed in Edge.
html5-rubiks-cube-render-ie

To get more inspiration check out this HTML5 Rubik’s Cube where you can generate little cube widgets to demonstrate rotations and algorithms.