skip to Main Content
#rectangle {
  width: 100vw;
  height: 50vw;
  background-color: black;
}

#triangle {
  width: 0;
  height: 0;
  border-top: 25vw solid transparent;
  border-bottom: 25vw solid transparent;
  border-left: 33.33vw solid blue;
}
<div id="rectangle">
  <div id="triangle"></div>
</div>

HTML

<div id="rectangle">
  <div id="triangle"></div>
</div>

CSS

#rectangle {
  width: 100vw;
  height: 50vw;
  background-color: black;
}

#triangle {
  width: 0;
  height: 0;
  border-top: 25vw solid transparent;
  border-bottom: 25vw solid transparent;
  border-left: 33.33vw solid blue;
}

I’m using the borders width of the "triangle" div to make an isosceles triangle with its base resting on the left side of the parent "rectangle" div.

I want the base of the triangle to be as long as the left side of the rectangle and its height to be exactly 1/3 of the width of the rectangle. I temporarily achieved this by setting its dimensions relative to the viewport, but what I actually want is to define them relative to the dimensions of the parent (yes, I’m aware it would functionally be the same). Is this possible?

4

Answers


  1. Since the rectangle has definite dimensions you can use Container Query dimensions on the triangle, like this:

    #rectangle {
      width: 80vw;
      height: 50vw;
      background-color: black;
      container-type: size;
      margin-inline: 10vw;
    }
    
    #triangle {
      width: 0;
      height: 0;
      border-top: 50cqh solid transparent;
      border-bottom: 50cqh solid transparent;
      border-left: 33.33cqw solid blue;
    }
    <div id="rectangle">
      <div id="triangle"></div>
    </div>

    I’ve used 50cqh for the half the rectangle height, and 33.33cqw for the width to show that it’s not reliant on the ratio of the height and width of the rectangle. I’ve also added a margin to the rectangle’s inline dimension so that it no longer matches that of the viewport.

    Login or Signup to reply.
  2. Percentages won’t work on borders, so I tried a different approach to achieve what you’re after.

    Here is a solution that fakes it using a clip-path.

    First I made #triangle equal sides, with size based on its parent. Then I positioned a clipped pseudo-element within it. The clipping path is calculated to make an equilateral triangle.

    #rectangle {
      width: 100vw;
      height: 50vw;
      background-color: black;
    }
    
    #triangle {
      height: 100%;
      aspect-ratio: 1 / 1;
      position: relative;
    }
    
    #triangle::before {
      background-color: red;
      clip-path: polygon(0 0, calc(100% * sqrt(3) / 2) 50%, 0 100%);
      content: '';
      display: block;
      height: 100%;
      left: 0;
      position: absolute;
      top: 0;
      width: 100%;
    }
    <div id="rectangle">
      <div id="triangle"></div>
    </div>
    Login or Signup to reply.
  3. As another solution, we can use css custom properties and the calc() function, to create the following code:

    html {
      --boxwidth: 100vw; /* Define in a parent element */
    }
    
    #rectangle {
      width: var(--boxwidth);
      height: 50vw;
      background-color: black;
    }
    
    #triangle {
      width: 0;
      height: 0;
      border-top: 25vw solid transparent;
      border-bottom: 25vw solid transparent;
      border-left: calc(var(--boxwidth) / 3) solid blue;
    }
    <html>
      <div id="rectangle">
        <div id="triangle"></div>
      </div>
    </html>

    Although not the most elegant solution, it is very flexible if you decide to continue to alter the dimensions. For more information you can visit CSS Custom Properties and CSS calc().

    Login or Signup to reply.
  4. Use modern way to create the triangle shape and you don’t need a complex code

    #rectangle {
      width: 80vw;
      height: 50vw;
      display: flex; /* make the triangle full height */
      background-color: black;
      margin-inline: auto;
    }
    
    #triangle {
      background: blue;
      width: calc(100%/3); /* 1/3 of the width */
      clip-path: polygon(0 0, 100% 50%, 0 100%); /* 3-point polgyon */
    }
    <div id="rectangle">
      <div id="triangle"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search