20

How can I create a diagonal line from the lower left corner to the upper right corner of any given cell?

To get this

<table>
    <tr>
        <td class="crossOut">A1</td>
        <td>B1</td>
    </tr>
    <tr>
        <td>A2 Wide</td>
        <td class="crossOut">B2<br/>Very<br/>Tall</td>
    </tr>
</table>

to show this

enter image description here

Sean
  • 6,873
  • 4
  • 21
  • 46
Josh
  • 2,259
  • 4
  • 22
  • 25

3 Answers3

15

I've found a simple, CSS-only solution using linear gradients:

You can simply specify a diagonal line by defining a linear gradient. The linear gradient becomes several stop colors. The start and the second color are the same (= no gradient). The same goes for the last and the pre-last color. The colors between them (around 50 %) are used for the diagonal line.

You can test it here:

td
{
 border: 1pt solid black;
}

td.diagonalRising
{
 background: linear-gradient(to right bottom, #ffffff 0%,#ffffff 49.9%,#000000 50%,#000000 51%,#ffffff 51.1%,#ffffff 100%);
}

td.diagonalFalling
{
 background: linear-gradient(to right top, #ffffff 0%,#ffffff 49.9%,#000000 50%,#000000 51%,#ffffff 51.1%,#ffffff 100%);
}

td.diagonalCross
{
 position:   relative;
 background: linear-gradient(to right bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 49.9%,rgba(0,0,0,1) 50%,rgba(0,0,0,1) 51%,rgba(0,0,0,0) 51.1%,rgba(0,0,0,0) 100%);
}

td.diagonalCross:after
{
 content:     "";
 display:     block;
 position:    absolute;
 width:       100%;
 height:      100%;
 top:         0;
 left:        0;
 z-index:     -1;
 background:  linear-gradient(to right top, #ffffff 0%,#ffffff 49.9%,#000000 50%,#000000 51%,#ffffff 51.1%,#ffffff 100%);
}
<table>
<tr><td>a</td><td class="diagonalRising">abc</td><td class="diagonalFalling">abcdefghijklmnopqrstuvwxyz</td><td class="diagonalCross">abcdefghijklmnopqrstuvwxyz<br>qaywsxedcrfvtgbzhnujmikolp</td></tr>
</table>

Unfortunately you can barely specify the line width. I've tested it with Firefox, Chrome, Opera and Internet Explorer. It looks ok in all of them (but slightly diffent in IE in comparison to the others).

David Gausmann
  • 1,570
  • 16
  • 20
  • Excellent idea, although of course the % could be too small or too large depending on the size of the cell, but in my case it looks just perfect. – Alexis Wilke Jan 06 '16 at 06:58
  • Solved my case with one line of CSS. Brilliant! – Johan Fredrik Varen Feb 23 '20 at 14:00
  • what's the reasoning for specifying rgb colors in one area and hex in the others? It seems like people usually use rgb for gradients ... why? Hex is neater (especially 3- or 4-character hex like `#000` as opposed to `rgba(0, 0, 0, 0)` ...) – ashleedawg Dec 24 '22 at 12:54
  • here's the `cross` css, but "compressed": `td.cross{position:relative;background:linear-gradient(to right bottom,#0000 0%,#0000 49.9%,#000 50%,#000 51%,#0000 51.1%,#0000 100%)} td.cross:after{content:"";display:block;position:absolute;width:100%;height:100%;top:0;left:0;z-index:-1;background:linear-gradient(to right top,#fff 0%,#fff 49.9%,#000 50%,#000 51%,#fff 51.1%,#fff 100%)}` – ashleedawg Dec 24 '22 at 13:20
  • @ashleedawg There was no special reason. I just prefer to use rgba if I specify the alpha value. Thus I used rgba for all values of cross to make it consistent. – David Gausmann Jan 11 '23 at 08:09
15

I don't know if is the best way, but I can't do that with CSS. My answer is in jQuery:

http://jsfiddle.net/zw3Ve/13/

$(function(){
    $('.crossOut').each(function(i){
        var jTemp = $(this),
            nWidth = jTemp.innerWidth(),
            nHeight = jTemp.innerHeight(),
            sDomTemp = '<div style="position:absolute; border-color: transparent black white white; border-style:solid; border-width:'+nHeight +'px '+nWidth +'px 0px 0px; width:0; height:0; margin-top:-'+nHeight+'px; z-index:-2"></div>';

        sDomTemp += '<div style="position:absolute; border-color: transparent white white white; border-style:solid; border-width:'+nHeight +'px '+nWidth +'px 0px 0px; width:0; height:0; margin-top:-'+(nHeight-1)+'px; z-index:-1"></div>';

        jTemp.append(sDomTemp);
    });
});

or

http://jsfiddle.net/zw3Ve/16/ (with CSS class cleaner)

CSS part:

.crossOut .child{
    position:absolute; 
    width:0; 
    height:0;
    border-style:solid;
}
.crossOut .black-triangle{
    z-index:-2;
    border-color: transparent black white white;
}
.crossOut .white-triangle{
    border-color: transparent white white white;
    z-index:-1;
}

jQuery code:

$(function(){
    $('.crossOut').each(function(i){
        var jTemp = $(this),
            nWidth = jTemp.innerWidth(),
            nHeight = jTemp.innerHeight(),
            sDomTemp = '<div class="child black-triangle" style="border-width:'+nHeight +'px '+nWidth +'px 0px 0px; margin-top:-'+nHeight+'px; "></div>';

        sDomTemp += '<div class="child white-triangle" style="border-width:'+nHeight +'px '+nWidth +'px 0px 0px; margin-top:-'+(nHeight-1)+'px;"></div>';

        jTemp.append(sDomTemp);
    });
});

The good thing is it works with any width and height of a table cell.

Edit:

I was not happy with the quality of rendering of triangles made ​​with CSS borders so I used the css-rotation. I think this is a better work (and the lines are render better):

http://jsfiddle.net/zw3Ve/21/

(Using -sand-transform is for IE6, so it use is optional.)

Edit2: The last version has not got support for IE7-IE8 (seems the -sand-transform only works in CSS styles and not in styles written by JavaScript). I made a version with compatibility with old browsers:

http://jsfiddle.net/zw3Ve/23/

Community
  • 1
  • 1
Galled
  • 4,146
  • 2
  • 28
  • 41
4

It is possible. Try my solution:

.line {
    width: 200px;
    height: 50px;
    border: 1px solid #cccccc;
    margin: 10px;
    padding: 10px;
    position: relative;
}

.me {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    z-index: -1;
}


<div class="line">LINE!
     <img src="http://i.piccy.info/i7/c7a432fe0beb98a3a66f5b423b430423/1-5-1789/1066503/lol.png" class="me" />
</div>
Nathan Arthur
  • 8,287
  • 7
  • 55
  • 80
korywka
  • 7,537
  • 2
  • 26
  • 48