skip to Main Content

It is convenient for isometric grids to start at the top like this: iso grid

I have the following code to draw a "3d" isometric box:

body {
  display: flex;
  justify-content: center;
  align-items: center;
}

.plane {
  position: relative;
  width: 600px;
  height: 600px;
}

.container {
  position: absolute;
  width: 0;
  height: 0;
}

.left {
  background-color: #3e8fe1;
  height: var(--width);
  width: var(--height);
  transform-origin: 0 0;
  transform: rotate(90deg) skewX(-30deg) scaleY(0.864);
}

.right {
  position: relative;
  background-color: #2870bd;
  height: var(--height);
  width: var(--length);
  transform-origin: 0 0;
  transform: rotate(-30deg) skewX(-30deg) scaleY(0.864);
  bottom: var(--width);
}

.top {
  position: relative;
  background-color: #80bdfe;
  height: var(--length);
  width: var(--width);
  transform-origin: 0 0;
  transform: rotate(210deg) skew(-30deg) scaleY(0.864);
  bottom: calc(var(--width) + var(--height));
}
<body>
  <div class="plane">
    <div class="container" style="--width: 50px; --length: 200px; --height: 100px; left: 150px; top: 150px;">
      <div class="left"></div>
      <div class="right"></div>
      <div class="top"></div>
    </div>
  </div>
</body>

This works, but is there any way to make it so that increasing the --width, --length, and --height CSS variables would grow the box in the opposite directions that they are currently growing in?

That is, --width is currently growing front to back, but should grow back to front (such that increasing it makes it extrude towards you instead of away from you)

Similarly, increasing the --height should make it grow up, not down.

And lastly, increasing the --length should make it grow towards the "camera", and not away from it, as it currently does.

2

Answers


  1. I used translation in the transform line, which allowed me to create a counter-movement and realign the faces of the cube. I also noticed that you were using 3 separate divs in your example so I replaced 2 of them with the before and after pseudo-elements.

    body {
      background-color: #000;
      box-shadow: inset 0 0 1em #000;
    }
    
    #plane {
      width: 10em;
      height: 10em;
      margin: 0 auto;
      position: relative;
      top: 5em;
      transform: rotateX(45deg) rotateZ(45deg) translateZ(-1em);
      transform-style: preserve-3d;
    }
    
    #plane div {
      float: left;
      transform-origin: 97% 97%;
      position: relative;
    }
    
    .tall {
      background: #fff;
      transform: translateZ(var(--height));
      transform-style: preserve-3d;
      width: var(--width);
      height: var(--length);
    }
    
    .tall:before, .tall:after {
      content: "";
      background: #2e6b8f;
      position: absolute;
      transform-origin: 100% 100%;
    }
    
    .tall:before {
      transform: translateY(calc(var(--length) - 1em - var(--height) + 1em)) rotateX(90deg);
      box-shadow: inset 0em -.125em .25em rgba(0, 0, 0, .1);
      width: var(--width);
      height: var(--height);
    }
    
    .tall:after {
      transform: translateX(calc(var(--width) - 1em - var(--length) + 1em)) translateY(calc(var(--length) - 1em)) rotateX(90deg) rotateY(90deg) translateX(calc(var(--height) * -1 + 1em));
      box-shadow: inset -.125em 0em .25em rgba(0, 0, 0, .1);
      width: var(--length);
      height: var(--height);
    }
    <div id="plane">
      <div class="tall" style="--width: 1em; --length: 1em; --height: 5em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 4em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 3em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 2em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
      <div class="tall" style="--width: 1em; --length: 1em; --height: 1em"></div>
    </div>
    Login or Signup to reply.
  2. I think you can simply change the value of the rotate to value - 180 and add some tweak to the translate transformation, and you will have it grow in the other direction accordingly:

    const container = document.getElementById('container')
    const width = document.getElementById('width')
    const length = document.getElementById('length')
    const height = document.getElementById('height')
    
    width.addEventListener("input", (event) => {
      container.style.setProperty("--width", `${event.target.value}px`)
    })
    
    length.addEventListener("input", (event) => {
      container.style.setProperty("--length", `${event.target.value}px`)
    })
    
    height.addEventListener("input", (event) => {
      container.style.setProperty("--height", `${event.target.value}px`)
    })
    body {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .plane {
      position: relative;
      width: 600px;
      height: 600px;
    }
    
    .container {
      position: absolute;
      width: 0;
      height: 0;
    }
    
    .left {
      background-color: #3e8fe1;
      height: var(--width);
      width: var(--height);
      transform-origin: 0 0;
      transform: translate(calc(var(--length) * -0.864), calc(var(--length) / 2)) rotate(270deg) skewX(-30deg) scaleY(0.864);
      position: relative;
    }
    
    .right {
      position: relative;
      background-color: #2870bd;
      height: var(--height);
      width: var(--length);
      transform-origin: 0 0;
      transform: translate(calc(var(--width) * 0.864), calc(var(--width) / -2)) rotate(150deg) skewX(-30deg) scaleY(0.864);
    }
    
    .top {
      position: relative;
      background-color: #80bdfe;
      height: var(--length);
      width: var(--width);
      transform-origin: 0 0;
      transform: rotate(30deg) skew(-30deg) scaleY(0.864);
      bottom: calc(var(--height) + var(--height) + var(--width));
    }
    <div class="plane">
      <div id="container" class="container" style="--width: 50px; --length: 200px; --height: 100px; left: 150px; top: 150px;">
        <div class="left"></div>
        <div class="right"></div>
        <div class="top"></div>
      </div>
    </div>
    
    <div style="position: fixed;
        top: 0;
        right: 0;
        z-index: 999999;">
      width: <input type="range" min="10" max="400" value="50" class="slider" id="width">
      <br/> length: <input type="range" min="10" max="400" value="200" class="slider" id="length">
      <br/> height: <input type="range" min="10" max="400" value="100" class="slider" id="height">
    </div>

    Note: the translate has 0.864 constant, you can adjust it according to the scale value (which is also 0.864).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search