Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintain angle of clip-path on viewport width and height changes

I am trying to create something similar to the example, where the angle of the clip path needs to remain the same on resizing. Both on height and width changes to the viewport. I have tried using calc(100% - 6vw) (as an example) but this doesn't maintain the exact angle.

The reason for this is I will have multiple elements that are required to have mirroring angles in a responsive environment.

Can this be achieved using CSS and calc alone, or is there a JS-based math solution to resolve it? I guess this is where trigonometry comes in and I believe what I need is the opposite side length being relative to the height of the adjacent/height of the content area (however, I failed maths...) to maintain the same angle.

Some work that I have done based on a mock-up I am working from. The angle (I think) I need to find is 14deg. I've based this on the adjacent being 899px and the opposite 229px.

Any help is much appreciated.

body {
  margin: 0;
}

.slide {
  background-color: red;
  height: 100vh;
  position: relative;
}

.slide_content {
  background-color: blue;
  padding: 50px 30px;
  color: #fff;
  position: absolute;
  width: 70%;
  left: 0;
  bottom: 0;
  clip-path: polygon(0 0, 90% 0, 102% 100%, 0% 100%);
}

.slide_content-top {
  background-color: orange;
  padding: 50px 30px;
  color: #fff;
  position: absolute;
  width: 70%;
  right: 0;
  top: 0;
  padding-left: 100px;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 10% 100%);

}
<div class="slide">
  <div class="slide_content-top">
    <h2>More content here</h2>
  </div>
  <div class="slide_content">
    <h2>Some text goes here</h2>
  </div>
</div>

Another Example

So how I would apply this is as follows - The shape in red is where text content would be placed. The area in blue is the right-angle triangle I need to create. The triangle would need to maintain it's ratio as the content area grows or shrinks. The base of this triangle (width: 85px in this example) would need to resize in proportion to the height of the content area (currently height: 200px).

The only values I would know are the acute angle between the hypotenuse and the adjacent (14deg), and the length of the adjacent would be calculated by getting it from the content area's current height.

.shape {
  width: 400px;
  height: 200px;
  background-color: red;
  position: relative;
}

.shape:after {
  content: '';
  position: absolute;
  width: 85px;
  height: 200px;
  background-color: blue;
  top: 0;
  bottom: 0;
  right: -85px;
  clip-path: polygon(0 0, 0 0, 100% 100%, 0% 100%);
}
<div class="shape"></div>

A further update

This is what I have achieved so far. Which I think does part of what I am looking for. Creates a right-angle that maintains to same ratio on resizing. However, I'm not entirely sure how robust this particular snippet I've created is.

function getTanFromDegrees(degrees) {
  return Math.tan(degrees * Math.PI / 180);
}



function createRightAngleTriangle() {
  const shapes = document.querySelectorAll('.shape');
  
  shapes.forEach(shape => {
    const shapeContent = shape.querySelector('.shape-content');
    const shapeTri = shape.querySelector('.shape-tri');
    
    const shapeHeight = shapeContent.offsetHeight; 
    
    const tan = getTanFromDegrees(14);
    const getLength = Math.floor(tan * shapeHeight);

    shapeTri.style.height = shapeHeight + 'px';
    shapeTri.style.width = getLength + 'px';

  })
}

window.addEventListener('load', createRightAngleTriangle);
window.addEventListener('resize', createRightAngleTriangle);
.shape {
  display: flex;
  align-items: flex-start;
}

.shape-content {
  padding: 20px;
  font-size: 22px;
  
}

.shape-tri {
  background-color:green;
  clip-path: polygon(0 0, 0 0, 100% 100%, 0% 100%);

}

.shape-1 .shape-content {
  background-color: red;
}

.shape-2 .shape-content {
  background-color: blue;
}
<div class="shape shape-1">
  <div class="shape-content">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Maiores aut deleniti dolor doloremque, nesciunt minus voluptatem! Voluptas odio obcaecati vitae?
  </div>
  <div class="shape-tri"></div>
</div>
<div class="shape shape-2">
  <div class="shape-content">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Maiores aut deleniti dolor doloremque, nesciunt minus voluptatem! Voluptas odio obcaecati vitae? Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ut, eos.
  </div>
  <div class="shape-tri"></div>
</div>
like image 328
Bagseye Avatar asked Dec 01 '25 22:12

Bagseye


1 Answers

You can try like below. the value 0.25 is tan(14deg)

body {
  margin: 0;
}

.slide {
  background-color: red;
  min-height: 100vh;
  display:grid;
  grid-auto-rows:1fr;
  color: #fff;
}

.slide_content {
  background: blue;
  box-shadow: 200px 0 blue;
  padding: 30px;
  width: 70%;
  margin-top:auto;
  clip-path: polygon(0 0, 100% 0, calc(100% + 0.25*100vmax) 100vmax, 0 100vmax);
}

.slide_content-top {
  background-color: orange;
  box-shadow: -200px 0 orange;
  padding: 30px;
  width: 70%;
  margin-left: auto;
  margin-bottom:auto;
  clip-path: polygon(calc(-0.25*100vmax) -100vmax ,100% -100vmax, 100% 100%, 0 100%);
  
}
<div class="slide">
  <div class="slide_content-top">
    <h2>More content here</h2>
  </div>
  <div class="slide_content">
    <h2>Some text <br> goes here</h2>
  </div>
</div>
like image 157
Temani Afif Avatar answered Dec 04 '25 13:12

Temani Afif



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!