How to create cube with only HTML and CSS?

According to your HTML, I get this JSFiddle. I just played with transform.

.mainDiv{
  position: relative;
  width: 206px;
  height: 190px;
  margin: 0px auto;
  margin-top:100px;
}
.square{
  width:100px;
  height:100px;
  background:#c52329;
  border:solid 2px #FFF;
  transform: skew(180deg,210deg);
  position: absolute;
  top: 43px;
}
.square2{
  width:100px;
  height:100px;
  background:#c52329;
  border:solid 2px #FFF;
  transform: skew(180deg,150deg);
  position: absolute;
  left:102px;
  top: 43px;
}
.square3{
  width:114px;
  height:100px;
  background:#c52329;
  border:solid 2px #FFF;
 

transform: rotate(150deg) translate(-40px, -16px) skew(30deg, 0deg);
  position: absolute;
  left: 0px;
  top: -32px;
}
<div class="mainDiv">
  <div class="square"></div>
  <div class="square2"></div>
  <div class="square3"></div>
</div>

Updated CSS

.square3{
  width:114px;
  height:100px;
  background:#c52329;
  border:solid 2px #FFF;
  transform: rotate(150deg) translate(-40px, -16px) skew(30deg, 0deg);
  position: absolute;
  left: 0px;
  top: -32px;
}

I changed transform CSS with this.


Extra: David Walsh has a cool animated version on an cube. Apart from the fact that it looks kinda cool, by fiddling with the settings you can learn quite a lot about it.


Basically, you want to do 2 transformations:

  1. rotate the rectangle
  2. squeeze it (skew it)

so basically, you need to do a transform: rotate(x) skew(y, y) and play a bit with size and placing.

here's a little demo I created, based on your own demo:

(I did remove the borders since they felt unneeded to me)

.mainDiv{
  position: relative;
  width: 206px;
  height: 190px;
  margin: 0px auto;
  margin-top:100px;
}
.square{
  width:100px;
  height:100px;
  background:#c52329;
  float:left;
  transform: skew(180deg,210deg);
  position: absolute;
  top: 43px;
}
.square2{
  width:100px;
  height:100px;
  background:#c52329;
  float:left;
  transform: skew(180deg,150deg);
  position: absolute;
  left:102px;
  top: 43px;
}
.square3{
  width:110px;
  height:110px;
  background:#c52329;
  float:left;
  transform: rotate(45deg) skew(-15deg, -15deg);
  position: absolute;
  left: 46px;
  top: -42px;
}
<div class="mainDiv">
  <div class="square"></div>
  <div class="square2"></div>
  <div class="square3"></div>
</div>

You can also achieve a cube with 3d transforms. This will give your cube a more realistic perspective. As if the cube was a real 3d shape like this:

3d cube with 3d transforms

In the following I used one div with 2 pseudo elements :

body {
  perspective: 900px;
  padding-bottom:50%;
}
div {
  position: relative;
  width: 20%;
  padding-bottom: 20%;
  margin: 0 auto;
  transform-style: preserve-3d;
  background: #C52329;
  transform: rotateX(60deg) rotatez(45deg);
}
div:before, div:after {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  transform-origin: -2% -2%;
  background: inherit;
}
div:before {
  top: 104%; left: 0;
  transform: rotateX(-90deg);
}
div:after {
  top: 0; left: 104%;
  transform: rotateY(90deg);
}
<div></div>

CSS 3d cube with 6 faces:

This technique allows you to make a "real cube" with 6 faces:

rotating 3d cube with 6 faces

body{
  perspective-origin:50% -100%;
  perspective: 900px;
  overflow:hidden;
}
h1{position:absolute;font-family:sans-serif;}
.cube {
  position:relative;
  padding-bottom:20%;
  transform-style: preserve-3d;
  transform-origin: 50% 100%;
  transform:rotateY(45deg) rotateX(0);
  transition:transform 3s;
}
.cubeFace {
  position: absolute;
  left:40%;top:0;
  width: 20%;height:100%;
  margin: 0 auto;
  transform-style: inherit;
  background: #C52329;
  box-shadow:inset 0 0 0 5px #fff; 
  transform-origin:50% 50%;
  transform: rotateX(90deg);
  backface-visibility:hidden;
}
.face2{
  transform-origin:50% 50%;
  transform: rotatez(90deg) translateX(100%) rotateY(90deg);
}
.cubeFace:before, .cubeFace:after {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  transform-origin:0 0;
  background: inherit;
  box-shadow:inherit;
  backface-visibility:inherit;
}
.cubeFace:before {
  top: 100%; left: 0;
  transform: rotateX(-90deg);
}
.cubeFace:after {
  top: 0; left: 100%;
  transform: rotateY(90deg);
}

body:hover .cube{
  transform:rotateY(405deg) rotateX(360deg);
}
<h1>Hover me:</h1>
<div class="cube">
  <div class="cubeFace"></div>
  <div class="cubeFace face2"></div>
</div>

Note that I didn't add the vendor prefixes in the examples. For more info about browser support and what vendor prefixes are needed according to your target audience, see canIuse for 3d transforms.


First let me point out that a skew angle should be between -90deg and 90deg, non-inclusive. All of your skews fall way outside this range.

Limiting myself to sensible skew numbers, it turned out to be quite simple:

.mainDiv{
  position: relative;
  width: 206px;
  height: 190px;
  margin: 0px auto;
  margin-top:100px;
}
.tile {
  width:100px;
  height:100px;
  background:#c52329;
  border:solid 2px #FFF;
  position: absolute;
}
.square{
  transform: skewY(30deg);
  top: 43px;
}
.square2{
  transform: skewY(-30deg);
  left:102px;
  top: 43px;
}
.square3{
  height: 58px;
  left: 50px;
  top: -18px;
  transform: skew(60deg, -30deg);
}
<div class="mainDiv">
  <div class="tile square"></div>
  <div class="tile square2"></div>
  <div class="tile square3"></div>
</div>

Job done. I've also tidied up the huge repetition of styles into a common class for you.