2

I'm trying to create a HTML design with objects which contain angled sides.

What I'm currently using is a background: linear-gradient() but the edges are not sharp and get pixelated. The reason I used this is because it is in % which makes it easier for responsiveness.

Code:

#container {
    position: absolute;
    width: 100%;
    height: 100%;
    display: block;
}

#shape {
    position: absolute;
    z-index: 6;
    background: #42145f;
    width: 45%;
    height: 60%;
    left: 0px;
    top: 0px;
    background: linear-gradient(to right bottom, #42145f 50%, transparent 50%)
}

#shape2 {
 position: absolute;
   z-index: 5;
   background: #c50084;
   width: 100%;
   height: 35%;
   left: 0px;
   top: 0px;
   background: linear-gradient(to right bottom, #c50084 50%, transparent 50%)
}

#shape3 {
   position: absolute;
    z-index: 4;
    background: #6e2c6b;
    width: 37%;
    height: 73%; 
    left: 0px;
    top: 27%;
    background: linear-gradient(to right top, #6e2c6b 50%, transparent 50%)
}

#shape4 {
    position: absolute;
    z-index: 3;
    background: #b71234;
    width: 100%;
    height: 14%;
    left: 0;
    top: 86%;
    background: linear-gradient(to left top, #b71234 50%, transparent 50%)
}

#shape5 {
    position: absolute;
    z-index: 0;
    background: #8d1b3d;
    width: 20%;
    height: 78%;
    left: 80%;
    top: 22%;
    background: linear-gradient(to left top, #8d1b3d 50%, transparent 50%)
}

#shape6 {
    position: absolute;
    z-index: 2;
    background: #ff5800;
    width: 22%;
    height: 59%;
    left: 78%;
    top: 0;
    background: linear-gradient(to left bottom, #ff5800 50%, transparent 50%)
}

#shape7 {
    position: absolute;
    z-index: 1;
    background: #fadc41;
    width: 30%;
    height: 54%;
    left: 70%;
    top: 0;
    background: linear-gradient(to left bottom, #fadc41 50%, transparent 50%)
}
<div id="container">
 <div id="shape"></div>
 <div id="shape2"></div>
 <div id="shape3"></div>
 <div id="shape4"></div>
 <div id="shape5"></div>
 <div id="shape6"></div>
 <div id="shape7"></div>
</div>

What I previously used was a div with border which has a smooth and sharp edge but border doest not support % so in that case I thought it wouldn't be possible in this solution for responsiveness:

#container {
    position: absolute;
    width: 100%;
    height: 100%;
    display: block;
}

#shape {
   position: absolute;
    height: 0; 
    width: 0px;
    border-top: 600px solid #42145f;
    border-right: 700px solid transparent;
    z-index: 6;
}

#shape2 {
   position: absolute;
   height: 0; 
   width: 0px;
   border-top: 375px solid #c50084;
   border-right: 1600px solid transparent;
   z-index: 5;
}

#shape3 {
    position: absolute;
    height: 0; 
    width: 0px;
    top: 200px;
    border-bottom: 780px solid #6e2c6b;
    border-right: 600px solid transparent;
    z-index: 4;
}

#shape4 {
    position: absolute;
    height: 0; 
    width: 0px;
    top: 840px;
    left: 0px;
    border-bottom: 140px solid #b71234;
    border-left: 1600px solid transparent;
    z-index: 3;
}

#shape5 {
    position: absolute;
    height: 0; 
    width: 0px;
    top: 250px;
    left: 1300px;
    border-bottom: 700px solid #8d1b3d;
    border-left: 300px solid transparent;
    z-index: 0;
}

#shape6 {
    position: absolute;
    height: 0; 
    width: 0px;
    left: 1250px;
    border-top: 600px solid #ff5800;
    border-left: 350px solid transparent;
    z-index: 2;
}

#shape7 {
    position: absolute;
    height: 0; 
    width: 0px;
    left: 1130px;
    border-top: 554px solid #fadc41;
    border-left: 470px solid transparent;
    z-index: 1;
}
<div id="container">
 <div id="shape"></div>
 <div id="shape2"></div>
 <div id="shape3"></div>
 <div id="shape4"></div>
 <div id="shape5"></div>
 <div id="shape6"></div>
 <div id="shape7"></div>
</div>

I'm aware of the :before and :after options but I'm not sure if it will create the sharp edges for angled <div>'s and how this could be done. Any help?

It should look like this:

Goal

Rich
  • 21
  • 1
  • 5
  • Maybe you need help online generators? https://www.google.by/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=css+shape+generator – grinmax Jan 30 '17 at 10:16
  • Hmmm that looks interesting! – Rich Jan 30 '17 at 10:56
  • The edges look smooth in firefox 50, chrome 56, Edge 38. Could you post a picture of how the pixelated borders look like? Also could a solution be to create this as an SVG? – Persijn Jan 30 '17 at 10:57
  • Is this also usable with position absolute and making it responsive? – Rich Jan 30 '17 at 11:03
  • I'll update the code in a bit, I took the older code. I'll also add a screenshot. The problem I was encountering is that I wanted to use % instead of pixels but that's not possible in borders. So that's why I'm using different style now and that's the one I'll update in a bit. – Rich Jan 30 '17 at 11:19
  • @grinmax could you add your comment as an answer, for me it's the solution. – Rich Jan 30 '17 at 14:09
  • @Rich may be use REM? https://jsfiddle.net/qba3pk97/ maybe this help you.. – grinmax Jan 30 '17 at 14:27

3 Answers3

3

This sounds like a similar issue to the one explored in this question: css transform, jagged edges in chrome

The answer there was to use: -webkit-backface-visibility: hidden;

Community
  • 1
  • 1
Alex Magill
  • 262
  • 3
  • 8
  • 1
    I'm not using the transform css attribute at the moment, so I think this wouldn't work. And I see the unsharpness also in Safari and Firefox. – Rich Jan 30 '17 at 10:55
  • My mistake - sorry about that. Can you screen-shot what you are seeing? – Alex Magill Jan 30 '17 at 11:06
  • I'll update the code in a bit, I took the older code. I'll also add a screenshot. The problem I was encountering is that I wanted to use % instead of pixels but that's not possible in borders. So that's why I'm using different style now and that's the one I'll update in a bit. – Rich Jan 30 '17 at 11:19
  • That's a really interesting technique! The only jagged edges I'm seeing appear to be down to the limits of antialiasing. I'm not sure there's a way around that. In terms of getting it to be more responsive (or at least fit different shapes) - using javascript to adjust the border widths on the fly might be your best option. However, as @Persijn notes, SVG might be a more useful approach in the long run. – Alex Magill Jan 31 '17 at 12:36
  • Why would SVG be more useful in the long run? – Rich Feb 02 '17 at 16:16
  • @Rich You get a lot more direct control with SVG, and its scalable - the down-side is more code. (I'm not sure there's a rendering advantage, you'll likely still see the same antialiasing effects) – Alex Magill Feb 02 '17 at 18:38
  • Thanks for the explanation. I currently used the -webkit-clip-path: polygon(); and clip-path: polygon(); combination. I'll set the final result soon here. Thanks for your input! – Rich Feb 03 '17 at 08:48
0

With the help of everyone here I came to the final solution of applying the suggested -webkit-clip-path() and clip-path() (answered by grinmax).

It gives clear and sharp edges on the angled objects.

Thanks for everyone's help!

The code is:

#container {
    position: absolute;
    width: 100%;
    height: 100%;
    display: block;
}

#shape {
    position: absolute;
    z-index: 6;
    background: #42145f;
    width: 40%;
    height: 55%;
    left: 0px;
    top: 0px;
    -webkit-clip-path: polygon(0 0, 0 100%, 100% 0);
 clip-path: polygon(0 0, 0 100%, 100% 0);
}

#shape2 {
    position: absolute;
    z-index: 5;
    background: #c50084;
    width: 100%;
    height: 35%;
    left: 0px;
    top: 0px;
    -webkit-clip-path: polygon(0 0, 0 100%, 100% 0);
    clip-path: polygon(0 0, 0 100%, 100% 0);
}

#shape3 {
    position: absolute;
    z-index: 4;
    background: #6e2c6b;
    width: 37%;
    height: 73%; 
    left: 0px;
    top: 27%;
    -webkit-clip-path: polygon(0 0, 0 100%, 100% 100%);
    clip-path: polygon(0 0, 0 100%, 100% 100%);
}

#shape4 {
    position: absolute;
    z-index: 3;
    background: #b71234;
    width: 100%;
    height: 14%;
    left: 0;
    top: 86%;
    -webkit-clip-path: polygon(0 100%, 100% 100%, 100% 0);
    clip-path: polygon(0 100%, 100% 100%, 100% 0);
}

#shape5 {
    position: absolute;
    z-index: 0;
    background: #8d1b3d;
    width: 20%;
    height: 78%;
    left: 80%;
    top: 22%;
    -webkit-clip-path: polygon(0 100%, 100% 100%, 100% 0);
    clip-path: polygon(0 100%, 100% 100%, 100% 0);
}

#shape6 {
    position: absolute;
    z-index: 2;
    background: #ff5800;
    width: 22%;
    height: 59%;
    left: 78%;
    top: 0;
    -webkit-clip-path: polygon(0 0, 100% 100%, 100% 0);
    clip-path: polygon(0 0, 100% 100%, 100% 0);
}

#shape7 {
    position: absolute;
    z-index: 1;
    background: #fadc41;
    width: 30%;
    height: 54%;
    left: 70%;
    top: 0;
    -webkit-clip-path: polygon(0 0, 100% 100%, 100% 0);
    clip-path: polygon(0 0, 100% 100%, 100% 0);
}
<div id="container">
 <div id="shape"></div>
 <div id="shape2"></div>
 <div id="shape3"></div>
 <div id="shape4"></div>
 <div id="shape5"></div>
 <div id="shape6"></div>
 <div id="shape7"></div>
</div>
Rich
  • 21
  • 1
  • 5
0

Or you could simply use -webkit-backface-visibility: hidden; instead of -webkit properties and shorten the code that way.

Code Genie
  • 11
  • 1
  • 6