2

How can I style a table in html so it gets laid out like this:

<-       full page width             ->
<-20px->< dynamic ><-20px->< dynamic  >
+------------------+-------------------+
¦ A                ¦ B                 ¦ header row 1
+-------+----------+-------+-----------+
+ A1    ¦ A2       ¦ B1    ¦ B2        ¦ header row 2
+-------+----------+-------+-----------+
¦ a1      a2         b1      b2        ¦ data rows

Without the grouping header row, I would do it like this:

<table style="width:100%; table-layout:fixed;">
  <tr>
    <th style="width:20px;">A1</th>
    <th style="           ">A2</th>
    <th style="width:20px;">B1</th>
    <th style="           ">B2</th>
  </tr>
  <tr>
    <td>a1</td>
    <td>a2</td>
    <td>b1</td>
    <td>b2</td>
  </tr>
</table>

This works nicely, when I resize the browser window, the two cols without explicit width take the available space, while the two fixed cols stay at the given width.

But when I add the grouping header row, I have not found any way to assign widths so that the table has two fixed and two adaptable columns.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Markus
  • 668
  • 7
  • 27
  • As a workaround, you could just add another element (e.g. a DIV containing two DIVs) above the table to contain the first headers, otherwise you lose the styling on the header row 2. – Tim Oct 16 '13 at 11:35
  • and how would I make sure the divs adapt to the table column widths? – Markus Oct 16 '13 at 18:00
  • Aren't the top two headers always 50%? – Tim Oct 17 '13 at 07:34
  • in this simplified example, yes, but not in my actual case – Markus Oct 17 '13 at 08:14
  • This is a great question. I had the same problem, and had a hard time figuring out how to ask a question like this. You nailed it. And your solution is perfect. Thanks again! – jumps4fun Dec 07 '16 at 15:19

4 Answers4

2

I can only test it on one browser here, but removing the table-layout fixs it here.

<table style="width:100%;">
  <tr>
    <th colspan="2">A</th>
    <th colspan="2">B</th>
  </tr>
  <tr>
    <th style="width: 20px;">A1</th>
    <th>A2</th>
    <th style="width: 20px;">B1</th>
    <th>B2</th>
  </tr>
  <tr>
    <td style="width: 20px;">a1</td>
    <td>a2</td>
    <td style="width: 20px;">b1</td>
    <td >b2</td>
  </tr>
</table>

Some browser do seem to have problems: Internet Explorer 8 table cell width bug with colspan set

Community
  • 1
  • 1
the_lotus
  • 12,668
  • 3
  • 36
  • 53
  • I tried it without the `style`s on the and it works okay too. at least on FF – Einacio Oct 16 '13 at 18:42
  • it works for the example. However, without table-layout:fixed, the two stretching columns get widths proportionally distributed to their cell content widths, replace b2 by a long text and you see what I mean – Markus Oct 17 '13 at 09:24
  • @Markus Seems like you can't have a fixed layout and then asking to change the width. You could set the first row (with colspan 2) to each column be 50%. – the_lotus Oct 17 '13 at 11:52
2

I'd recommend using <colgroup /> and setting the widths via CSS (don't use inline styles if at all possible). As you saw, you need to set the width for each column when you have colspan involved, but that's really not an issue for HTML/CSS.

CSS

table{
    width:100%;

.narrow{
    width:40px;
}
.dynamic{
    width:auto;
}

HTML

<table>

<colgroup class="narrow"/>
<colgroup class="dynamic"/>
<colgroup class="narrow"/>
<colgroup class="dynamic"/>

<tr>
    <th colspan="2">A</th>
    <th colspan="2">B</th>
</tr>
<tr>
    <th>A1</th>
    <th>A2</th>
    <th>B1</th>
    <th>B2</th>
</tr>

<tr>
    <td>a1</td>
    <td>a2</td>
    <td>b1</td>
    <td>b2</td>
</tr>
[ ... ]

</table>

http://jsfiddle.net/daCrosby/X7TgN/1/

DACrosby
  • 11,116
  • 3
  • 39
  • 51
  • Yes, I agree about using css instead of inline. I'm a little irritated by the fact that html 5 doesn't support most of the colgroup and col attributes (at least they say so in w3 schools)? – Markus Oct 17 '13 at 09:08
  • [Several of the possible attributes on colgroup & col are depreciated](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup), but those same attributes are depreciated basically everywhere (`align` for example should be replaced with CSS). [The colgroup & col elements themselves are part of the HTML5 specs.](http://www.w3.org/TR/html5/tabular-data.html#the-colgroup-element) – DACrosby Oct 17 '13 at 21:08
1

With your contributions and some search in W3C docs, I came to this solution:

<table border="1" style="table-layout:fixed; width:100%;">
  <col style="width:20px;">
  <col style="width:50%;">
  <col style="width:20px;>
  <col style="width:50%;>
  <tr>
    <th colspan="2">A</th>
    <th colspan="2">B</th>
  </tr>
  <tr>
    <th>A1</th>
    <th>A2</th>
    <th>B1</th>
    <th>B2</th>
  </tr>
  <tr>
    <td>a1</td>
    <td>a2</td>
    <td>b1</td>
    <td>b2 very long text</td>
  </tr>
</table>

The table-layout:fixed is required to have the column widths as specified. Else the widths are calculated from cell contents, which is OK in the example but a trouble in reality.

In fixed layout, in absence of col elements, the first row is used to define the column widths. That's why cell widths worked with a single header row, but not with the grouping header. Providing col elements solves it.

Markus
  • 668
  • 7
  • 27
  • Thank You! This is the only answer that actually works for all of the specifications in the question. It is the perfect answer. I do not get why this is not more upvoted, but I am thankful that it was the accepted answer! – jumps4fun Dec 07 '16 at 15:18
0
<table style="width:100%; table-layout:fixed;">
  <tr>
   <th colspan="2">A1</th>
   <th colspan="2">A2</th>
  </tr>
   <tr>
   <th colspan="1">A1</th>
   <th colspan="1">A2</th>
   <th colspan="1">B1</th>
   <th colspan="1">B2</th>
  </tr>
   <tr>
   <td colspan="1">a1</td>
   <td colspan="1">a2</td>
   <td colspan="1">b1</td>
   <td colspan="1">b2</td>
  </tr>
  </table>

Using colspan will solve your problem. Try the one above and let me know what you get.

Magic
  • 505
  • 2
  • 6
  • 19