Grow your CSS skills. Land your dream job.

Last updated on:

CSS Triangle

HTML

You can make them with a single div. It's nice to have classes for each direction possibility.

<div class="arrow-up"></div>
<div class="arrow-down"></div>
<div class="arrow-left"></div>
<div class="arrow-right"></div>

CSS

The idea is a box with zero width and height. The actual width and height of the arrow is determined by the width of the border. In an up arrow, for example, the bottom border is colored while the left and right are transparent, which forms the triangle.

.arrow-up {
	width: 0; 
	height: 0; 
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	
	border-bottom: 5px solid black;
}

.arrow-down {
	width: 0; 
	height: 0; 
	border-left: 20px solid transparent;
	border-right: 20px solid transparent;
	
	border-top: 20px solid #f00;
}

.arrow-right {
	width: 0; 
	height: 0; 
	border-top: 60px solid transparent;
	border-bottom: 60px solid transparent;
	
	border-left: 60px solid green;
}

.arrow-left {
	width: 0; 
	height: 0; 
	border-top: 10px solid transparent;
	border-bottom: 10px solid transparent; 
	
	border-right:10px solid blue; 
}

Examples

Dave Everitt writes in:

For an equilateral triangle it's worth pointing out that the height is 86.6% of the width so (border-left-width + border-right-width) * 0.866% = border-bottom-width

Comments

  1. Trippy! I can’t get my head around it!

  2. TeMc
    Permalink to comment#

    It’s basicly like a giant 3D border-corner. (when the left and top border-color are different the edge is diagonal, that’s being used to make this triangle).

    • Thanks, TeMc, now it all makes sense.

      By the way, it’s fun to play with the inner div’s right border width, and change the shape and size of the triangle!

    • Santosh
      Permalink to comment#

      thanks for making it clear.. thanks even to admin to share a lovely tricks :) am very greatful to this website.. :)

    • Thanks for the reminder! It hass been so long since I’ve noticed how different border colors act together (think table cells).

  3. Permalink to comment#

    Clever. I like seeing CSS doing things it shouldn’t

  4. Can you turn it?

    • Jack Jackson
      Permalink to comment#

      Yep:

      <code>-moz-transform: rotate(1deg);
      -o-transform: rotate(1deg);
      -webkit-transform: rotate(1deg);
      transform: rotate(1deg);</code>
      

      Obviously, replace the “1” with whatever you want!

  5. 40a
    Permalink to comment#
    div {
       height:0px;
       width:0px;
       border-top:100px dashed transparent;
       border-right:100px solid #955;
    }

    http://www.cssplay.co.uk/menu/flag

  6. Permalink to comment#

    Anyone know why this looks like crap in webkit?

    http://img825.imageshack.us/img825/3002/screenshot20100830at827.png

    • Maybe webkit can’t draw it the right way?

    • Permalink to comment#

      If the dimensions of the triangle aren’t symmetrical, you tend to get those jagged lines. It appears to be more noticeable in Webkit, for some reason–not sure why.

    • You may have figured this out, but here goes anyway:

      For webkit, to get the lines smooth, add the following rule:

      transform: rotate(360deg);

      Play with different deg depending on your arrow’s direction.

    • bob20-2012
      Permalink to comment#

      try adding “box-shadow: 0 0 2px orange;” to the triangle. it might help. if not reducing the “2px” in it or incressing will change the blur strangth of the shadow.

  7. Permalink to comment#

    Like it. Thanks.

  8. davyne
    Permalink to comment#

    Cool trick, I tried it first after seeing it elsewhere.
    Then I came across the ivy-leaf trick on this website, and if you want the triangle to scale with the text, change the ivy leaf to a triangle.

    down: \25bc
    up: \25b2
    right: \25b6

    I couldn’t find a “map”, but if you play around changing the last 4 digits in the url, you can find all kinds of cool stuff.

    http://www.decodeunicode.org/en/u+25bc

  9. Micky
    Permalink to comment#

    Haha, funny trick.

  10. This is amazing!! Thanks for sharing..

  11. Justin
    Permalink to comment#

    Thanks,

    This is just want I was looking for :)

  12. Soony
    Permalink to comment#

    Now perfect in IE

  13. You can use those triangles to create Real-time 3D objects in IE6. Yes, IE6!

    http://www.uselesspickles.com/triangles/

    Borders can also build a house:

    http://www.designdetector.com/tips/3DBorderDemo2.html

  14. Ted
    Permalink to comment#

    I noticed a small issue with this technique in Firefox 5.0 (Win). FF 5.0 renders a light stroke on the front sides of the triangle. Here’s a link to a jsFiddle that replicates the issue:

    http://jsfiddle.net/brightlight/4DmFk/

    Obviously, you’ll need to view that in FF 5.0 (Win) to see what I’m talking about.

    • Ted
      Permalink to comment#

      Update: Changing the border style to “inset” on the transparent sides of the element seems to fix this issue in Firefox 5 and 6. Other browsers continue to render the triangles fine even after this border-style adjustment.

    • Matt Ruby
      Permalink to comment#

      Thanks for the inset tip! I’ve been trying to eliminate that thin stroke for a day!!

    • great tutorial.
      @ted: great tip on the “inset”. Was working my mind through the reason for the strange micro-border!

  15. Christo
    Permalink to comment#

    In scenarios like below I get pixelation in Safari, IE and some yet less in FF. Is anyone else getting this ?


    .point_bottom {
    border-left: 200px solid transparent;
    border-right: 200px solid transparent;
    border-top: 80px solid #FF0000;
    bottom: 0;
    height: 0;
    left: -101px;
    position: absolute;
    width: 0;
    }

    • Permalink to comment#

      If the triangle is not symmetrical, it won’t look smooth. Basically, it’s like trying to draw a straight line at a 30-degree angle in a bitmap image. The line will always look a little jagged.

      This trick is just an exploitation of CSS behavior–I don’t believe CSS was intended to do this sort of thing. If you want truly straight lines at whatever angle, you might want to explore SVG.

    • This worked for me to smooth things out: http://stackoverflow.com/a/9945375

  16. Damir
    Permalink to comment#

    Now how about a nice way to add a drop shadow to the triangle? Would be so awesome…

    • Permalink to comment#

      You do some limited drop shadows using a pseudo-element. Just position it a little different than the original triangle shape and then change the color and/or transparency. A little rotation looks nice with this effect, too. I saw it in a NetTuts piece recently.

  17. Permalink to comment#

    Is it possible to use this on a [submit] button?
    so the end result would look like this https://skitch.com/iestynx/fa6et/artwork

    I’m a bit new to this so sorry if it’s a stupid question.

    Thanks

  18. Permalink to comment#

    The problem that some people have been reporting with inaccurate edges is to do with antialiasing and the fact that transparent is equivalent to rgba(0, 0, 0, 0)—transparent black. When combined with antialiasing, this produces a result which is not what the author intended. I am not aware whether any browsers used antialiasing back in mid-2009, but now, Firefox distinctly does.

    I am in the process of writing a blog post (as part of starting a blog, which makes it take longer…) dealing with this particular subject with full details, explanations, the caveats, et cetera, and I initially planned on waiting till I had that done before posting this. But as it’s been several weeks since I began to plan it and will probably be at least as many more until it’s ready and posted, I figured I should try to stop people using transparent when they don’t mean it before it’s too too late.

    My general recommendation is to avoid using transparent unless you know that it’s suitable (i.e. black is the touching colour). If you have to care about browsers that don’t support rgba() values (IE8 and earlier), then specify it as transparent and add a border-left/right/top/bottom-color value after it with the correct rgba value to override it and make it correct.

    • I was just playing around with the antialiasing issue and found that if I set the border widths to make the triangle symmetrical and then do a scale transform to the triangle to stretch it to the right dimensions, it forces the browser to antialias the edges and gets rid of the jaggedness.

    • The transform trick works a treat in webkit!

      Unfortunately for me it introduces issues in Firefox. There’s now a vertical split down the middle of the triangle whenever I scale it up or down…

      http://jsfiddle.net/bensmithett/fEjJ3/

  19. Saurabh
    Permalink to comment#

    Hi,
    Triangle design problem in ie9

    • Tom
      Permalink to comment#

      I’ve noticed a problem in IE9 if you use this to style a button as an arrow. If you define a style for all 4 borders, it will show them all (even if they’re transparent). Since you’ll want to reset all of the borders to avoid the default button style, this causes a problem. It also does some funny stuff with the sizes, so even if you only define the 3 sides you need, it doesn’t look right.

      So far, the best I’ve found for a workaround is to use a <a> (or a div) instead, even though it’s less semantic.

  20. Hi Chris, I watched your video on vimeo and you went a mile a minute. I have a love to be able to create angled nav tabs with variable widths for text. I have been attempting to modify a PVII menu set, but have encountered a problem that I’m not sure arrows can solve due to the width of the borders. I can only show you by example the fixed width image based version of the project I’m trying to duplicate in CSS:

    http://heavy-construction.us/

    Notice the yellow line border on rollover. Now here is the project so far: http://heavy-construction.us/test.html. Using the arrows let me create an angled tab, but the hover loses the yellow border. Right now I’m using a background repeating image gradient for each state of the nav buttons, and I could replace it with a CSS3 gradient fill, but I don’t think anything I’ve seen can create the narrow yellow 45 degree border, unless perhaps 2 triangles overlapping?

    • Gotten a little further using gradient buttons:

      http://heavy-construction.us/test3.html

      This is based on the Spry Widget for menus in DW, but for some reason it doesn’t start the gradient at the full left of the menu tab.
      And I’ve not been able to figure out how to at the yellow 45degree border to the hover.

    • Yuzer
      Permalink to comment#

      Hey Jeff can you please share the video link? I also saw that video but just lost the link.

  21. Wow, it’s very nice tutorial..

    Thank u so much…

  22. Well, I got it working using a yellow flag instead of an outline edge:

    http://heavy-construction.us

  23. shrey
    Permalink to comment#

    good tutorial, your website is great.

  24. soundarapandian
    Permalink to comment#

    This is amazing :)

  25. Thanks the tutorial! I used this with em sizing to make it work dynamically – check it out!

    http://thinkcloud.ly/snippets/tooltips.html

  26. wendee
    Permalink to comment#

    An interesting thing I am noticing in Chrome is that when all arrows are set to the same size, the .arrow-right is 2px taller than the other arrows .

  27. Lee
    Permalink to comment#

    how do you get the text to line up next to the arrow? Thanks!

    • Daniel
      Permalink to comment#

      line-height: 0 will vertically center the text, and you should apply a padding so the text doesn’t bleed over the arrow.

  28. Vincent Verbrugh
    Permalink to comment#

    This is brilliant! Thanks

  29. tambo
    Permalink to comment#

    div{
    height: 0px;
    width: 0px;
    }

    div.left-arrow {
    border: 20px solid #fff;
    border-right: 20px solid #abc;
    border-left:none;
    }

    div.right-arrow {
    border: 20px solid #fff;
    border-left: 20px solid #abc;
    }

    div.down-arrow {
    border: 20px solid #fff;
    border-top: 20px solid #abc;
    border-bottom:none;
    }

    div.up-arrow {
    border: 20px solid #fff;
    border-bottom: 20px solid #abc;
    border-top:none;
    }

    from: http://kougiland.com/css-triangle.html

  30. Permalink to comment#

    Hey guys! I just made a simple generator:
    http://apps.eky.hk/css-triangle-generator

  31. Permalink to comment#

    Thanks for a great tutorial!

    Question: is it possible to assign more than one of these “triangles” to an element? I’m thinking of creating star shapes by assigning multiple border-based triangles to a square div. Will that work or does the :after pseudo-class preclude that?

  32. Umesh
    Permalink to comment#

    How to give auto width ? its taking width of its parent div. I tried all types e.g auto… Is there another trick?

  33. Hello Chris, I must say I really enjoyed the post, even I managed to get it working. Will be sharing this, cheers!

  34. Dude, the buggy Fire Fox is putting a gray border :( didn’t working even using before and after

    Tried with white color!
    .arrow-right {
    width: 0;
    height: 0;
    border-top: 60px solid transparent;
    border-bottom: 60px solid transparent;
    border-left: 60px solid #FFF;
    }

    • Matt Ruby
      Permalink to comment#

      See Ted’s comment above re: inset borders
      That should fix you right up.

  35. file-monger
    Permalink to comment#

    Looks great. I am a total newbie to Css at this level. I need to take a fast track to showing a callout with a triangle pointing down or to the left depending on which type of control I assign it to. How do I put this use of triangles together with a rectangulat or rounded-rectangular callout box?
    Thanks in advance,
    file-monger

  36. Dan
    Permalink to comment#

    if you want to improve how the triangles get rendered on chrome/safari add

    -webkit-transform:rotate(360deg);

  37. Thanks, this is exactly what I was looking for, works great.

    One minor bug I wanted to mention: in the css example it doesn’t list “display: block” as a required def – in the demo this is inherited, but without the proper display setting the arrow gets cut off.

    I would recommend adding “display: block” to the css example.

    • Permalink to comment#

      The arrows on your site are not CSS triangular but image. Did you mean that you want to replace these graphic triangular with CSS triangular?

  38. Yess,, it so Cool.. i can make triangle.. what ever i want..

  39. Roger
    Permalink to comment#

    Cool and easy! I wonder how to add an arroy to a window which has a border color black and background white and you want your arrow follows same background and border. Like google+

  40. Permalink to comment#

    really like this trick!

    unfortunately, your facebook recommend button doesn’t work mate.

    any particular reason for setting overflow:hidden in “.end-of-article-stuff “?

  41. Justme

    Uh, this is a departure from the above discussion, but if anyone knows how to do it…

    I am looking to create a floating triangle that points northeast, to be placed in the upper corner of the right column of a 3-column page (right and left columns narrow, and of equal width), such that as one scrolls down the page, the contents of the RH column disappears under the floating (always on top) triangle.

    Here is the idea in practice (eky’s Triangle Generator (Top Right) may do the trick, I haven’t tried it yet):

    http://www.1001cocktails.com/

    Thanks,
    Justme

  42. DevDan

    CSS Arrows! (overlapping triangles)

    .arrow-right {
    width:0px;
    height:0px;
    border-bottom:9px solid transparent;
    border-top:9px solid transparent;
    border-left:9px solid #2f2f2f;
    font-size:0px;
    line-height:0px;
    position: absolute;
    z-index: 1;
    top: 0;
    left: 0;
    overflow:auto;
    }

    .smaller-arrow-right {
    width:0px;
    height:0px;
    border-bottom:4px solid transparent;
    border-top:4px solid transparent;
    border-left:4px solid #fff;
    font-size:0px;
    line-height:0px;
    position: absolute;
    z-index: 2;
    top: 5px;
    left: 0;
    }

  43. Roger

    check this page. Add borders to our arrow. http://cssarrowplease.com/

  44. piotrsitarek

    That’s what I was looking for. Very nice!

  45. I totally consent with your ideas. We all obtain a benefit from this fantastic posting. This website is excellent. I have discovered a great deal of things from here. Many thanks.

  46. Have to big you up on your idea bro, well done!

  47. Cool, thanks for the tips! I used this method instead of images for my new website, http://www.doodlingpandas.com .

  48. Permalink to comment#

    The above comment from
    wendee
    12/16/2011

    Is a very valid concern. I seem to be having this problem and the examples I have seen all reproduce the issue. In chrome the left arrow is 2px smaller that the right facing arrow. ONLY chrome! I cannot fix this. So anytime the arrows are used close together and small – the difference is very noticeable. This is a huge problem for sites that want to be image and sprite free but must be cross browser compatible. Oh woe is me!!!

    When I apply the fix from Dan :

    -webkit-transform:rotate(360deg);

    It smoothes the edges making the issue less noticeable in large examples but leaves the smaller ones still looking too different.

    Anyone have more insight? It appears to me to be a bug in chrome.

    Don

  49. Awesome, Chris! This definitely beats a cumbersome SVG tag.

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <polygon points="0,0 12,0 6,8" fill="#000000" fill-opacity="0.5">
    </svg>
  50. Sebastian
    Permalink to comment#

    Arrow with Border:

    CSS:

    
    .arrow-border {
    width: 0; 
    height: 0; 
    border-top: 15px solid transparent;
    border-bottom: 15px solid transparent; 
    border-right:16px solid #7F7F7F; 
    }
    			
    .arrow {
    width:0;
    height:0;
    border-top:9px solid transparent;
    border-bottom:9px solid transparent;
    border-right:9px solid #A6A6A6;
    position:relative;
    bottom:9px;
    left:4px;
    }
    

    HTML Snippet:

    
    <div class="arrow-border">		
    <div class="arrow"></div>	
    </div>
    
    
  51. Hi, I have been updating my website and have been trying to change the arrows. Right now my arrows are coded using javascript but the rest of my website is coded with HTML AND CSS. When I put in the code Otto posted, it worked and the arrows show up but I am trying to figure out how to get the arrows to click to the next picture as well as being able to click the thumbnails. Can anyone help with that? I also want the arrows on the middle of both sides of the picture rather than on the bottom.

    Please help! Thanks in advance! :)

    -Angela

  52. Amit

    Was giving that here a try locally and it looks great

    The issue I have is that I have a span inside the container (which is an h3) and I guess because of the width being 0 I can’t manage to get the text to appear inside the triangle look :

    
    
    /*-------------Featured Products on Home Page-------------*/
    
    ul.featured-products li {
    	margin-left: 1em;
    	
    }
    /*-------------My triangle h3-------------*/
    
    ul.featured-products li h3 {
    	width: 0 !important; 
    	height: 0; 
    	border-left: 80px solid transparent;
    	border-right: 80px solid transparent;
    	border-top: 80px solid rgba(184, 62, 14, 1);
    	border-bottom: 0.382em solid rgba(218, 96, 48, 0) !important;
    	background: rgba(218, 96, 48, 0) !important;
    	bottom: 150px !important;
    	left: -50px !important;
    	padding: 0 !important;
    	transform:rotate(135deg);
    	-ms-transform:rotate(135deg); /* IE 9 */
    	-moz-transform:rotate(135deg); /* Firefox */
    	-webkit-transform:rotate(135deg); /* Safari and Chrome */
    	-o-transform:rotate(135deg); /* Opera */
    }
    
    /*-------------A nice Icon - but can't seem to be able to insert into triange-------------*/
    
    ul.featured-products li h3:after {
    	font-family: HeydingsIconsRegular;
    	font-size: 2em;
    	text-shadow: 1px 1px 1px #000, 3px 3px 5px #777;
    	color: #FFF;
    	vertical-align: baseline;
    	margin-right: 0.5em;
        content:'t';
    }
    /*-------------Text should go here-------------*/
    
    ul.featured-products li h3 .price {
    	
    	
    }
    

    Cheers,
    Amit

  53. Is it possible to give shadow to the arrows?

    • Waqas K.

      No because there is no height and width. it is only border trick. If you want shadow create photoshop PNG

  54. Matt
    Permalink to comment#

    Hi,
    Playing around with this technique and wondering if anybody can help.. see this jsbin:

    http://jsbin.com/uviyat/2/edit

    Notice ‘Longer Wording Example’ – how can I get the triangle to scale vertically to dynamically fill the selected blue area height ? (the triangle in generated in the last css rule)..

    I’m stumped! Anybody got any ideas?
    Thanks in advance

  55. Permalink to comment#

    Very nice trick and exactly what I was looking for.
    I used a non isosceles triangle which works great with the rotate-webkit-fix from Dan.
    In IE8 it looks a bit crappy but I can live with this.

    Thank you so much and keep up the good work.

  56. Permalink to comment#

    Anyone know of a fix for IE8’s jagged rendering? -ms-transform: rotate(360deg); doesn’t seem to play nice with IE8.

  57. M
    Permalink to comment#

    Hi there!

    I like that solution!
    Unfortunately I have to do an arrow with border… Has anyone a nice solution for me? :/

    Thank you! ^^

    • HoofedCracker
      Permalink to comment#

      Hey Mate.

      Thanks to @Matts link, I was able to put something together : )

      Its very basic, but gets the job done.

      It works best in Mozilla Firefox.

      /* begin css */

      body
      {
      margin-top: 100px;
      }

      .container
      {
      width:100%;
      }

      .trifront
      {
      position:absolute; right:5px; top:-195px;
      width: 0;
      height: 0;
      border-top: 195px solid transparent;
      border-bottom: 195px solid transparent;
      border-left: 195px solid #FFFF66;
      }

      .triback
      {
      position:absolute; left:64%;
      width: 0;
      height: 0;
      border-top: 205px solid transparent;
      border-bottom: 205px solid transparent;
      border-left: 205px solid #000000;
      z-index:-1;
      }

      .rectangle
      {
      position:absolute; top: 28%; left:1%; width:63%; height:14%; background-color:#FFFF66;
      text-align:center; border-style:solid; border-width: 5px;border-right:0px;
      }

      /* end css */

      Just add a reference to the css in your HTML code, and apply div tags accordingly.

      I hope I have been of some assistance, or at least got you on the right track!!

      Good luck mate!

      Let me know what what you think : )

      HoofedCracker

  58. HoofedCracker
    Permalink to comment#

    Hey mate!

    I had no such luck with that exact situation going on about a week or two ago now!

    I believe when you edit the border element for the triangle, it defeats the purpose; as it changes the shape, position and size of the arrow head. The transparent element of the solid border is very important; so I don’t really see a way to amend the border to suit the situation.

    I had to just use a good contrast- with a strong fill colour for the arrow, to give that bold effect.

    I know this is no solution, just thought I’d let you know how I simply over came this, by amending my original proposed layout.

    Let me know if you find a solution!

    (Feel free to correct me if I am wrong with any of the above statements)

    HoofedCracker

  59. Matt
    Permalink to comment#

    @M
    @HoofedCracker

    I came across a way to do this using :before and :after, essentially creating another triangle behind the front one that is slightly larger so looks like a border.. I used it to create a tooltip like this sort of thing:

    http://jsbin.com/oturaf/1/edit

    • HoofedCracker
      Permalink to comment#

      Choice!

      That sounds very promising!

      Trying to wrap my head around it.

      Do you believe it’d be possible to implement that to a complete triangle shape , rather than a box with a triangle pointer?

      i.e. (The original Triangle; as illustrated above)

      .arrow-right {
      width: 0;
      height: 0;
      border-top: 60px solid transparent;
      border-bottom: 60px solid transparent;

      border-left: 60px solid green;
      }

      Very curious to how this would look : )

      Cheers,

      HoofedCracker

  60. jitender
    Permalink to comment#

    Nice example but it wont work on quirks mode in ie

  61. Hi.. Nice explanation. I have wrote something similar about [how to create CSS triangle](http://webdesigninspirationtoday.com/article/133/how-to-create-css-triangle-caret/). There I explained the basic theory using CSS border to give everyone better understanding, how the CSS triangle produced.

  62. Chris,

    Below is a question on StackOverflow that touches on this topic and provides a robust example of a good real-world use case:

    http://stackoverflow.com/questions/12499673/css-items-with-border-radius-and-triangle-side

  63. Ibro
    Permalink to comment#

    I don’t seem to get where to place the code in blogger template, please help

  64. Permalink to comment#

    Hello,

    Is it possible to have drop shadow in triangle?

    i tried to use box shadow and the effect goes around the box and not the triangle .

    thx in advance.

  65. Permalink to comment#

    I know about this tut but its not what i want.

    take a look at this that i made. i hope you like it :D

    http://jsfiddle.net/adoumas/tNXdp/

  66. No need to use four DIVs to create a triangle with CSS.

    Based on 40a‘s and Web Design Inspiration Today‘s examples above, I created this CodePen demo with several other options for ‘rotating’ the triangle: http://codepen.io/rzea/pen/feiLs

  67. I thought this was pretty cool, and I was surprised no one posted it already!

    .css-arrow(@color: @gray, @size: 25px) {
        width: 0;
        height: 0;
            &.up {
            border-left: @size solid transparent;
            border-right: @size solid transparent;
            border-bottom: @size solid @color;
            }
            &.down {
            border-left: @size solid transparent;
            border-right: @size solid transparent;
            border-top: @size solid @color;
            }
            &.left {
            border-bottom: @size solid transparent;
            border-right: @size solid transparent;
            border-top: @size solid @color;
            }
            &.right {
            border-left: @size solid transparent;
            border-bottom: @size solid transparent;
            border-top: @size solid @color;
            }
    }
    
  68. Permalink to comment#

    Nice. Works like a charme :-)

  69. I thought this was cool as well, refactored a bit from my other post.

    LESS:

    .arrow {
        width: 0;
        height: 0;
    }
    
    .css-arrow(@direction, @side_one, @side_two, @main_size: 100, @color) when (@direction = down) {
      (~".arrow.dir-@{direction}.size-@{main_size}") {
        border-left: @side_one solid transparent;
        border-right: @side_two solid transparent;
        border-top: @main_size solid @color;
      }
    }
    
    .css-arrow(@direction, @side_one, @side_two, @main_size: 100, @color) when (@direction = up) {
      (~".arrow.dir-@{direction}.size-@{main_size}") {
        border-left: @side_one solid transparent;
        border-right: @side_two solid transparent;
        border-bottom: @main_size solid @color;
      }
    }
    
    .css-arrow(@direction, @side_one, @side_two, @main_size: 100, @color) when (@direction = left) {
      (~".arrow.dir-@{direction}.size-@{main_size}") {
        border-top: @side_one solid transparent;
        border-bottom: @side_two solid transparent;
        border-right: @main_size solid @color;
      }
    }
    
    .css-arrow(@direction, @side_one, @side_two, @main_size: 100, @color) when (@direction = right) {
      (~".arrow.dir-@{direction}.size-@{main_size}") {
        border-top: @side_one solid transparent;
        border-bottom: @side_two solid transparent;
        border-left: @main_size solid @color;
      }
    }
    
    .css-arrow(down, 60px, 60px, 100px, @green);
    .css-arrow(up, 60px, 60px, 100px, @green);
    .css-arrow(left, 60px, 60px, 100px, @green);
    .css-arrow(right, 60px, 60px, 100px, @green);
    

    Outputs this:

    CSS:

    .arrow {
      width: 0;
      height: 0;
    }
    .arrow.dir-down.size-100 {
      border-left: 60px solid transparent;
      border-right: 60px solid transparent;
      border-top: 100px solid #8da1ae;
    }
    .arrow.dir-up.size-100 {
      border-left: 60px solid transparent;
      border-right: 60px solid transparent;
      border-bottom: 100px solid #8da1ae;
    }
    .arrow.dir-left.size-100 {
      border-top: 60px solid transparent;
      border-bottom: 60px solid transparent;
      border-right: 100px solid #8da1ae;
    }
    .arrow.dir-right.size-100 {
      border-top: 60px solid transparent;
      border-bottom: 60px solid transparent;
      border-left: 100px solid #8da1ae;
    }
    
  70. Mohit Srivastava
    Permalink to comment#

    I looked up on making straight double headed arrows using pure css but didn’t find anything, so I did a little tweaking of the given snippet myself and Volla ! Here it is… (In making these, I really got a hold of pseudo elements and how they work(:before and :after))
    Change the degrees to ’90’ in rotate class to make the arrow horizontal or tilt it to any angle you want to.

    Try pasting this in JSFiddle and see for yourself :)

    The HTML :

    <div class="arrow"></div>
    <div class="arrow rotate"></div>
    

    The CSS:

    .arrow {
    height:100px;      /*length of Arrow*/
    width:5px;
    background-color:black;
    margin-top:50px;
    margin-left:50px;
    position: relative;
    }
    
    .arrow:before {
    content:"";
    position: absolute;
    left:-6px;
    top:-8px;
    border-color: black transparent;
    border-style: solid;
    border-width: 0px 8px 8px 8px;
    height: 0px;
    width: 0px;
    }
    
    .arrow:after {
    content:"";
    position: absolute;
    left:-6px;
    top:100%;
    border-color: black transparent;
    border-style: solid;
    border-width: 8px 8px 0px 8px;
    height: 0px;
    width: 0px;
    }
    
    .rotate {
    transform:rotate(40deg);     /*change the degrees to anything*/
    -ms-transform:rotate(40deg); /* IE 9 */
    -moz-transform:rotate(40deg); /* Firefox */
    -webkit-transform:rotate(40deg); /* Safari and Chrome */
    -o-transform:rotate(40deg); /* Opera */
    }
    
  71. Roy
    Permalink to comment#

    could anyone please tell me how do i give the triangles a thick black border.

  72. Faudzif
    Permalink to comment#

    Thanks Ted; you’re technique is perfectly remove stroke from firefox.

  73. Anu
    Permalink to comment#

    Thanks all. Me too have a basic tool at http://www.careerbless.com/services/css/csstooltipcreator.php – Can be used in line with the techniques u suggested. Please share your thoughts on the same.

  74. Vedant
    Permalink to comment#

    This Isn’t Works In IE 8.

    Means: Accurate Arrow Point Doesn’t comes up in IE 8 With Same Code.

    • Permalink to comment#

      Thanks God I’ve found it :

      Just Add

      line-height:0px;
      

      in your css to make it work in IE 8.
      Here is all Code :

      .left-arrow{
      width:0px;
      height:0px;
      border-top: 30px solid transparent;
      border-bottom: 30px solid transparent;
      border-right:  30px solid #f00;
      line-height:0px;
      z-index:1;
      }
      
  75. Permalink to comment#

    This One is Also Useful !

  76. Rron
    Permalink to comment#

    What about if I wanted to ad text inside the triangle is that possible?
    I have tried it but the text breaks after each word and im assuming this is because the div has 0 hight and width so if any1 has a solution please let me know :)

  77. nice trick :)

  78. Tamm
    Permalink to comment#

    Great tip!
    Wondering if there is a way to duplicate the arrow in a straight row for as long as the browsers width is?

  79. Alejandro Next
    Permalink to comment#

    Here I have a better development in Less (CSS) to do that sort of thing

    https://gist.github.com/alejonext/5131863

  80. Viko
    Permalink to comment#

    this is arrow is nice. do you have any tutorial making games using javascript ? thanks :)

  81. Permalink to comment#

    Its also worth nothing how to add a triangle/arrow to a element without any extra mark-up.
    .add-on { position: relative {
    .add-on:after {
    border-bottom: 4px solid transparent;
    border-left: 4px solid #EDEDED;
    border-top: 4px solid transparent;
    content: " ";
    height: 0;
    left: 0;
    margin-top: -4px;
    position: absolute;
    top: 50%;
    width: 0;
    }

  82. I can’t seem to find a solution to my problem, I wanted to have a dynamic height triangle for my responsive divs.

  83. Luís
    Permalink to comment#

    I came across a “caret”, but could not replicate it in my code. After much poking around I found the original code in the CSS where the code worked, but I did not understand the logic. I did a search on Google and landed on your site. Great explanation.

  84. Is it possible to add rounded corners to the triangle?

  85. Mark Pickering

    Excellent trick! For those who haven’t already thought of it you can place a slightly smaller triangle inside of your first one to create a nice little arrow. By positioning with negative margins (or similar) it’s easy to create a Speech Bubble look to your main

    <

    div>

  86. Thank you for this! The only problem comes when you want to put a border on the triangle.

  87. This is great, thanks a lot. I just took so long to find your post. Django, to put a border on the triangle, you should add one more outer div that will have border width a little larger than the original triangle’s border width with the color of your choice. Let me know if that works.

  88. Vinicius Pires
    Permalink to comment#

    Awesome! Thanks!

  89. Hasan
    Permalink to comment#

    just simply to say thanks!

  90. Excellent post, many thanks for sharing.

    This has saved me from using transform: rotateZ(45deg); which didn’t work particularly well on iOS 6 / Safari.

  91. Praveen Jegan
    Permalink to comment#

    Nice one. Yet a problem. Is there a way to apply** border for the border**?

    Hope you can understand what I am trying to acheive.

  92. Jason
    Permalink to comment#

    Was looking for something like this to save messing about with images. for pointers and such. Definitely going in the toolbox.

  93. Amit
    Permalink to comment#

    i want arrow with a 1 px of border around it , is it possible?
    plz Help.

  94. Arif
    Permalink to comment#

    Hello, i need border also for triangle. Here my codes.

    http://jsfiddle.net/e62b3/

  95. Craig Wayne
    Permalink to comment#

    I have a fairly simpler solution,

  96. Ammad
    Permalink to comment#

    can we make write able triangle I cant write in the triangle when i write it

  97. Permalink to comment#

    I created responsive CSS-only triangles using one div: Pure CSS responsive triangles. It takes advantage of padding being calculated against parent’s width to cover a big fixed-width triangle. For an up-pointing triangle and 100% width:

    .triangle-up {
        width: 50%;
        height: 0;
        padding-left:50%;
        padding-bottom: 50%;
        overflow: hidden;
    }
    .triangle-up div {
        width: 0;
        height: 0;
        margin-left:-500px;
        border-left: 500px solid transparent;
        border-right: 500px solid transparent;
        border-bottom: 500px solid green;
    }
    
  98. Permalink to comment#

    Last one was using two divs. For a one-div responsive up-pointing triangle 100% width using a pseudo-element:

    .triangle-up {
        width: 50%;
        height: 0;    
        padding-left:50%;
        padding-bottom: 50%;
        overflow: hidden;
    }
    .triangle-up:after {
        content: "";
        display: block;
        width: 0;
        height: 0;
        margin-left:-500px;
        border-left: 500px solid transparent;
        border-right: 500px solid transparent;
        border-bottom: 500px solid #959595;
    }
    

    For the full explanation on how to change the triangle proportions and down, left and right pointing triangle snippets see Pure CSS responsive triangles. This CSS assumes box-sizing:content-box.

  99. Henry
    Permalink to comment#

    Created this small visualization to explain how do borders turn into triangles : http://codepen.io/Tresva/pen/dxHsb. This may help to understand quicker.

  100. sulaman
    Permalink to comment#

    For more on css3, can check below URL:
    http://www.uiplayground.in/css3-icons/

  101. Martin Kocev
    Permalink to comment#

    Believe me or not, I’m in a situation that nothing can help but a CSS triangle :)

    Thanks for the tutorial

  102. ebuychance
    Permalink to comment#

    Firefox gray diagonal lines on the mac issue.

    Resolved: rather then ‘transparent’ use rgba(255,255,255,0)

    [rgba(0,0,0,0) renders the same as transparent]

  103. After reading this article (thanks for the helpful info Chris!), I stumbled across this CSS Triangle Generator. It’s pretty awesome

  104. Linus lilja
    Permalink to comment#

    Heres my little mixin I use in order to get arrows!

    // Mixin for creating arrows, basic usage @include arrow(top-left, #000, 15px);
    // available directions: top, right, bottom, left, top-left, top-right, bottom-left, bottom-right
    
    @mixin arrow($direction, $color, $size){
      height: 0;
      width: 0;
      content: '';
    
      @if $direction == 'top' {
        border-left: $size solid transparent;
        border-right: $size solid transparent;
        border-bottom: $size solid $color;
      } @else if $direction == 'right' {
        border-top: $size solid transparent;
        border-bottom: $size solid transparent;
        border-left: $size solid $color;
      } @else if $direction == 'bottom' {
        border-top: $size solid $color;
        border-right: $size solid transparent;
        border-left: $size solid transparent;
      } @else if $direction == 'left' {
        border-top: $size solid transparent;
        border-right: $size solid $color;
        border-bottom: $size solid transparent;
      } @else if $direction == 'top-left' {
        border-top: $size solid $color; 
        border-right: $size solid transparent;  
      } @else if $direction == 'top-right' {
        border-top: $size solid $color; 
        border-left: $size solid transparent;
      } @else if $direction == 'bottom-left' {
        border-bottom: $size solid $color; 
        border-right: $size solid transparent;  
      } @else if $direction == 'bottom-right' {
        border-bottom: $size solid $color; 
        border-left: $size solid transparent;
      }
    }
    
  105. Adam Dehnel
    Permalink to comment#

    Great article, I’ve referenced it many times. I’m playing around with making a speedometer partially as a learning exercise for transforms and partially because working with a lot of automotive manufacturers they like their data represented in real dashboard looking widgets. I’m having a weird thing with the triangle I’m using as the “needle” on the gauge, though, where it looks really blocky (like it’s from the original Nintendo or something). Is there anything I can do to make that better?

    Thanks!

  106. Alan
    Permalink to comment#

    Thanks! I was using an html entity for an arrow in an html email template, but it wasn’t displaying properly on iOS. The CSS triangle solved it!

  107. Balint
    Permalink to comment#

    Not at all necessary to rotate the triangles as they are hard to align. E.g. this triangle is sittin on one of its sides:
    border-left:30px solid transparent;
    border-bottom:25px solid #B7550C;>

  108. Permalink to comment#

    Just putting this out there, if the lines look like crap in Firefox etc. Use ‘dashed’ instead of ‘solid’ on the transparent borders. :)

  109. For the first time I knew about this ..
    Very useful once, and of course the function all of assets can be reduced slightly with the help of CSS 3..
    Thx alot..

  110. Will
    Permalink to comment#

    Created a Gist for a SASS Version to be used as a mixin. Enjoy!

    https://gist.github.com/willbowling/10181744#file-_sass-arrows-sass

  111. Anyone can help me to make that triangle is on :before or :after for the div?

  112. There is an article in the March 2013 (Vol. 56 No. 3) Communications of the ACM, The Story of the Teapot in DHTML, by Brian Beckman and Erik Meij, that explains how you can use CSS borders to render any arbitrary image. If you don’t have access to CACM, there is a wiki at http://www.sjbaker.org/wiki/index.php?title=The_History_of_The_Teapot.

  113. Jake
    Permalink to comment#

    Note: The BACKGROUND needs to be TRANSPARENT/NONE
    Explanation: This might not be clear, but even though the width and height are 0, any background appears “behind” those transparent borders.
    So if you are for example editing an existing element with black background and you would set black bottom border and transparent left/right borders – you would actually get a rectangle :)
    Hope this helps someone :)

  114. Permalink to comment#

    Whats the Best way to get a background image in that triangle?

  115. abhijeet gupta
    Permalink to comment#

    what if I want to create an arrow with html css only (not a traingle with filled background color or border color) .. pls give any suggestions

    • Jake
      Permalink to comment#

      1) use a font arrow e.g. → ( &amp;#8592 ) , you can google “ascii arrows” for more
      2) use HTML&CSS (triangle will have to be borderized, but check this out):
      It is basically doing a rectangle and triangle next to each other (using inline-block)
      and setting vertical-align: middle to both of them so they get verticaly-centerized :)

      <style>
      .arrow-rectangle {
        border-top: 6px solid green;
        border-left: 28px solid green;
        display: inline-block;
        position: relative;
        vertical-align: middle;
      }
      .arrow-triangle {
        border-top: 10px solid transparent;
        border-bottom: 12px solid transparent;
        border-left: 12px solid green;
        display: inline-block;
        position: relative;
        left: -4px;
        vertical-align: middle;
      }
      </style>
      
      <div class="arrow-rectangle"></div>
      <div class="arrow-triangle"></div>
      
      

      Hope this helps :)

  116. Permalink to comment#

    Very Nice. But can we make bullets for list with this like code?

Leave a Comment

Posting Code

  • Use Markdown, and it will escape the code for you, like `<div class="cool">`.
  • Use triple-backticks for blocks of code.
    ``` 
    <div>
      <h1>multi-line block of code</h1>
      <span>be cool yo.</span>
    </div>
    ```
  • Otherwise, escape your code, like <code>&lt;div class="cool"&gt;</code>. Markdown is just easier though.

Current ye@r *

*May or may not contain any actual "CSS" or "Tricks".