title: formular to calculate width/height (relative to parent) of container with translateZ inside of parent container with perspective
body: <h1>What is the formular to calculate the widths/heights of child elements with <code>translateZ</code> inside of parent container with set <code>perspective</code> (keyword: &quot;parallax&quot;) relative to its parents width/height?</h1>
  <p>I'd like to create a site with parallax effect on both axis. I was able to figure out everything i need for my mockup except one thing. How to calculate the childrens widths/heights when its above 100%. <strong>Because of parents perspective and childrens translateZ the childrens widths/heights visually don't align with parents width/height anymore.</strong></p>
  <p>The formular to scale the child elements is: <code>1 + (translateZ * -1) / perspective</code>. But i was not able to find a formular for width/height. BTW: When childrens widths/heights &lt;= 100% everything works fine.<br>
  But see the result on the image below when <strong>width &gt;= 100%</strong> (containers have top offset to make things visible).</p>
  <p><a href="https://i.stack.imgur.com/9GaM8.png" rel="noreferrer"><img src="https://i.stack.imgur.com/9GaM8.png" alt="enter image description here" /></a></p>
  <p><strong>To be correct the approach in my particular case is to let all child elements have visually the same widths/heights.</strong></p>
  <hr />
  <p>in SASS (preferred): <a href="https://codepen.io/elstermann/pen/EvWEyb/?editors=0100" rel="noreferrer">PEN</a> or <a href="https://www.sassmeister.com/gist/34cec842ce5c313ebf506c3c17ecc7f2" rel="noreferrer">SassMeister</a><br>in CSS: <a href="https://codepen.io/elstermann/pen/WEdqQO/?editors=0100" rel="noreferrer">PEN</a></p>
  <hr />
  <p>links from the specs that could help:<br>
  <a href="https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-3d-matrix" rel="noreferrer">https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-3d-matrix</a><br>
  <a href="https://www.w3.org/TR/css-transforms-1/#mathematical-description" rel="noreferrer">https://www.w3.org/TR/css-transforms-1/#mathematical-description</a></p>
  <hr />
  <p><strong>&quot;Googled&quot; a lot but didn't find anything pointing me to the right direction. Thanks in advance...</strong></p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>html, body {
    height: 100%;
    overflow: hidden;
    width: 100%;
  }
  
  #projection {
    perspective: 1px;
    perspective-origin: 0 0;
    height: 100%;
    overflow: auto;
    width: 100%;
  }
  
  .pro {
    transform: scale(1) translate(0px, 0px) translateZ(0px);
    height: 100%;
    position: absolute;
    transform-origin: 0 0;
    transform-style: preserve-3d;
    width: 100%;
  }
  
  .pro--1 {
    transform: scale(4) translate(0px, 0px) translateZ(-3px);
    width: 110%;
  }
  
  .pro--2 {
    transform: scale(3) translate(0px, 50%) translateZ(-2px);
    width: 110%;
  }
  
  .pro--3 {
    transform: scale(2) translate(0px, 100%) translateZ(-1px);
    width: 110%;
  }
  
  .pro {
    background: #333;
    box-shadow: inset 0 0 0 5px orange;
    color: orange;
    font-size: 4em;
    line-height: 1em;
    text-align: center;
  }
  
  .pro--2 {
    background: rgba(75, 75, 75, 0.5);
    box-shadow: inset 0 0 0 5px green;
    color: green;
    line-height: 4em;
  }
  
  .pro--3 {
    background: rgba(75, 75, 75, 0.5);
    box-shadow: inset 0 0 0 5px white;
    color: white;
    line-height: 7em;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="projection"&gt;
    &lt;div class="pro pro--1"&gt;pro--1&lt;/div&gt;
    &lt;div class="pro pro--2"&gt;pro--2&lt;/div&gt;
    &lt;div class="pro pro--3"&gt;pro--3&lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <h2>SASS</h2>
  <pre><code>@mixin  projection($translateZ: 0, $translateX: 0, $translateY: 0, $width: 0, $height: 0, $perspective: $perspective)
  
    // strip and sanitize units for further calculations
    // units must be &quot;px&quot; for both $translateZ and $perspective
    $unit: unit( $translateZ )
    @if '' != $unit
      $translateZ: $translateZ / ($translateZ * 0 + 1)
      @if 'px' != $unit
        @warn '$translateZ must have &quot;px&quot; as unit!'
  
    $unit: unit( $perspective )
    @if '' != $unit
      $perspective: $perspective / ($perspective * 0 + 1)
      @if 'px' != $unit
        @warn '$perspective must have &quot;px&quot; as unit!'
  
    $unit: 0px // yeah - technically this is no unit
    
    // calculate scaling factor
    $scale: 1 + ($translateZ * -1) / $perspective
  
    // sanitize units for translateX, translateY, translateZ
    $translateZ: $translateZ + $unit
    @if unitless( $translateX )
      $translateX: $translateX + $unit
    @if unitless( $translateY )
      $translateY: $translateY + $unit
  
    // render css &quot;transform: scale() translate(x, y) translateZ()&quot;
    transform: scale( $scale ) translate($translateX, $translateY) translateZ( $translateZ + $unit )
  
  $width: 110% // 100% works like a charme
  $translateZ--1: -3 // &quot;px&quot; will be added in mixin
  $translateZ--2: -2
  $translateZ--3: -1
  $perspective: 1
  
  html, body
    height: 100%
    overflow: hidden
    width: 100%
  
  #projection
    perspective: $perspective + 0px
    perspective-origin: 0 0
    height: 100%
    overflow: auto
    width: 100%
  
  .pro
    @include projection()
    height: 100%
    position: absolute
    transform-origin: 0 0
    transform-style: preserve-3d
    width: 100%
  
  .pro--1
    @include projection( $translateZ--1 )
    width: $width
  
  .pro--2
    @include projection( $translateZ--2, 0, 50% )
    width: $width
  
  .pro--3
    @include projection( $translateZ--3, 0, 100% )
    width: $width
  </code></pre>