129

So I have this code here:

<table>
    <tr>
        <td width="200px" valign="top">
            <div class="left_menu">
                <div class="menu_item">
                    <a href="#">Home</a>
                </div>
            </div>
        </td>
        <td width="1000px" valign="top">Content</td>
    </tr>
</table>

with the CSS

.left_menu {
    background: none repeat scroll 0 0 #333333;
    border-radius: 5px 5px 5px 5px;
    font-family: Arial,Helvetica,sans-serif;
    font-size: 12px;
    font-weight: bold;
    padding: 5px;
}

.menu_item {
    background: none repeat scroll 0 0 #CCCCCC;
    border-bottom: 1px solid #999999;
    border-radius: 5px 5px 5px 5px;
    border-top: 1px solid #FFFFCC;
    cursor: pointer;
    padding: 5px;
}

It works fine on my browser and I have tested it in every browser both mac and PC, but someone is complaining that the td with the width of 200 keeps changing width. I have no idea what he is talking about. Does anyone know why he or she is seeing the width change on the td?

Allan Pereira
  • 2,572
  • 4
  • 21
  • 28
user979331
  • 11,039
  • 73
  • 223
  • 418
  • So how can we help when we have even less idea of what the complaint is about? We cannot even test the real page, and we have no information about the someone and his or her browsing environment. – Jukka K. Korpela Jun 18 '12 at 20:42

15 Answers15

157

It should be:

<td width="200">

or

<td style="width: 200px">

Note that if your cell contains some content that doesn't fit into the 200px (like somelongwordwithoutanyspaces), the cell will stretch nevertheless, unless your CSS contains table-layout: fixed for the table.

EDIT

As kristina childs noted on her answer, you should avoid both the width attribute and using inline CSS (with the style attribute). It's a good practice to separate style and structure as much as possible.

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • 62
    should the table be ``
    – user979331 Jun 18 '12 at 20:35
  • 4
    @user1193385, Yes, that's it. But avoid using inline css if possible. – bfavaretto Jun 18 '12 at 20:45
  • 4
    inline css is a bad idea unless you really only need it in one place. also, td width has been deprecated for some time. see answer below – kristina childs Jun 18 '12 at 20:46
  • 2
    @kristinachilds I agree. I used inline css on my example so I wouldn't need to split into two code blocks for HTML and CSS. Added a comment above telling the OP to avoid inline CSS. About the width attribute, technically it's not deprecated (since the HTML5 spec is still a working draft), but you are right it should be avoided. I'll edit my answer with a note about that. – bfavaretto Jun 18 '12 at 20:53
  • The formal incorrectness of the syntax in the code in the question in this respect has no impact on functionality on any browser that I know it. Setting `table-layout: fixed` is relevant if you want rigid layout, but browsers may still deviate from the widths set. – Jukka K. Korpela Jun 19 '12 at 04:40
  • @JukkaK.Korpela Yes, `width="200"` works and has always worked in all browsers, and I don't see they dropping support for it anytime soon (but it is bad practice nevertheless). And you got me curious about `table-layout:fixed`: when may browsers deviate from the widths set? I always see the whole table overflowing, but each cell seems to respect the width set. – bfavaretto Jun 19 '12 at 04:50
  • Simple solution: Use `` instead of td widths: https://stackoverflow.com/q/928849/3894981 – dude Jun 25 '21 at 18:17
40
 <table style="table-layout:fixed;">

This will force the styled width <td>. If the text overfills it, it will overlap the other <td> text. So try using media queries.

mateostabio
  • 958
  • 8
  • 11
39

Width and/or height in tables are not standard anymore; as Ianzz says, they are deprecated. Instead the best way to do this is to have a block element inside your table cell that will hold the cell open to your desired size:

<table>
    <tr>
        <td valign="top">
            <div class="left_menu">
                <div class="menu_item">
                    <a href="#">Home</a>
                </div>
            </div>
        </td>
        <td valign="top" class="content">Content</td>
    </tr>
</table>

CSS

.content {
    width: 1000px;
}

.left_menu {
    background: none repeat scroll 0 0 #333333;
    border-radius: 5px 5px 5px 5px;
    font-family: Arial,Helvetica,sans-serif;
    font-size: 12px;
    font-weight: bold;
    padding: 5px;
    width: 200px;
}

.menu_item {
    background: none repeat scroll 0 0 #CCCCCC;
    border-bottom: 1px solid #999999;
    border-radius: 5px 5px 5px 5px;
    border-top: 1px solid #FFFFCC;
    cursor: pointer;
    padding: 5px;
}
Timothy Lee Russell
  • 3,719
  • 1
  • 35
  • 43
kristina childs
  • 2,190
  • 1
  • 20
  • 19
  • 12
    Unfortunately, email technology is many years behind the current HTML spec, and in that case, tables and inline css are sadly, unavoidable. – Mike G Aug 13 '13 at 14:29
  • 2
    No one was talking about html emails, this was for basic desktop web browsing. But yes, for emails tables and inline css are the only way to build them. Thanks, Microsoft... – kristina childs Aug 13 '13 at 21:00
  • 4
    I only bring up email because that's what brought me here; I was having this same issue with email. – Mike G Aug 13 '13 at 21:13
20

This problem is quite easily solved using min-width and max-width within a css rule.

HTML

<table>
  <tr>
    <td class="name">Peter</td>
    <td class="hobby">Photography</td>
    <td class="comment">A long comment about something...</td>
  </td>
</table>

CSS

.name {
  max-width: 80px;
  min-width: 80px;
}

This will force the first column to be 80px wide. Usually I only use max-width without min-width to reign in text that is very occasionally too long from creating a table that has a super wide column that is mostly empty. The OP's question was about setting to a fixed width though, hence both rules together. On many browsers width:80px; in CSS is ignored for table columns. Setting the width within the HTML does work, but is not the way you should do things.

I would recommend using min and max width rules, and not set them the same but rather set a range. This way the table can do it's thing, but you can give it some hints on what to do with overly long content.

If I want to keep the text from wrapping and increasing the height of a row - but still make it possible for a user to see the full text, I use white-space: nowrap; on the main rule, then apply a hover rule that removes the width and nowrap rules so that the user can see the full content when they over their mouse over it. Something like this:

CSS

.name {
  max-width: 80px;
  white-space: nowrap;
  overflow: hidden;
}
.name:hover {
  max-width: none;
  white-space: normal;
  overflow:auto;
}

It just depends on exactly what you are trying to achieve. I hope this helps someone. PS As an aside, for iOS there is a fix for hover not working - see CSS Hover Not Working on iOS Safari and Chrome

SOKitsune
  • 325
  • 2
  • 5
8

You can use within <td> tag css : display:inline-block

Like: <td style="display:inline-block">

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
Siddharth Shukla
  • 1,063
  • 15
  • 14
7

You can't specify units in width/height attributes of a table; these are always in pixels, but you should not use them at all since they are deprecated.

lanzz
  • 42,060
  • 10
  • 89
  • 98
7

You can try the "table-layout: fixed;" to your table

table-layout: fixed;
width: 150px;

150px or your desired width.

Reference: https://css-tricks.com/fixing-tables-long-strings/

Cyan Baltazar
  • 3,462
  • 1
  • 17
  • 11
3

try this:

word-break: break-all;
Masoud HB
  • 78
  • 4
2

try to use

word-wrap: break-word;

hope this help

medhatdawoud
  • 1,168
  • 2
  • 12
  • 18
2

I use

<td nowrap="nowrap">

to prevent wrap Reference: https://www.w3schools.com/tags/att_td_nowrap.asp

user1760527
  • 1,144
  • 9
  • 14
1

If using table-layout: fixed is not an option for you, I would suggest wrapping your cell content in a div and then apply your desired dimensions to it like:

<td>
    <div style="min-width: 200px; max-width: 600px; width: max-content;">Your long paragraph goes here...</div>
</td>

In this approach td will fit to its child element (div) which is responsible for precisely keeping the dimensions.

Mohsen Taleb
  • 645
  • 5
  • 16
0

I tried with many solutions but it didn't work for me so I tried flex with the table and it worked fine for me with all table functionalities like border-collapse and so on only change is display property

This was my HTML requirement

<table>
  <thead>
    <tr>
      <th>1</th>
      <th colspan="3">2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td colspan="3">2</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td colspan="2">3</td>
    </tr>
  </tbody>
</table>

My CSS

table{
    display: flex;
  flex-direction: column;
}
table tr{
    display: flex;
  width: 100%;
}
table > thead > tr > th:first-child{
    width: 20%;
}
table > thead > tr > th:last-child{
    width: 80%;
}
table > tbody tr > td:first-child{
    width: 10%;
}
table > tbody tr > td{
    width: 30%;
}
table > tbody tr > td[colspan="2"]{
    width: 60%;
}
table > tbody tr > td[colspan="3"]{
    width: 90%;
}
/*This is to remove border making 1px space on right*/
table > tbody tr > td:last-child{
    border-right: 0;
}
Mohammed Yousuff
  • 122
  • 1
  • 1
  • 9
0

If you don't set the table to have table-layout: fixed and a certain width, then the table cells will stretch beyond their own width if content is wider. That's what he/she was complaining about.

dorsta
  • 81
  • 1
  • 6
-1

Note that adjusting the width of a column in the thead will affect the whole table

<table>
    <thead>
        <tr width="25">
            <th>Name</th>
            <th>Email</th>
        </tr>
    </thead>
    <tr>
        <td>Joe</td>
        <td>joe@email.com</td>
    </tr>
</table>

In my case, the width on the thead > tr was overriding the width on table > tr > td directly.

Nick Woodhams
  • 11,977
  • 10
  • 50
  • 52
-1

Use

<table style="table-layout:fixed;">

It will force table to set to 100% width.Then use this code

$('#dataTable').dataTable( {
        bAutoWidth: false, 
        aoColumns : [
          { sWidth: '45%' },
          { sWidth: '45%' },
          { sWidth: '10%' },
              ]
      });

(table id is dataTable and having 3 column) to specify length to each cell

Amrit Anand
  • 17
  • 1
  • 3