Oliver Evans
Oliver Evans

Reputation: 989

Responsive triangles in a horizontal rule

I'm trying to create a fancy geometric looking horizontal rule. It consists of two triangles the points of which meet at the center of the page.

Below is a hacky code snippet showing what I've achieved so far. My issue is that it isn't responsive, I need the width of the triangles to span 50% of the window width. Plus I shuddered when I had to use calc.

The only way I can think about achieving what I want is to make the border width massive, then stick an overflow-x: hidden; on the container, but I'm sure there must be a better way to do this. Potentially using some sort of skew?

hr {
  position: relative;
  border: none;
  margin: 50px 0;
}
hr:before {
  content: "";
  border-style: solid;
  border-width: 50px 200px 0 0;
  border-color: blue transparent transparent transparent;
  position: absolute;
  left: calc(50% - 200px);
  top: 25px;
}
hr:after {
  content: "";
  border-style: solid;
  border-width: 0 0 50px 200px;
  border-color: transparent transparent red transparent;
  position: absolute;
  left: 50%;
  top: -25px;
}
<hr />

Upvotes: 2

Views: 392

Answers (1)

Hidden Hobbes
Hidden Hobbes

Reputation: 14183

One method is to use the vw unit for the border-width. vw is relative to the width of the viewport which means that border will adapt as the viewport width is increased/decreased. To ensure the triangle keeps the same shape the top/bottom borders can be modified to use vw units, this will ensure that the triangle's height is relative to it's width.

Rather than use margin a height equal to the height of the two triangles can be used for the hr, this makes it easier to position the triangles and ensures enough space is allotted for them (so they don't overlap other elements).

To achieve this the following modifications are required:

  • Remove margin: 50px 0; from hr
  • Add height: 16vw; to hr
  • Change border-width: 50px 200px 0 0; to border-width: 8vw 25vw 0 0;, top: 25px; to bottom: 0; and left: calc(50% - 200px); to right: 50%; on hr:before
  • Change border-width: 0 0 50px 200px; to border-width: 0 0 8vw 25vw; and top: -25px; to top: 0; on hr:after

hr {
  position: relative;
  border: none;
  height: 16vw;
}

hr:before {
  content: "";
  border-style: solid;
  border-width: 8vw 25vw 0 0;
  border-color: blue transparent transparent transparent;
  position: absolute;
  right: 50%;
  bottom: 0;
}

hr:after {
  content: "";
  border-style: solid;
  border-width: 0 0 8vw 25vw;
  border-color: transparent transparent red transparent;
  position: absolute;
  left: 50%;
  top: 0;
}
<hr />

Upvotes: 2

Related Questions