365

I've got a simple table that is used for an inbox as follows:

<table border="1">
     <tr>
        <th>From</th>
        <th>Subject</th>
        <th>Date</th>
    </tr>
</table>

How do I set the width so the From and Date are 15% of the page width and the Subject is 70%. I also want the table to take up the whole page width.

13 Answers 13

575

You can set the width of a table column using the CSS width property of the col element. The width value is most commonly specified in pixels (width: 200px;), or as a percentage of the width of the parent element (width: 50%;). Example with inline style attribute:

<table style="width: 100%">
    <colgroup>
       <col span="1" style="width: 15%;">
       <col span="1" style="width: 70%;">
       <col span="1" style="width: 15%;">
    </colgroup>
    
    
    
    <!-- Put <thead>, <tbody>, and <tr>'s here! -->
    <tbody>
        <tr>
            <td style="background-color: #777">15%</td>
            <td style="background-color: #aaa">70%</td>
            <td style="background-color: #777">15%</td>
        </tr>
    </tbody>
</table>

Sign up to request clarification or add additional context in comments.

14 Comments

Like the cleanliness of this solution. However, please close out the col e.g <col span="1" style="width: 15%;" /> or <col span="1" style="width: 15%;"></col>
@Isu_guy you only close <col> when using XHTML -- in HTML, <col> tag has no closing... see link for more info. In HTML5, <col> is a void element, meaning it MUST NOT be closed
@Zulu according to w3schools.com/tags/att_col_width.asp "The <col> width attribute is not supported in HTML5."
@Caltor: the code is not using the <col> width attribute; it is using a CSS *style* width, which is what replaced the <col> width attribute. (despite the multiple people up-voting that comment!!)
span="1" is superfluous since 1 is the default.
|
178

table {
  width: 100%;
  border: 1px solid #000;
}
th.from, th.date {
  width: 15%
}
th.subject {
  width: 70%; /* Not necessary, since only 70% width remains */
}
<table>
  <thead>
    <tr>
      <th class="from">From</th>
      <th class="subject">Subject</th>
      <th class="date">Date</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>[from]</td>
      <td>[subject]</td>
      <td>[date]</td>
    </tr>
  </tbody>
</table>

The best practice is to keep your HTML and CSS separate for less code duplication, and for separation of concerns (HTML for structure and semantics, and CSS for presentation).

Note that, for this to work in older versions of Internet Explorer, you may have to give your table a specific width (e.g., 900px). That browser has some problems rendering an element with percentage dimensions if its wrapper doesn't have exact dimensions.

5 Comments

this solution fails if you have colspans in the first row
Good because <col width=""> is obsolete in HTML5: developer.mozilla.org/en/docs/Web/HTML/Element/col
I had to use min-width.
I had to use min-width instead of width for it to work, but overall great, thanks.
@mark1234 This seems to work with colpans if you set the width for <td>s (not just <th>s).
46

Use the CSS below, the first declaration will ensure your table sticks to the widths you provide (you'll need to add the classes in your HTML):

table{
  table-layout:fixed;
}
th.from, th.date {
  width: 15%;
}
th.subject{
  width: 70%;
}

2 Comments

Actually you only need to specify width of the two columns. The third one will be calculated automatically, so table{table-layout:fixed};.from,.date{width:15%} is enough. Unless the classes are used on other elements too, writing th.from is redundant and can be shortened to just .from.
Oh my, this table-layout: fixed is a real gotcha! This answer should really be higher up.
22

Alternative way with just one class while keeping your styles in a CSS file, which even works in IE7:

<table class="mytable">
    <tr>
        <th>From</th>
        <th>Subject</th>
        <th>Date</th>
    </tr>
</table>
<style>
    .mytable td, .mytable th { width:15%; }
    .mytable td + td, .mytable th + th { width:70%; }
    .mytable td + td + td, .mytable th + th + th { width:15%; }
</style>

More recently, you can also use the nth-child() selector from CSS3 (IE9+), where you'd just put the nr. of the respective column into the parenthesis instead of stringing them together with the adjacent selector. Like this, for example:

<style>
    .mytable tr > *:nth-child(1) { width:15%; }
    .mytable tr > *:nth-child(2) { width:70%; }
    .mytable tr > *:nth-child(3) { width:15%; }
</style>

6 Comments

The proposed :nth-child solution is horrible in terms of performance. There is no valid reason to use it (especially with the universal selector) in this example where there are only three elements (th or col) to style. Additionally, you only need to set width to the th in the first row. The .mytable td in the first example is redundant.
"The proposed :nth-child solution is horrible in terms of performance." - citation needed.
This should be enough: Efficiently Rendering CSS. With your use of the universal selector the browser will first check ALL elements whether they are nth child of another element, then if their direct parent is tr and then whether they belong to .mytable. If you really want to use "nth" then something like this will probably be much better: .mytable th:nth-of-type(1) {width: 15%}; .mytable th:nth-of-type(2) {width: 70%};. There is also no need to specify the third column width in this case.
Personally I would use classes or just .mytable th+th{width: 70%}.mytable th+th+th{width:15%}. The "nth" selectors themselves may be very useful but in this particular case (a tiny table with only 3 columns) are not really needed. When using table-layout: fixed you can even do just this: table{table-layout:fixed}th:first-child+th{width:70%}.
I'm aware of that. But those articles are from years back, and there are bigger problems today that CSS selectors, like huge amounts of images and JS code.
|
16

These are my two suggestions.

  1. Using classes. There is no need to specify width of the two other columns as they will be set to 15% each automatically by the browser.

        table { table-layout: fixed; }
        .subject { width: 70%; }
        <table>
          <tr>
            <th>From</th>
            <th class="subject">Subject</th>
            <th>Date</th>
          </tr>
        </table>

  2. Without using classes. Three different methods but the result is identical.

    a)

        table { table-layout: fixed; }
        th+th { width: 70%; }
        th+th+th { width: 15%; }
        <table>
          <tr>
            <th>From</th>
            <th>Subject</th>
            <th>Date</th>
          </tr>
        </table>

    b)

        table { table-layout: fixed; }
        th:nth-of-type(2) { width: 70%; }
        <table>
          <tr>
            <th>From</th>
            <th>Subject</th>
            <th>Date</th>
          </tr>
        </table>

    c) This one is my favourite. Same as b) but with better browser support.

        table { table-layout: fixed; }
        th:first-child+th { width: 70%; }
        <table>
          <tr>
            <th>From</th>
            <th>Subject</th>
            <th>Date</th>
          </tr>
        </table>

Comments

9

Add colgroup after your table tag. Define width and number of columns here, and add the tbody tag. Put your tr inside of tbody.

<table>
    <colgroup>
       <col span="1" style="width: 30%;">
       <col span="1" style="width: 70%;">
    </colgroup>
    
    
    <tbody>
        <tr>
            <td>First column</td>
            <td>Second column</td>
        </tr>
    </tbody>
</table>

1 Comment

colgroup seems to only works when you set table-layout: "fixed" on the table using css. You also dont need the styles on the col. Afterwards, you specify the width as the colspan on the individual td cells eg <td colspan="3"></td>
6

Try this instead.

<table style="width: 100%">
    <tr>
        <th style="width: 20%">
           column 1
        </th>
        <th style="width: 40%">
           column 2
        </th>
        <th style="width: 40%">
           column 3
        </th>
    </tr>
    <tr>
        <td style="width: 20%">
           value 1
        </td>
        <td style="width: 40%">
           value 2
        </td>
        <td style="width: 40%">
           value 3
        </td>
    </tr>
</table>

Comments

6

    table { table-layout: fixed; }
    .subject { width: 70%; }
    <table>
      <tr>
        <th>From</th>
        <th class="subject">Subject</th>
        <th>Date</th>
      </tr>
    </table>

Comments

5

Depending on your body (or the div which is wrapping your table) 'settings' you should be able to do this:

body {
  width: 98%;
}

table {
  width: 100%;
}


th {
  border: 1px solid black;
}


th.From, th.Date {
  width: 15%;
}

th.Date {
  width: 70%;
}


<table>
  <thead>
    <tr>
      <th class="From">From</th>
      <th class="Subject">Subject</th>
      <th class="Date">Date</th>
    </tr>
   </thead>
   <tbody>
     <tr>
       <td>Me</td>
       <td>Your question</td>
       <td>5/30/2009 2:41:40 AM UTC</td>
     </tr>
   </tbody>
</table>

Demo

Comments

5

Here's another minimal way to do it in CSS that works even in older browsers that do not support :nth-child and the like selectors: http://jsfiddle.net/3wZWt/.

HTML:

<table>
    <tr>
        <th>From</th>
        <th>Subject</th>
        <th>Date</th>
    </tr>
    <tr>
        <td>Dmitriy</td>
        <td>Learning CSS</td>
        <td>7/5/2014</td>
    </tr>
</table>

CSS:

table {
    border-collapse: collapse;
    width: 100%;
}

tr > * {
    border: 1px solid #000;
}

tr > th + th {
    width: 70%;
}

tr > th + th + th {
    width: 15%;
}

Comments

5
<table>
  <col width="130">
  <col width="80">
  <tr>
    <th>Month</th>
    <th>Savings</th>
  </tr>
  <tr>
    <td>January</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>February</td>
    <td>$80</td>
  </tr>
</table>

Demo

2 Comments

The col width attribute is not supported in HTML5.
width attribute is indeed deprecated, still you can use width in CSS style as replacement.
3

Don't use the border attribute, use CSS for all your styling needs.

<table style="border:1px; width:100%;">
    <tr>
            <th style="width:15%;">From</th>
            <th style="width:70%;">Subject</th>
            <th style="width:15%;">Date</th>
    </tr>
... rest of the table code...
</table>

But embedding CSS like that is poor practice - one should use CSS classes instead, and put the CSS rules in an external CSS file.

1 Comment

I would suspect that the example code the OP and helpful stackoverflowians posted was for legibility and simplicity's sake, by no means an encouragement for inline styles.
-3
style="column-width:300px;white-space: normal;"

1 Comment

Hi - welcome to Stack Overflow. In general, answers with text (instead of just code) and some explanation are viewed as better than just code-only answers. Since this question is older and has a lot of other answers, they may help guide you in future answers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.