Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS triangle to fit variable sized div elements

Please refer to my fiddle. I was aiming to create a triangle (to be placed inside a div), and make it fit exactly (corner to corner).

Here are the rules outlined:

  • Place the triangle inside all the div elements.
  • The bottom left corner of the triangle should fit the bottom left corner inside all the divs.
  • The top right corner of the triangle should fit the top right corner inside all the divs.
  • The divs has fixed width and height BUT in real life they are all unknown, inherited from a parent.
  • The angle of the diagonal will be different for every div but that is ok.
  • Use borders, gradients, transform or SVG to solve the problem. I would not like to use fixed pixel solutions like canvas or PNG.

.one {
  width: 100px;
  /* Unknown */
  height: 30px;
  /* Unknown */
  background: #ccc;
}
.two {
  width: 40px;
  /* Unknown */
  height: 90px;
  /* Unknown */
  background: #aaa;
}
.three {
  width: 70px;
  /* Unknown */
  height: 70px;
  /* Unknown */
  background: #aaa;
}
.triangle {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 0 50px 50px;
  border-color: transparent transparent #007bff transparent;
}
<div class="one"></div>
<br>
<div class="two"></div>
<br>
<div class="three"></div>
<br>

<div class="triangle"></div>

JSFiddle Reference

like image 244
Jens Törnell Avatar asked Feb 18 '16 07:02

Jens Törnell


People also ask

How do I fit something in a div?

For width it's easy, simply remove the width: 100% rule. By default, the div will stretch to fit the parent container.

How do you fit a full width to a div?

What you could do is set your div to be position: absolute so your div is independent of the rest of the layout. Then say width: 100% to have it fill the screen width. Now just use margin-left: 30px (or whatever px you need) and you should be done.

How do I make DIVS stay the same size?

if you set width:500px; and height:300px; (or whatever size you want) the div should stay the same size. Also, you can set overflow:hidden; so that if whatever is in the div goes beyond those bounds, it is not shown, and does not resize the div. Show activity on this post. Try this one.


1 Answers

Achieving this effect with border will not be possible for dynamically sized containers because they cannot take percentage values or adapt based on a change in dimension of the container. They can only use either pixel or viewport units. Both those wouldn't be of much use for a dynamic container.

Transforms can be used by placing a pseudo-element on top of the containers but they would need calculations for height and width of the element based on trigonometric equations. The simpler ones would be the gradient and SVG approaches.

Using Gradient:

You can do this using a gradient with to [side] [side] syntax. This is responsive and would work for all container sizes. The only drawback is that there would be jagged lines in some cases where the width or height is too large compared to the other.

One advantage of this is that it doesn't require any extra elements (SVG or HTML, not even pseudos) but the drawback will be when hover and click effects are required for the triangle alone (restricted to the triangle's boundaries). Since the element is still a rectangle/square, the hover or click effect will be triggered even when the mouse is outside the triangle but within the container.

.one {
  width: 100px;
  height: 30px;
  background-color: #ccc;
}
.two {
  width: 40px;
  height: 90px;
  background-color: #aaa;
}
.three {
  width: 70px;
  height: 70px;
  background-color: #aaa;
}
div {
  background-image: linear-gradient(to top left, blue 50%, transparent 51%);
}
<div class="one"></div>
<br>
<div class="two"></div>
<br>
<div class="three"></div>
<br>

Using SVG:

You could also do it with SVG path element like in the below snippet. The SVG has to be positioned absolutely with respect to the container and have 100% of the parent's width and height.

The advantage of using SVG for the triangle over gradients is that hover and click effects can be added to the triangle alone.

.one {
  width: 100px;
  height: 30px;
  background-color: #ccc;
}
.two {
  width: 40px;
  height: 90px;
  background-color: #aaa;
}
.three {
  width: 70px;
  height: 70px;
  background-color: #aaa;
}

div{
  position: relative;
}
div > svg {
  position: absolute;
  height: 100%;
  width: 100%;
}
svg path{
  fill: #0007bf;
}
svg path:hover{
  fill: crimson;
}
<div class="one">
  <svg viewBox='0 0 100 100' preserveAspectRatio='none'>
    <path d='M100,0 L100,100 0,100z' />
  </svg>
</div>
<br>
<div class="two">
  <svg viewBox='0 0 100 100' preserveAspectRatio='none'>
    <path d='M100,0 L100,100 0,100z' />
  </svg>
</div>
<br>
<div class="three">
  <svg viewBox='0 0 100 100' preserveAspectRatio='none'>
    <path d='M100,0 L100,100 0,100z' />
  </svg>
</div>
<br>
like image 77
Harry Avatar answered Sep 16 '22 13:09

Harry