518

How can I specify a td tag should span all columns (when the exact amount of columns in the table will be variable/difficult to determine when the HTML is being rendered)? w3schools mentions you can use colspan="0", but it doesn't say exactly what browsers support that value (IE 6 is in our list to support).

It appears that setting colspan to a value greater than the theoretical amount of columns you may have will work, but it will not work if you have table-layout set to fixed. Are there any disadvantages to using an automatic layout with a large number for colspan? Is there a more correct way of doing this?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Bob
  • 97,670
  • 29
  • 122
  • 130
  • 4
    The accepted answer is about how NOT to do this, and it seems to have serious performance/consistency downsides. So I guess the answer is: hardcode the number of columns. I don't see any viable alternative. – Andrew Koster May 10 '19 at 19:11
  • 2
    Great question, but you should have just not accepted any answer if none of them are correct. – HoldOffHunger Oct 02 '20 at 14:46

15 Answers15

404

Just use this:

colspan="100%"

It works on Firefox 3.6, IE 7 and Opera 11! (and I guess on others, I couldn't try)


Warning: as mentioned in the comments below this is actually the same as colspan="100". Hence, this solution will break for tables with css table-layout: fixed, or more than 100 columns.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Cluxter
  • 4,737
  • 2
  • 14
  • 2
  • 20
    Tested [additionally] in IE6 - IE8, Chrome [on PC and Mac], Firefox 4.0 [PC and Mac], Safari 5 [PC and Mac] – hndcrftd May 06 '11 at 17:55
  • 13
    How is this still so obscure? This should be shouted on every street corner!!! I've been struggling with this damned colspan issue at different times for quite a while now – hndcrftd May 06 '11 at 17:56
  • 40
    On chrome and firefox, colspan="3%" is handled just the same as colspan="3". – zpmorgan May 21 '11 at 19:49
  • 9
    @zpmorgan are we therefore to assume that 100% is just the same as 100 and therefore only working correctly because of the answer above? – Angry Dan Aug 12 '11 at 13:20
  • 128
    @zpmorgan and @Sprog, you are right! `colspan="100%"` means exactly `colspan="100"`. – NemoStein Sep 13 '11 at 14:35
  • 60
    Lol, I was very happy to finally see a consistent cross-browser solution to this problem, only to find through the comments that this is indeed a deceptive not-working-as-expected one :( I think it doesn't deserve more upvotes than the accepted answer =/ – Francisco Dec 28 '11 at 15:07
  • 2
    @Francisco however 100% is semantically more correct, so the mechanism by which it works is perhaps not so important? Unless of course, you happen to have a table with >100 columns (ouch). – Jonathan Day Mar 13 '12 at 09:06
  • 2
    In chrome when setting colspan='100%' I loose the right border of the table – Omu Oct 29 '12 at 20:27
  • As Omu said, this can cause issues with table borders especially when cellspacing is involved. So if your picky about your tables (Oh My! Tables...), then this solution doesn't work. – teynon Jan 17 '13 at 16:13
  • 2
    I've used this approach and also never knew it meant 100 columns, and that the % was effectively ignored. I think it would be awesome if browsers did actually implement this, so I'm going to stick to using 100%. Plus, I think if you have a table with more than 100 columns, then you have another problem on your hands :) – jamiebarrow Mar 11 '13 at 16:11
  • 12
    @JonathanDay: It's not at all semantically more correct, it's semantically absolutely misleading. It means something completely different than what it looks like. It's pretty much obfuscation of what is going on and that it works in *some* situations (`table-layout: automatic` only) doesn't make it better. – sth Jul 03 '13 at 15:57
  • 3
    @jamiebarrow I think you are right. If you run this construct through and HTML5 validator, it reports the presence of a '%' as an error. The spec seems pretty clear that it's not supposed to be there: http://www.w3.org/html/wg/drafts/html/master/tabular-data.html#attr-tdth-colspan – killthrush Sep 20 '13 at 16:51
  • 1
    This does not work when using borders on the table + td's, setting 100% shows a blank space to the right of the last column, eliminating the border. – Michael Mikhjian Jul 31 '19 at 16:50
  • Working on Chrome version 77.0.3865.90! – Gustavo Amaro Oct 09 '19 at 15:48
  • @GustavoAmaro: As of Chrome v78.0.3904.108 it's still only working for up to 100 columns (as the other comments already stated) – nitzel Nov 21 '19 at 11:35
  • of course its only working for 100 columns, it's just interpreting it as 100. if you need more columns, just use a higher number. and dont bother with the percent sign. – stackers Mar 04 '21 at 20:46
  • I had no idea this was a thing - I always have waited until my columns were done then went back and fixed the colspans to the number of coumns. Then changing when adding or deleting a column... this is so much nicer.... – jpgerb Apr 21 '22 at 20:22
  • This is inaccessible. Screen readers will read "Table with 100 columns", which is very irritating as it hides the actual number of columns. – deltragon Nov 30 '22 at 17:42
310

I have IE 7.0, Firefox 3.0 and Chrome 1.0

The colspan="0" attribute in a TD is NOT spanning across all TDs in any of the above browsers.

Maybe not recommended as proper markup practice, but if you give a higher colspan value than the total possible no. of columns in other rows, then the TD would span all the columns.

This does NOT work when the table-layout CSS property is set to fixed.

Once again, this is not the perfect solution but seems to work in the above mentioned 3 browser versions when the table-layout CSS property is automatic.

starball
  • 20,030
  • 7
  • 43
  • 238
Nahom Tijnam
  • 4,726
  • 5
  • 25
  • 25
  • If you specify a strict doctype at the very start of the html Firefox 3 render the colspan as required by html 4.01 specs. – Eineki Dec 29 '08 at 23:28
  • 313
    I'm a fan of `colspan="42"` to span the entire range. Obviously this is a problem for >42 columns, but it's one of the few magic numbers I approve of. – Mar Jan 14 '13 at 19:43
  • 65
    I highly recommend you put colspan=. I just hit a huge perf bug in Firefox that took me all day to figure out. An arbitrarily large colspan will make FF choke on a large table with border-collapse:collapse. My table with 800 rows and 8 columns was taking 5 seconds to render. With the right colspan it's back down to a reasonable 1 second. https://bugzilla.mozilla.org/show_bug.cgi?id=675417 – InfinitiesLoop Jun 04 '13 at 00:50
  • 2
    I recommend not using this method. Just got very strange result from Chrome on OSX (columns overlapping each other). – Tzach Nov 25 '14 at 16:07
  • another problem found in Chrome if you try to give a border to the TR element that contains the "oversize" TD, the right border will not be visible. – Massimo Feb 02 '16 at 21:51
  • Approach does not work on Chrome v54. Scales columns down so they appear very narrow on left. – Dan Solovay Nov 03 '16 at 13:55
  • Using large numbers can mess up CSS such as the `border-right` property. I assume the border tries to end on the furthest column, even if it's not used and just a `colspan`. – bryc Jan 20 '17 at 22:02
  • Those browsers you're mentioning are almost SIXTY versions behind. Firefox is on version 62 and Chrome is on version 69. Some client bases might have ancient browsers, but don't think most sites need to cater to machines that have somehow disabled their browsers updates and left it that way for TEN YEARS. This answer is also ten years old, but the question it addresses is sadly still relevant. – Andrew Koster Sep 17 '18 at 19:52
  • Setting the colspan to a value higher than the actual column number will also break screen readers, as they will announce the colspan, and not the actual number of columns. – deltragon Jun 08 '20 at 17:09
  • *give a higher colspan value than the total possible no. of columns* Does not work in Microsoft Edge. – HoldOffHunger Oct 02 '20 at 14:41
75

If you want to make a 'title' cell that spans all columns, as header for your table, you may want to use the caption tag (http://www.w3schools.com/tags/tag_caption.asp / https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption) This element is meant for this purpose. It behaves like a div, but doesn't span the entire width of the parent of the table (like a div would do in the same position (don't try this at home!)), instead, it spans the width of the table. There are some cross-browser issues with borders and such (was acceptable for me). Anyways, you can make it look as a cell that spans all columns. Within, you can make rows by adding div-elements. I'm not sure if you can insert it in between tr-elements, but that would be a hack I guess (so not recommended). Another option would be messing around with floating divs, but that is yuck!

Do

<table>
    <caption style="gimme some style!"><!-- Title of table --></caption>
    <thead><!-- ... --></thead>
    <tbody><!-- ... --></tbody>
</table>

Don't

<div>
    <div style="float: left;/* extra styling /*"><!-- Title of table --></div>
    <table>
        <thead><!-- ... --></thead>
        <tbody><!-- ... --></tbody>
    </table>
    <div style="clear: both"></div>
</div>
natevw
  • 16,807
  • 8
  • 66
  • 90
  • 2
    Exactly what I was searching to put pagination controls at the bottom of a datatable. It works perfectly. Thank you very much. – Comencau Aug 10 '15 at 16:10
  • 12
    This does not work if you want to span all cols in the middle of a table..such as group by separator between related groups of rows. (Chrome) – David Hempy Oct 16 '15 at 20:15
39

As a partial answer, here's a few points about colspan="0", which was mentioned in the question.

tl;dr version:

colspan="0" doesn't work in any browser whatsoever. W3Schools is wrong (as usual). HTML 4 said that colspan="0" should cause a column to span the whole table, but nobody implemented this and it was removed from the spec after HTML 4.

Some more detail and evidence:

  • All major browsers treat it as equivalent to colspan="1".

    Here's a demo showing this; try it on any browser you like.

    td {
      border: 1px solid black;
    }
    <table>
      <tr>
        <td>ay</td>
        <td>bee</td>
        <td>see</td>
      </tr>
      <tr>
        <td colspan="0">colspan="0"</td>
      </tr>
      <tr>
        <td colspan="1">colspan="1"</td>
      </tr>
      <tr>
        <td colspan="3">colspan="3"</td>
      </tr>
      <tr>
        <td colspan="1000">colspan="1000"</td>
      </tr>
    </table>
  • The HTML 4 spec (now old and outdated, but current back when this question was asked) did indeed say that colspan="0" should be treated as spanning all columns:

    The value zero ("0") means that the cell spans all columns from the current column to the last column of the column group (COLGROUP) in which the cell is defined.

    However, most browsers never implemented this.

  • HTML 5.0 (made a candidate recommendation back in 2012), the WhatWG HTML living standard (the dominant standard today), and the latest W3 HTML 5 spec all do not contain the wording quoted from HTML 4 above, and unanimously agree that a colspan of 0 is not allowed, with this wording which appears in all three specs:

    The td and th elements may have a colspan content attribute specified, whose value must be a valid non-negative integer greater than zero ...

    Sources:

  • The following claims from the W3Schools page linked to in the question are - at least nowadays - completely false:

    Only Firefox supports colspan="0", which has a special meaning ... [It] tells the browser to span the cell to the last column of the column group (colgroup)

    and

    Differences Between HTML 4.01 and HTML5

    NONE.

    If you're not already aware that W3Schools is generally held in contempt by web developers for its frequent inaccuracies, consider this a lesson in why.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
  • 14
    Haha I like how useful API features just get removed entirely when no one gets around to implementing them. Amazing process. – Andrew Koster May 10 '19 at 19:12
  • 1
    I just tested colspan="0" in Firefox 116 and it does not appear to support colspan="0". As far as I know, there is (still) no browser that supports colspan="0". – Albert Wiersch Aug 24 '23 at 17:20
  • @AlbertWiersch that's to be expected - as I note in the answer, it got removed from the HTML spec over a decade ago and `colspan="0"` has been officially illegal under the HTML spec ever since. – Mark Amery Aug 25 '23 at 13:15
14

For IE 6, you'll want to equal colspan to the number of columns in your table. If you have 5 columns, then you'll want: colspan="5".

The reason is that IE handles colspans differently, it uses the HTML 3.2 specification:

IE implements the HTML 3.2 definition, it sets colspan=0 as colspan=1.

The bug is well documented.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • 1
    The amount of columns may be variable, I will update my question to include that remark. – Bob Dec 29 '08 at 21:43
  • While the advice in the top paragraph seems sensible, I think that many of the details here aren't quite right. The [HTML 3.2 spec](https://www.w3.org/TR/2018/SPSD-html32-20180315/) says that `colspan`s must be *positive* integers, which makes `colspan=0` illegal; nowhere does it explicitly dictate that `colspan=0` should be handled as `colspan=1` (although I'm sure that is in fact what IE 6 does). Also, the quote is not (any longer?) anywhere on the forum page you link to, and most of the Google search results (now?) are about entirely *different* IE 6 colspan-related bugs. – Mark Amery Sep 16 '18 at 17:13
13

If you're using jQuery (or don't mind adding it), this will get the job done better than any of these hacks.

function getMaxColCount($table) {
    var maxCol = 0;

    $table.find('tr').each(function(i,o) {
        var colCount = 0;
        $(o).find('td:not(.maxcols),th:not(.maxcols)').each(function(i,oo) {
            var cc = Number($(oo).attr('colspan'));
            if (cc) {
                colCount += cc;
            } else {
                colCount += 1;
            }
        });
        if(colCount > maxCol) { 
            maxCol = colCount; 
        }
    });

    return maxCol;
}

To ease the implementation, I decorate any td/th I need adjusted with a class such as "maxCol" then I can do the following:

$('td.maxcols, th.maxcols').each(function(i,o) {
    $t = $($(o).parents('table')[0]); $(o).attr('colspan',  getMaxColCount($t));
});

If you find an implementation this won't work for, don't slam the answer, explain in comments and I'll update if it can be covered.

frankenapps
  • 5,800
  • 6
  • 28
  • 69
rainabba
  • 3,804
  • 35
  • 35
  • 1
    Would be great if you had a vanilla JS version – jpaugh Sep 15 '15 at 16:54
  • Do you have a common use case that lacks $(selector) support or just not want to use it? – rainabba Sep 16 '15 at 21:48
  • 1
    Neither. I'm just curious whether jQuery adds any benefit here; it's a pretty hefty prerequisite, and it looks like its only minimally used here. – jpaugh Sep 17 '15 at 00:17
  • Fair enough. Between jQuery and Angular, It's rare that I don't have those tools so I default to them. I'll leave it to someone else to come up with the vanilla version for now though. – rainabba Sep 18 '15 at 16:46
  • 1
    Since jQuery is somewhat outdated I've added an es6 version/answer (didn't want to update this answer with completely different code). – Sjeiti Oct 08 '18 at 12:26
  • If I understand the code correctly, it will calculate getMaxColCount() for each cell in the table. this is not very performant... – Nadav Dec 05 '19 at 16:45
7

Another working but ugly solution : colspan="100", where 100 is a value larger than total columns you need to colspan.

According to the W3C, the colspan="0" option is valid only with COLGROUP tag.

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
Raptor
  • 53,206
  • 45
  • 230
  • 366
  • colspan="100" (e.g. beyond limit) can cause very strange table rendering in some cases (I'll try to hunt down some test cases and post the URLs) – scunliffe Mar 22 '10 at 16:19
  • -1 because as far as I can determine the claim in the final paragraph is false. HTML 4 allows ``s to have `colspan="0"` (see https://www.w3.org/TR/REC-html40/struct/tables.html#adef-colspan), while HTML 5.0 doesn't allow `span="0"` on a `colgroup` (see https://www.w3.org/TR/html50/tabular-data.html#attr-colgroup-span which states that *"a span content attribute['s] value must be a valid non-negative integer greater than zero."*). – Mark Amery Sep 16 '18 at 17:32
  • https://www.w3schools.com/tags/att_td_colspan.asp W3schools actually says that colspan="0" only works in firefox. – AutoBaker Apr 06 '21 at 13:07
  • 1
    @5Diraptor never trust w3schools. The site is full of errors. use MDN instead – Raptor Apr 07 '21 at 01:49
7

Simply set colspan to the number of columns in the table.

All other "shortcuts" have pitfalls.

The best thing to do is set the colspan to the correct number to begin with. If your table has 5 columns, set it to colspan="5" That is the only way that will work in all scenarios. No, it's not an outdated solution or only recommended for IE6 or anything -- that's literally the best way to handle this.

I wouldn't recommend using Javascript to solve this unless the number of columns changes during runtime.

If the number of columns is variable, then you'll need to calculate the number of columns so that you can populate the colspan. If you have a variable number of columns, whatever is generating the table should be able to be adapted to also calculate the number of columns the table has.

As other answers have mentioned, if your table is not set to table-layout: fixed, you can also just set colspan to a really large number. But I find this solution messy, and it can be a headache if you come back later and decide it should be a fixed table layout. Better just to do it correctly the first time.

Skeets
  • 4,476
  • 2
  • 41
  • 67
  • 1
    This should be the accepted answer, the other ones suggesting to use a higher colspan are misleading as they also cause issues for screen readers. – deltragon Nov 30 '22 at 17:43
6

Below is a concise es6 solution (similar to Rainbabba's answer but without the jQuery).

Array.from(document.querySelectorAll('[data-colspan-max]')).forEach(td => {
    let table = td;
    while (table && table.nodeName !== 'TABLE') table = table.parentNode;
    td.colSpan = Array.from(table.querySelector('tr').children).reduce((acc, child) => acc + child.colSpan, 0);
});
html {
  font-family: Verdana;
}
tr > * {
  padding: 1rem;
  box-shadow: 0 0 8px gray inset;
}
<table>
<thead>
  <tr>
    <th>Header 1</th>
    <th>Header 2</th>
    <th>Header 3</th>
    <th>Header 4</th>
    <th>Header 5</th>
    <th>Header 6</th>
  </tr>
</thead>
<tbod><tr>
  <td data-colspan-max>td will be set to full width</td>
</tr></tbod>
</table>
Sjeiti
  • 2,468
  • 1
  • 31
  • 33
2

I've always used this; if not enough, increase the number. (overwhelms the number of columns you think you will have)

<td colspan='999'>
0

A CSS solution would be ideal, but I was unable to find one, so here is a JavaScript solution: for a tr element with a given class, maximize it by selecting a full row, counting its td elements and their colSpan attributes, and just setting the widened row with el.colSpan = newcolspan;. Like so...

var headertablerows = document.getElementsByClassName('max-col-span');

[].forEach.call(headertablerows, function (headertablerow) {
    var colspan = 0;
    [].forEach.call(headertablerow.nextElementSibling.children, function (child) {
        colspan += child.colSpan ? parseInt(child.colSpan, 10) : 1;
    });
    
    headertablerow.children[0].colSpan = colspan;
});
html {
  font-family: Verdana;
}
tr > * {
  padding: 1rem;
  box-shadow: 0 0 8px gray inset;
}
  <table>
    <tr class="max-col-span">
      <td>1 - max width
      </td>
    </tr>
    <tr>
      <td>2 - no colspan
      </td>
      <td colspan="2">3 - colspan is 2
      </td>
    </tr>
  </table>

You may need to adjust this if you're using table headers, but this should give a proof-of-concept approach that uses 100% pure JavaScript.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
0

Anyone else here feel that diving into JS for this seemingly minor issue seems a bit much?

PURE CSS

Boom! I have a pure CSS solution to offer you! Example is below, you just have to add a class to the row that you want to span all columns. Then the CSS will make the first <td> element span the full width and hide the remaining <td> elements. (You must use visibility:hidden; and NOT display:none; for this.)

Note: You will need at least two cells for this method to render nicely, and CSS will render best if you keep the correct quantity of <td> elements - don't remove any to make room for span element. This will help ensure the cells / rows still flow normally.

EXAMPLE

/* standard styling css */

table {
  border-collapse: collapse;
}

table, tr, td {
  border: 1px solid black;
}

td {
  padding: 3px;
}

/* make full width class span the whole table */

.full-span {
  position:relative;
}

.full-span > * {
  visibility: hidden;
  border:0;
}

.full-span > *:nth-child(1) {
  display: block;
  visibility: unset;
  position:absolute;
}
<table>
  <tbody>
    <tr>
      <td>A1</td>
      <td>A2</td>
      <td>A3</td>
      <td>A4</td>
    </tr>
    <tr class="full-span">
      <td>B1 long text</td>
      <td>B2</td>
      <td>B3</td>
      <td>B4</td>
    </tr>
    <tr>
      <td>C1</td>
      <td>C2</td>
      <td>C3</td>
      <td>C4</td>
    </tr>
    <tr>
      <td>D1</td>
      <td>D2</td>
      <td>D3</td>
      <td>D4</td>
    </tr>
  </tbody>
</table>

Bonus tip!

if you are dynamically producing your table in PHP/JS, this may clean up some of your code. Say you are looping through a 2D array to create a table: for each row that needs to span all columns you'll need to add some logic to calculate the amount of columns, add the colspan attribute, add any remaining <td> elements required to make up the full width of the table and so on.

Using my method, you can loop through all the columns and output them all, and simply include the class in the parent row.

AutoBaker
  • 919
  • 2
  • 15
  • 31
-1

Lots of complicated answers above.. but can be resolved very simply.

Either (because you'll never have a table with more than 1000 columns):

td colspan=1000

OR if you want to be very specific and don't mind using jquery:

$('table td.whichCol').attr('colspan',$('table tr:first td').length)

where: "td.whichCol" specifies the classname of the column to be spanned

where: "$('table tr:first td').length" counts the number of columns for the first row of the table.

-2

Just want to add my experience and answer to this.
Note: It only works when you have a pre-defined table and a tr with ths, but are loading in your rows (for example via AJAX) dynamically.

In this case you can count the number of th's there are in your first header row, and use that to span the whole column.

This can be needed when you want to relay a message when no results have been found.

Something like this in jQuery, where table is your input table:

var trs = $(table).find("tr");
var numberColumns = 999;
if (trs.length === 1) {
    //Assume having one row means that there is a header
    var headerColumns = $(trs).find("th").length;
    if (headerColumns > 0) {
        numberColumns = headerColumns;
    }
}
skiwi
  • 66,971
  • 31
  • 131
  • 216
  • Like [the JavaScript solution posted before this one](https://stackoverflow.com/a/7988152/1709587), this doesn't generalise well; the number of `th`s isn't necessarily the number of columns, since some of them may have a `colspan` set, and so this won't work as written for everyone. – Mark Amery Sep 16 '18 at 17:54
-5
colspan="100%"

it's work also in email outlook , gmail....

pmatatias
  • 3,491
  • 3
  • 10
  • 30
CrazyWolf
  • 9
  • 1