31

I have a triangle (JSFiddle) using this CSS:

.triangle {
    width: 0;
    height: 0;
    border-top: 0;
    border-bottom: 30px solid #666699;
    border-left: 20px solid transparent; 
    border-right: 20px solid transparent;
    }

And this HTML:

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

This makes a triangle, but the diagonal lines are jagged and pixelated. How can I make them smooth? (I was able to smooth them out in Safari and Chrome by making them dotted, but that broke the triangles in Firefox and IE.)

web-tiki
  • 99,765
  • 32
  • 217
  • 249
kirkaracha
  • 742
  • 2
  • 14
  • 23
  • I'm using FF6 at the moment, and it's nice and smooth (anti-aliased) here. IE renders things very badly all over the place, so this doesn't surprise me. What version of FF are you using? – Bojangles Sep 12 '11 at 22:45
  • Strange, FF6 and Chrome 13 render it with smooth edges, and both IE8 and Safari 5.1 render jagged edges. OS=Win XP SP3. – fvu Sep 12 '11 at 22:48
  • Firefox 6.0.2 and Chrome 13 (OS X), IE8 (Windows XP) are jagged for me. (Windows in Parallels emulation.) – kirkaracha Sep 12 '11 at 23:08
  • 3
    I think this question has become out of date - corners are anti-aliased by default in webkit, and 'dotted' fixes it in Firefox http://jsbin.com/opusan/1/edit (and ticket in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=805393) – JaffaTheCake Oct 25 '12 at 11:58

8 Answers8

54

For Firefox you can add -moz-transform: scale(.9999); to make smooth edges. In your case:

.triangle {
    width: 0;
    height: 0;
    border-top: 0;
    border-bottom: 30px solid #666699;
    border-left: 20px solid transparent; 
    border-right: 20px solid transparent;
    -moz-transform: scale(.9999);
}

Will do the trick.

Caner Şahin
  • 568
  • 1
  • 4
  • 6
  • 2
    This works but on my computer anyway it made the lines look "too smooth", ie a bit blurry as compared to the rotate(0.01deg) method – Erin Drummond Sep 28 '14 at 02:06
  • 2
    @ErinDrummond which browser and version you have tried with? My answer will only work with Firefox though as I implied. I have checked rotate(0.01) with Firefox (32.0.3) for Mac and it didn't get me a smooth line. – Caner Şahin Sep 29 '14 at 13:03
  • @CanerŞahin I was using Firefox 32.something on Linux (Fedora 20). The jagged edge problem doesn't even occur at all for me on Firefox for Mac (32.0.3), no workarounds required – Erin Drummond Sep 29 '14 at 19:30
  • Firefox has no problem, it's Chrome which has. – vsync Dec 16 '14 at 19:04
  • 1
    For me on FF36, I still get rough edges. Using `-moz-transform: scale(.9999);` does work for me. – TheCarver Mar 03 '15 at 15:31
  • I was digging this for Chrome (41.0.2272.118 m says `about`). Diagonal lines (from borders) were jagged, scale and rotate does the magic, yet, it's true that rotate makes a best result - clear non blurry and non jagged lines – Max Yari Apr 11 '15 at 23:32
29

I have just stumbled upon the same problem, and figured out this trick (at least, it works on a Mac):

-webkit-transform: rotate(0.05deg);
-moz-transform: scale(1.1);
-o-transform: rotate(0.05deg); /* Didn't check Opera yet */
transform: rotate(0.05deg);
unclenorton
  • 1,605
  • 11
  • 19
  • 1
    I've added only `-webkit-transform: rotate(0.01deg);` to my CSS and that works perfectly for both Webkit on Windows and Mac (Chrome on Win, Safari on OSX) Other browsers (at least on Windows) shows the triangle perfectly smoothed, except Opera. Didn't fixed that one yet... – trizz Aug 01 '12 at 09:02
  • 21
    I'd suggest doing a 360deg rotate so that the triangle is in the same position `transform: rotate(360deg);` – JohnC Oct 01 '12 at 08:13
  • 2
    Doing rotate(360deg) as suggested by @JohnC doesnt work precisely because it puts the triangle in the same position - rotating by 0.01deg shifts it slightly enough to have antialiasing applied but not enough for a human to be able to tell its been rotated – Erin Drummond Sep 27 '14 at 23:36
  • 1
    My issue was with Chrome (40) Firefox was fine this fixed did it for me and good suggestion to use 360 deg, thanks all – Gurnard Mar 12 '15 at 09:41
19

Even in pure CSS we can get the smooth diagonals.

.triangle {
    width: 0;
    height: 0;
    border-top: 0;
    border-bottom: 30px solid #666699;
    border-left: 20px solid rgba(255, 255, 255, 0); 
    border-right: 20px solid rgba(255, 255, 255, 0);
}

Instead of giving transparent you can make use of rgba(255, 255, 255, 0). This again gives transparent. But the alpha=0 makes smooth diagonals.

Check the browser support for rgba css-tricks.com/rgba-browser-support

Thanks

iamjustcoder
  • 4,714
  • 10
  • 33
  • 46
13

Using border style inset for transparent borders gives much better results in Firefox:

border-top: 22px solid $pink;
border-right: 84px inset transparent;
border-left: 84px inset transparent;
kcmr
  • 313
  • 3
  • 8
3

What really helped me when first stumbling over this was to scale a uniform triangle by a certain amount. Firefox seems to be particularly 'edgy' with scalene triangles. Interesting though, perfect triangles get rendered without jagged edges. If CSS transforms are possible in your project, just try:

.triangle {
  width: 0;
  height: 0;
  border-top: 0;
  border-bottom: 20px solid #666699;
  border-left: 20px solid transparent; 
  border-right: 20px solid transparent;
  -moz-transform: scaleY(1.5); // optional: replace with Sass/SCSS/LESS mixin
  -moz-transform-origin: top; // optional: replace with mixin, too
}

This fixed the aliasing across the edge for me. JSFiddle here (Mozilla only right now). Hope this helps!

1

For me, using dashed for the transparent borders worked for most browsers that don't automatically smooth them and rotating 360 degrees worked for old Webkit:

.triangle {
    width: 0;
    height: 0;
    border-top: 0;
    border-bottom: 30px solid #666699;
    border-left: 20px dashed transparent; 
    border-right: 20px dashed transparent;
    -webkit-transform: rotate(360deg);
}
tobymackenzie
  • 818
  • 6
  • 12
1

A very hacky way would be using a rotated div

Here I used two divs to show a triangle:

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

and rotated the inner div for two not right sides of triangle:

.triangle{
    position:relative;
    width:100px;
    height:60px;
    border-bottom:1px solid black;
    border-radius:12px;
}
.rot{
    border-radius:10px;
    border-left: 1px solid black;
border-top: 1px solid black;
width:70px; height:70px;
    -webkit-transform:rotate(45deg);
    position:absolute;
    left:15px;
    top:23px;
}

I didn't tried to find the relation between numbers.

Here is the fiddle of the code:

http://jsfiddle.net/mohsen/HTMcF/

BUT I would strongly suggest you to use canvas element for this reason.

Mohsen
  • 64,437
  • 34
  • 159
  • 186
0

None of the others worked for me, but I found the following did (by accident):

.triangle {
  border: 1.3rem dashed #666699;
  border-right: .5rem solid rgba(255, 255, 255, 0);
}

The mixture of dashed/solid and the rgba fix worked in FF31, IE11, and Chrome36.

Don
  • 25
  • 3