Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

background image, linear gradient jagged edged result needs to be smooth edged

I'm trying to make the bottom of an image pointed. I've tried to get this effect by producing two triangles at the bottom. They must be responsive. and after searching all over the internet with a lot of examples that don't work for my requirement this is the best so far I've managed to produce.

body,
html {
  height: 100%
}
.image {
  width: 1410px;
  margin-right: auto;
  margin-left: auto;
  height: 500px;
  overflow: hidden;
  position: relative;
}
.pointer {
  height: 50px;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
}
.triangleWrapper {
  width: 50%;
  height: 50px;
  float: left;
}
.lefttriangle {
  width: 100%;
  height: 10px;
  left: 0px;
  top: 0px;
  background-image: linear-gradient(to right top, #ffffff 50%, transparent 50%);
}
.righttriangle {
  width: 100%;
  height: 10px;
  right: 0px;
  top: 0px;
  background: linear-gradient(to left top, #ffffff 50%, transparent 50%)
}
<div class="image">
  <img src="http://placekitten.com/1410/500">
  <div class="pointer">
    <div class="triangleWrapper">
      <div style="height: 100%;" class="lefttriangle"></div>
    </div>
    <div class="triangleWrapper">
      <div style="height: 100%;" class="righttriangle"></div>
    </div>
  </div>
</div>

CodePen Demo

It works exactly how I want it to as it is responsive without the need for media queries. BUT it has a jagged edge on the triangle line that isn't 90deg.

How do I get this to produce a smooth line in most if not all modern browsers? I'm not asking for backward compatibility.

Any help is greatly appreciated!

like image 925
Richard Avatar asked Oct 12 '15 22:10

Richard


People also ask

What is linear gradient in background image?

The linear-gradient() function sets a linear gradient as the background image. To create a linear gradient you must define at least two color stops. Color stops are the colors you want to render smooth transitions among. You can also set a starting point and a direction (or an angle) along with the gradient effect.

What are background gradients?

Gradients, also known as color transitions, are a gradual blending from one color to another color (or, if you're in a colorful mood, from one color to another color to another color—gradients aren't limited to two shades).

What is linear gradation?

linear-gradient() The linear-gradient() CSS function creates an image consisting of a progressive transition between two or more colors along a straight line. Its result is an object of the <gradient> data type, which is a special kind of <image> .

How do you add transparency to a linear gradient?

To add transparency, we use the rgba() function to define the color stops. The last parameter in the rgba() function can be a value from 0 to 1, and it defines the transparency of the color: 0 indicates full transparency, 1 indicates full color (no transparency).


2 Answers

Unfortunately, this always happens when we use angled linear-gradient images and currently the only way to overcome this behavior seems to be to avoid hard-stopping of the colors (that is, don't make the stop point of one color as the start point of the next). Making the second color start a little farther away from the stop point of the first color would kind of create a blurred area and make it look more smoother. This is still not 100% perfect but is better than having jagged edges.

.lefttriangle {
  width: 100%;
  height: 10px;
  left: 0px;
  top: 0px;
  background-image: linear-gradient(to right top, #ffffff 48%, transparent 50%); /* note the change of stop and start points */
}
.righttriangle {
  width: 100%;
  height: 10px;
  right: 0px;
  top: 0px;
  background: linear-gradient(to left top, #ffffff 48%, transparent 50%);  /* note the change of stop and start points */
}

body,
html {
  height: 100%
}
.image {
  width: 1410px;
  margin-right: auto;
  margin-left: auto;
  height: 500px;
  overflow: hidden;
  position: relative;
}
.pointer {
  height: 50px;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
}
.triangleWrapper {
  width: 50%;
  height: 50px;
  float: left;
}
.lefttriangle {
  width: 100%;
  height: 10px;
  left: 0px;
  top: 0px;
  background-image: linear-gradient(to right top, #ffffff 48%, transparent 50%);
}
.righttriangle {
  width: 100%;
  height: 10px;
  right: 0px;
  top: 0px;
  background: linear-gradient(to left top, #ffffff 48%, transparent 50%);
}
<div class="image">
  <img src="http://placekitten.com/1410/500">
  <div class="pointer">
    <div class="triangleWrapper">
      <div style="height: 100%;" class="lefttriangle"></div>
    </div>
    <div class="triangleWrapper">
      <div style="height: 100%;" class="righttriangle"></div>
    </div>
  </div>
</div>

Alternate Implementations:

Clip Paths: You can use clip-path feature also to produce a similar effect. The advantage of using clip-path is that it is both responsive and also produces a transparent cut. The SVG based clip-path has better browser support than the CSS version. This is not yet supported in IE though.

body,
html {
  height: 100%
}
.image {
  width: 1410px;
  margin-right: auto;
  margin-left: auto;
  height: 500px;
  overflow: hidden;
  position: relative;
}
.css-clip {
  -webkit-clip-path: polygon(0% 0%, 0% 90%, 50% 100%, 100% 90%, 100% 0%);
  clip-path: polygon(0% 0%, 0% 90%, 50% 100%, 100% 90%, 100% 0%);
}
.svg-clip {
  -webkit-clip-path: url(#clipper);
  -moz-clip-path: url(#clipper);
  clip-path: url(#clipper);
}
<!-- CSS Clip-path - Lower browser support -->
<div class="image css-clip">
  <img src="http://placekitten.com/1410/500">
</div>

<!-- SVG Clip-path - Better browser support -->

<svg width="0" height="0">
  <defs>
    <clipPath clipPathUnits="objectBoundingBox" id="clipper">
      <path d="M0,0 0,0.9 0.5,1 1,0.9 1,0z" />
    </clipPath>
  </defs>
</svg>
<div class="image svg-clip">
  <img src="http://placekitten.com/1410/500">
</div>

Using CSS Transform: You could also try using the approach mentioned in this answer. It achieves a pointed effect on the left side but it should be easy to adapt it to create a pointed effect on the bottom side.

body,
html {
  height: 100%
}
.image {
  width: 1410px;
  margin-right: auto;
  margin-left: auto;
  height: 500px;
  overflow: hidden;
  position: relative;
}
.top-container,
.bottom-container {
  position: absolute;
  bottom: 0px;
  height: 100%;
  width: 50%;
  overflow: hidden;
  backface-visibility: hidden;
}
.top-container {
  left: 0px;
  transform-origin: right bottom;
  transform: skewY(10deg);
}
.bottom-container {
  right: 0px;
  transform-origin: left bottom;
  transform: skewY(-10deg);
  background-position: 0% 100%;
}
.top-container:after,
.bottom-container:after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  bottom: -62px;  /* tan(10) * (width/2) / 2 */
  background: url(http://placekitten.com/1410/500);
  background-size: 200% 100%;
}
.top-container:after {
  left: 0px;
  transform: skewY(-10deg);
}
.bottom-container:after {
  right: 0px;
  transform: skewY(10deg);
  background-position: 100% 0%;
}
<div class="image">
  <div class='top-container'></div>
  <div class='bottom-container'></div>
</div>
like image 54
Harry Avatar answered Nov 15 '22 21:11

Harry


Just found an insanely good solution on codepen using calc(50% - 1px)

https://codepen.io/hellonico/pen/xEYXmL

background: linear-gradient(7deg, currentColor calc(50% - 1px), transparent 50%);

No blur whatsoever, just a smooth edge

EDIT: .. apparently not in Safari?..

like image 35
katerlouis Avatar answered Nov 15 '22 21:11

katerlouis