8

This is my css triangle. When the parent container -which has a height percentage setting- is resized then the triangle should resize too.

How must change the below definition that this could work?

If it does not work with common CSS I am also open for CSS3.

.segmentTriangle{
    width: 0px;
    height: 0px;
    position: relative;
    left: 0;
    top: 0;
    border-style: solid;
    border-width: 20px 20px 0 0;
    border-color: #000 transparent transparent transparent;
}

UPDATE

That is part of my layout:

<div style="height: 100%;">
    <div style="float: left; height: 100%;" id="triangleWrapper">
        <div style="height: 100%;" class="segmentTriangle"></div>
    </div>
    <div class="fontsize" data-bind="text: replies, style: { height: heightFormatted, background: background }" style="width: 90%;padding-right:20px; height: 100%; text-align: right; float: left;"></div>
</div>
Elisabeth
  • 20,496
  • 52
  • 200
  • 321

4 Answers4

14

You need to change the way you generate the triangle, as Mr Alien says border is not fluid.

The CSS would be:

.triangle {
    width: 40%;
    height: 40%;
    left: 0px;
    top: 0px;
    background: linear-gradient(to right bottom, black 50%, transparent 50%)
}

demo

You set the triangle dimension to the percentage of the parent that best suits you, then you make the diagonal of the triangle in black.

Changed demo so that base elements are responsive:

demo2

New demo to include your html.

demo3

I have added CSS to a bare minimum to make it work: added 100% height to body & html, added width to wrapper. Otherwise, it's your layout, so this should work.

Community
  • 1
  • 1
vals
  • 61,425
  • 11
  • 89
  • 138
  • Your fiddle does not work. When I resize the window none of the triangles resize. – Elisabeth Jul 30 '13 at 11:05
  • @Elisa My original fiddle was demonstrating that the triangle adapts to different parent sizes, that was your original requirement; not that the parent were responsive. Added demo with the base elements responsive. – vals Jul 30 '13 at 11:11
  • I have read that the width and height can not be set with percentage using the arrow border approach. Why does it work for you? I can not use absolue position on the parent my layout is pretty different. – Elisabeth Jul 30 '13 at 11:36
  • I am not using the arrow border layout, I am getting the same result with a different technique (that does allow for percentages). Why don't you set a more complete fiddle, including your parent class ? – vals Jul 30 '13 at 11:46
  • I have updated my init post with the html layout. Does my layout allow your technique? – Elisabeth Jul 30 '13 at 12:07
  • Would it not be better for me to try SVG ? This should always resize? – Elisabeth Jul 30 '13 at 12:28
  • @Elisa why so redundant to use jQuery? – Mr. Alien Jul 30 '13 at 15:28
  • @Elisa Added another demo based on your html. I wouldn't go for SVG, it is more complex. What you have heard about SVG is that it scales very well (that is, the definition is always good) but not necesarily that it scales easily. Anyway, it's your choice, good luck. – vals Jul 30 '13 at 17:28
  • you were right still had to tweak some margins and now it looks very good :) Thanks learned again something new about borders and percentage values. – Elisabeth Jul 31 '13 at 06:53
  • Is there a way to tell the triangle_aspect_ratio = parent_aspect_ratio * 1.5 ? – Elisabeth Jul 31 '13 at 07:12
  • You choose the horizontal ratio and the vertical ratio thru the width and height properties. One way to get this ratio would be to set width:100% and height:66% (if you calculate ratio as width/height and not height/width). This way the width is the same of the parent, the height is 2/3 of the parent, and the ratio is 1.5 – vals Jul 31 '13 at 09:52
  • Thanks, made the child a width of 150% then it looks better. – Elisabeth Jul 31 '13 at 10:28
  • The anti-aliasing is nice in IE11, but horrible in Chrome, almost like "crisp edges" in SVG. –  Apr 06 '17 at 12:36
11

My solution:
http://codepen.io/malyw/pen/mhwHo/

Description:
I needed arrows to mark active sidebar menu items.
When I had multiline text in them, arrow was broken.
So mu solution is:
use :after and :before elements with linear-gradient to provide stretched arrows with the same width:

Code:

&:before { 
  top: 0px; background: linear-gradient(to right top, $color 50%, transparent 50%);
}

&:after {
  top: 50%; background: linear-gradient(to right bottom, $color 50%, transparent 50%);
}

Thanks @vals for idea.

Serg Hospodarets
  • 4,658
  • 4
  • 25
  • 31
  • I like it, even if it doesn't support IE < 10! Here's an expanded fork of your solution showing top, right, bottom, and left points http://codepen.io/henry/pen/raLOvd – henry Dec 17 '14 at 02:11
6

This fiddle implements responsive CSS triangles using just CSS and one element. It shows up, down, left and right pointing triangles and yours is top-left pointing. The responsive down pointing triangle can be easily modified to achieve it:

.triangle-top-left {
    width: 0;
    height: 0;
    padding-bottom: 25%;
    padding-left: 25%;
    overflow: hidden;
}
.triangle-top-left:after {
    content: "";
    display: block;
    width: 0;
    height: 0;
    margin-left: -500px;

    border-bottom: 500px solid transparent;
    border-left: 500px solid #4679BD;
}

For the explanation on the logic used for the responsive triangle see my article on Pure CSS responsive triangles.

JoseV
  • 852
  • 10
  • 9
0

Non Gradient solution to avoid Jagged lines (Fiddle)

I was looking for something exactly like @Serg Hospodarets answer but I realized that gradient is creating a jagged line, probably a rendering issue of browser. So after some searching and fiddling I made this.

Summary: I using a spacer technique answered here by Johan Rönnblom to calculate width relative to height by 1:1 ratio, then I am adding 2 boxes at the edge of div which have 50% of parent element height and width equal to that 50% creating perfect squares, then I am rotating sub element at 45deg creating the diagonal cuts.

Below is the complete code:

HTML

<div class="box">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro, esse assumenda corporis nemo perspiciatis dolorem vero consectetur asperiores necessitatibus, ea, saepe fugit alias, voluptatum blanditiis quia! Consequatur dolorem, consectetur adipisci.
  <div class="u-prop">
    <div class="wrap">
      <img class="spacer" width="2048" height="2048" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
      <div class="proportional"></div>
    </div>
  </div>

  <div class="u-prop is--bot">
    <div class="wrap">
      <img class="spacer" width="2048" height="2048" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
      <div class="proportional"></div>
    </div>
  </div>

</div>

SCSS:

body {
  padding: 10px;
}

* {
  box-sizing: border-box;
}

.box {
  padding: 10px;
  width: 500px;
  position: relative;
  background: #eee;
  &:before {
    content: '';
    display: block;
    width: 100%;
    height: 100%;
    border: 1px solid #000;
    position: absolute;
    top: 0;
    left: 0;
    box-sizing: border-box;
    border-right: solid -0px transparent;
  }
}

.u-prop {
  position: absolute;
  height: 50%;
  width: 100%;
  top: 0;
  left: 100%;
  &.is--bot {
    top: 50%;
    .proportional {
      transform: rotate(-45deg);
      transform-origin: bottom left;
      &:before {
        border-bottom: 1px solid #000;
        border-top: none;
      }
    }
  }
  .spacer {
    width: auto;
    max-height: 100%;
    visibility: hidden;
  }
  .proportional {
    position: absolute;
    top: 0;
    left: 0px;
    width: 150%;
    height: 0;
    padding-bottom: 100%;
    background: #eee;
    transform: rotate(45deg);
    transform-origin: top left;
    &:before {
      content: '';
      display: block;
      width: 100%;
      height: 100%;
      border-top: 1px solid #000;
      position: absolute;
      top: 0;
      left: 0;
      box-sizing: border-box;
    }
  }
  .wrap {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: auto;
    max-width: 100%;
    overflow: hidden;
  }
}
Imran Bughio
  • 4,811
  • 2
  • 30
  • 53