Search code examples
htmlcsscss-transformsskew

SkewX() math formula for full width (3 divs next to each other)


.parent {
  height: 500px;
  width: 500px;
  position: relative;
  background: black;
}

.test {
  transform: skewX(20deg);
  width: 33%;
  height: 100%;
  position: absolute;
}

.a {
  background: purple;
  left: 0;
}

.b {
  background: green;
  left: 33%;
}

.c {
  background: orange;
  left: 66%;
}
<div class="parent">
  <div class="test a"></div>
  <div class="test b"></div>
  <div class="test c"></div>
</div>

Jsfiddle: http://jsfiddle.net/jksqc1ux/7/

As you can see, because of the skew, you can still see the background of parent. All 3 of the divs being equall, what would it be the formula so that it will fill 100% of the parent (so you can no longer see the black in the snippet code)? The parent dimensions can have different values.

I'm looking for something like .a {left: calc(33% *0.4)} or something like that?


Solution

  • First, Adjust the transform-origin to bottom left to make it easier and you will obtain the result shown in the image below.

    Then you need to adjust both width and left properties by the amount X in order to cover the whole area. To calculate X you need to use the formula : tan(deg) = X / height (X = height * tan(deg)) where deg is the degree used for the skew and height is the height of the parent element. Since you have 3 elements this amount need to be split between them to always keep the same width.

    enter image description here

    I added some opacity so you can see that all the elements fit the width of the parent container:

    .parent {
      height:500px;
      width:500px;
      margin:auto;
      position:relative;
      background:black;
    }
    .test {
      transform: skewX(20deg);
      --X:calc(0.364 * 500px); /*tan(20deg) ~ 0.364*/
      transform-origin:bottom left;
      width:calc(calc(100%/3) + calc(var(--X)/3));
      height:100%;
      position:absolute;
      opacity:0.8;
    }
    .a {
        background:purple;
        left:0;
    }
    .b {
      background:green;
      left:calc(calc(100%/3) + calc(var(--X)/3));
    
    }
    .c {
      background:orange;
      left:calc(calc(2*100%/3) + calc(2 * var(--X)/3));
    }
    <div class="parent">
      <div class="test a">
    
      </div>
      <div class="test b">
    
      </div>
      <div class="test c">
    
      </div>
    </div>

    Another way to obtain a similar effect with less of code is to use gradient:

    .parent {
      height:500px;
      width:500px;
      margin:auto;
      position:relative;
      background:
      linear-gradient(70deg, purple 0,purple 33%, green 33%, green 66%,orange 66%,orange 100%);
    }
    <div class="parent">
    
    </div>