61

After some research, I couldn't find an answer to this question. There was this but it didn't really answer my question. I would like to "strikethrough" a complete HTML table row in CSS, not just the text in it. Is it at all possible? From the example that I linked, it seems tr styling doesn't even work in Firefox. (And anyway, text-decoration only applies on text afaik)

Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
Mathieu M-Gosselin
  • 1,158
  • 1
  • 12
  • 17

9 Answers9

106

Oh yes, yes it is!

CSS:

table {
    border-collapse: collapse;
}

td {
    position: relative;
    padding: 5px 10px;
}

tr.strikeout td:before {
    content: " ";
    position: absolute;
    top: 50%;
    left: 0;
    border-bottom: 1px solid #111;
    width: 100%;
}

HTML:

<table>
    <tr>
        <td>Stuff</td>
        <td>Stuff</td>
        <td>Stuff</td>
    </tr>
    <tr class="strikeout">
        <td>Stuff</td>
        <td>Stuff</td>
        <td>Stuff</td>
    </tr>
    <tr>
        <td>Stuff</td>
        <td>Stuff</td>
        <td>Stuff</td>
    </tr>
</table>

http://codepen.io/nericksx/pen/CKjbe

crinkledMap
  • 1,104
  • 1
  • 8
  • 8
  • I would edit the solution given to have the css applied only to a table with a class such as strike-able. Your code may have the side effect of modifying other tables. I'll add a solution to help explain – Greg Jul 22 '15 at 21:24
  • Is there a way to get the line in red? Thanks! – Stefan Müller Oct 28 '15 at 10:03
  • FYI, the code listed is not the same as the code in the link. I believe the link is more updated. @StefanMüller change the `#111` to the color you want. – dbinott Nov 24 '15 at 15:51
39

My answer (below) said that it is not possible. I was wrong, as pointed out by @NicoleMorganErickson. Please see her answer (and upvote it!) for how to do it. In short, you use :before pseudo-class to create an element that draws a border across the middle of the cell, above the content:

table           { border-collapse:collapse } /* Ensure no space between cells   */
tr.strikeout td { position:relative        } /* Setup a new coordinate system   */
tr.strikeout td:before {                     /* Create a new element that       */
  content: " ";                              /* …has no text content            */
  position: absolute;                        /* …is absolutely positioned       */
  left: 0; top: 50%; width: 100%;            /* …with the top across the middle */
  border-bottom: 1px solid #000;             /* …and with a border on the top   */
}    

(original answer)

No, it is not possible using only CSS and your semantic table markup. As @JMCCreative suggests, it is possible visually using any number of ways to position a line over your row.

I would instead suggest using a combination of color, background-color, font-style:italic and/or text-decoration:line-through to make the entire row obviously different. (I'd personally strongly 'fade out' the text to a color much closer to the background than normal text and make it italic.)

Phrogz
  • 271,922
  • 98
  • 616
  • 693
13
tr {
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NkYGCQBAAAIwAbDJgTxgAAAABJRU5ErkJggg==');
    background-repeat: repeat-x;
    background-position: 50% 50%;
}

I used http://www.patternify.com/ to generate the 1x1 image url.

René Höhle
  • 24,401
  • 22
  • 66
  • 73
Semiaddict
  • 141
  • 2
  • 5
11

The easiest way would be to use a background-image on the tr and its descendant cells (or simply use a transparent background-color on those cells).

html:

<table>
    <thead>
        <tr>
            <th>Col One</th>
            <th>Col Two</th>
            <th>Col Three</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>First row, One-One</td>
            <td>First row, One-Two</td>
            <td>First row, One-Three</td>
        </tr>
        <tr class="empty">
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

css:

table {
    empty-cells: show;
}
th, td {
    width: 6em;
    height: 2em;
    line-height: 2em;
    border: 1px solid #ccc;
}
tr.empty,
tr.empty td {
    background: transparent url('http://davidrhysthomas.co.uk/linked/strike.png') 0 50% repeat-x;
}

JS Fiddle demo

David says reinstate Monica
  • 230,743
  • 47
  • 350
  • 385
9

Edit 02/03/2020:

In a recent bootstrap 4.3 ServiceNow Angular.js project, I found myself having to make some changes, and instead used the following css, similar to the experience of Revoman:

    tr.strikeout td.strike-able:before {
          content: " ";  
          position: absolute;  
          display: inline-block;  
          padding: 12px 10px;  
          left: 0;  
          border-bottom: 2px solid #d9534f;  
          width: 100%;          
    }

Orginal Post:

I like Nicole Morgan Erickson's answer, but it might cause side effects if your implement his solution verbatim. I've add some small tweaks to keep this kosher, below... so that we're not globally modifying every table or every td with this css.

I also wanted a button on the row to strike out the row, but I didn't want to strike out the column with the button, for visibility sake. I just wanted to strike out the rest of the row. For this, I made it so that every column that wants to be capable of showing the strike out must declare such by also being marked with a class. In this iteration, you'd need to mark the table as strike-able, and also mark each td as strike-able; but you gain safety by not side effecting any non-strike-able tables, and you gain control of which columns to strike out.

CSS:

table.strike-able {
    border-collapse: collapse;
}

table.strike-able tr td {
    position: relative;
    padding: 3px 2px;
}

table.strike-able tr th {
    position: relative;
    padding: 3px 2px;
}

table.strike-able tr.strikeout td.strike-able:before {
    content: " ";
    position: absolute;
    top: 50%;
    left: 0;
    border-bottom: 2px solid #d9534f;
    width: 100%;
}

Usage:

<table class="strike-able" id="Medications" data-item-count="@Model.Medications.Count">
<tr>
    <th>
        Some Column
    </th>
    <th>
        Command Column
    </th>
</tr>
<tr class="strikeout">
    <td class="strike-able"></td>
    <td>Button that Toggles Striking Goes Here (active)</td>
</tr>
<tr>
    <td class="strike-able"></td>
    <td>Button that Toggles Striking Goes Here</td>
</tr>
</table>

Lastly, since I'm using this with Bootstrap, and treating the deletions as a dangerous thing to do, I've formatted the colors a little to match my use.

Greg
  • 1,982
  • 17
  • 20
  • Brilliant, thank you for this. Your use case is exactly mine down to the use of Bootstrap. We're using the DataTables plugin for jQuery and your answer appears to work perfectly with it (including sorting). – Paul Sep 30 '15 at 22:44
  • Would this work where the rendered table is from an asp:GridView ? –  Jun 24 '17 at 12:06
6

EDIT: As pointed out by @Mathieu M-Gosselin in the comments, this actually puts the line behind the text. That said, if your line is the same color as your text or you are using a small-ish font, this still works pretty well.

For what it's worth, here's a pretty effective way to do it in pure CSS without using pseudo elements. You can change the thickness of the strikethrough line by adjusting the background-size.

table {
  border-collapse: collapse;
}

td {
  width: 100px
}

.strikethrough {
  background: repeating-linear-gradient(
    180deg,
    red 0%,
    red 100%
  );
  background-size: 100% 2px;
  background-position: center;
  background-repeat: no-repeat;
}
<table>
  <tr>
    <td>Foo</td>
    <td>Bar</td>
    <td>Baz</td>
  </tr>
  <tr class="strikethrough">
    <td>Foo Strike</td>
    <td>Bar Strike</td>
    <td>Baz Strike</td>
  </tr>
</table>
gaw89
  • 905
  • 9
  • 19
3

@NicoleMorganErickson, I like your answer, but I could not get the strikeout to affect only the applied row. Also, I needed it to be applied multiple rows so I modified your solution down into a single class.

CSS:

tr.strikeout td:before {  
  content: " ";  
  position: absolute;  
  display: inline-block;  
  padding: 5px 10px;  
  left: 0;  
  border-bottom: 1px solid #111;  
  width: 100%;  
}

http://codepen.io/anon/pen/AaFpu

Lukasz Stelmach
  • 4,821
  • 3
  • 22
  • 29
Revoman
  • 214
  • 2
  • 5
  • this maybe old, but i needed to do this and this answer was the one that worked best; the others caused side effects, or didn't "strike out" enough. Thanks. – warath-coder Mar 20 '17 at 00:11
1

Yes you can. In the first cell of the row you create a div containing a HR. Float the div to the left and specify its width as a % of its containing element, in this case the table cell. It'll stretch as wide as you want across the table cells in that row, even beyond the width of the table if you want.

This works for me:

<style>
.strikeThrough {
height:3px;
color:#ff0000;
background-color:#ff0000;
}
.strikeThroughDiv {
float:left;
    width:920%;
    position:relative;
    top:18px;
border:none;
}
</style>
<table width="900" border="1" cellspacing="0" cellpadding="4">
   <tr  valign="bottom">
    <td>
    <div class="strikeThroughDiv"><hr  class="strikeThrough"/></div>
    One
    </td>
    <td>    
        <label for="one"></label>
        <input type="text" name="one" id="one" />
    </td>
    <td>
    <label for="list"></label>
      <select name="list" id="list">
        <option value="One">1</option>
        <option value="Two">2</option>
        <option value="Three" selected>3</option>
      </select>
    </td>
    <td>
      Four
    </td>
    <td>
      Five
    </td>
  </tr>
</table>

To control the width of your line you have to specify the width of the table cell containing the HR. For styling HR elements they say you shouldn't make it less than 3px in height.

Eamonn Gormley
  • 2,200
  • 4
  • 16
  • 19
0

How about absolutely positioning an <hr /> element overtop of the row. Depending on how static or dynamic this needs to be, it could be an extremely fast/easy way to go or much harder.

JakeParis
  • 10,471
  • 3
  • 34
  • 63
  • It's a table containing a list of products, some of which need to be striked out. I was wondering if there was a CSS property to do it, rather than relying on that kind of "hack". – Mathieu M-Gosselin Jan 06 '11 at 20:40
  • 1
    Definitely a hack, not denying that! Actually I was just playing with it in a fiddle, and it would be extremely hard to "get right" anyway. – JakeParis Jan 06 '11 at 20:41
  • I'd say that this type of hack isn't that much better or worse than the accepted solution which also feels a bit like a hack to me. But like you say, the place where this gets more difficult is in the positioning of the hr 's which might take some javascript and not be purely css. The accepted solution wins some awards for pure css, and seems to work in IE and Chrome. – Greg Jul 22 '15 at 21:43