How to add triangle in table cell

Using CSS Triangles:

You basically have a 0 height, 0 width element, and use the borders to construct the triangle. Because the line between borders (for example, between top and left) is diagonal, you can create nice looking, solid color triangles with it!

Here's an Example!

HTML:

<table border="1">
    <tr>
        <td class="note">Triangle!</td>
        <td>No Triangle!</td>
    </tr>
</table>

CSS:

td {
    padding: 20px;
}
.note {
    position: relative;
}
.note:after { /* Magic Happens Here!!! */
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 0; 
    height: 0; 
    display: block;
    border-left: 20px solid transparent;
    border-bottom: 20px solid transparent;

    border-top: 20px solid #f00;
} /* </magic> */

Advantages:

  • No Images! - Meaning, no extra request.
  • No Additional Markup! - Meaning, you don't litter your HTML with unsemantic markup.
  • Looks good on all sizes! - Because it renders in the browser, it would look perfect on any size and any resolution.

Disadvantages:

  • Depends on pseudo-elements - Meaning that lower versions of IE will not display the triangle. If it's critical, you can modify the CSS a bit, and use a <span> in your HTML, instead of relying on :after.

Found this question through Google and ran into issues, so I'll add this here despite the age of original post.

Madara's answer works in most browsers, and works anywhere outside of a table in all browsers. But as mentioned in the comments, the example doesn't work in Firefox.

There's a very old ticket in Bugzilla concerning position:absolute; not working in <td> elements.

The main solution is to add an inner <div>:

HTML:

<table border="1">
<tr>
    <td><div class="note">Triangle!</div></td>
    <td>No Triangle!</td>
</tr>
</table>

CSS:

td .note {
    padding: 20px;
}

jsFiddle example

I did find that it was possible to achieve without an inner <div> but only when the <td> was empty, which probably doesn't help.


To do cell text inside div it good idea. but if you just put extra div for ARROW not for text. because it creates problem when td has given width and height and text stays on TOP with padding-top:20px;.

I found another solution and tested on All major browsers (eg: IF and FF as well)

.arrow-right-1 {
  position: absolute;
  top: -1px;
  right: -5px;
  float: right;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid red;
  transform: rotate(45deg);
}

td {
  border: solid 1px blue;
  width: 160px;
  height: 100px;
  /* padding: 0px !important; */
  /* vertical-align: top; */
  position: relative;
}
<table class="table">

  <tbody>
    <tr>
      <td>
        <div class="arrow-right-1"></div>you can increase or decrease the size of td's height or can put more text
      </td>

    </tr>

  </tbody>
</table>