How to prevent HTML tables from becoming too wide

The layout model of tables differ from that of block level elements in that they will normally expand beyond their specified width to make their contents fit. At first that may sound like a good thing – and it often is – but it makes it possible for oversized content to make text unreadable or completely break a site’s layout, especially in Internet Explorer.

This happened to me recently when a client’s legacy content, which contains some layout tables, was injected into the CSS-based layout I had built. It worked well in most cases, but some of the old documents have very long URLs that the browser can’t break. I needed to find a solution to that problem.

View Example 1 to see what I mean. Not very pretty.

Your first instinct is probably to do what I did: start hacking away at the CSS. How about giving overflow:hidden a try? Nope, nothing happens. What if I give the table a different width? No, it doesn’t budge. But there is a solution.

The trick is to use the CSS property table-layout. It can take three values: auto, fixed, and inherit. The normal (initial) value is auto, which means that the table width is given by its columns and any borders. In other words, it expands if necessary.

What you want to use is table-layout:fixed. Bam! Now the table is as wide as you have specified in the CSS. No more, no less. And to my great surprise this seems to be widely supported by browsers. The only browser of any significance that does not support it is IE/Mac, and the significance of that browser is rapidly approaching zero. Check it out for yourself in Example 2.

Next is deciding what to do with the content that doesn’t fit in the table anymore. If the table only contains text, word-wrap:break-word (word-wrap is specified in the CSS3 Text Effects Module) will force the browser to break words as necessary to prevent overflow. The result can be seen in Example 3.

Unfortunately that currently only works in IE/Win, Safari, and Shiira (imagine that… IE/Win, even version 6, is ahead of Firefox in supporting a CSS property).

A compromise is needed for the browsers that don’t support word-wrap. The choices are to either let the content overflow and collide with the other stuff on the page, or to use overflow:hidden to hide it. Which solution is more appropriate will vary from case to case. I went with overflow:hidden, the effect of which you can see in Example 4.

Sorry if this is old news to some of you, but since I only recently discovered this very useful property I thought it would be worthy of a quick write-up.

Update (2007-04-26): Ok, I’ve done some quick testing with overflow:auto. The only browser that handles it properly is Safari (and others based on WebKit). It acts exactly as you would expect it to when setting overflow:auto on table tells, only displaying a horizontal scrollbar when it is needed. In the others either nothing at all happened or things went completely mad.

In other words browser support doesn’t seem to be there for overflow:auto to be a real option.

I also tested overflow:hidden on table cells with over-wide content in other columns than the last one, and noticed no problems anywhere, so that option seems pretty safe.

Update (2009-08-25): Firefox 3.5 now supports word-wrap:break-word and displays Example 3 the same as Safari and IE.

Translations

This article has been translated into the following languages:

Posted on April 25, 2007 in CSS

Comments

  1. Oh, thanks for that. I did not know of this solution, it could be very useful in future.

  2. Cool, I hadn’t noticed the table-layout property before.

    I suppose you could use a DOM script to detect large links and cut out the middle? Kind of like I do the the shrinkUrl function for adding links to quotes, but you’d need to do a bit more work to detect the right elements.

  3. Very very nice. Too many times have I come across this ‘lil bugger. I never thought to play around with table-layout: fixed. I’ll have to experiment with that on my next project where I come across this problem. Rock on. :]

  4. Many might be surprised to find that IE generally does a better job at handling text (like decent support of soft hyphens, the example you gave above, and the completely non-standard but incredibly useful text-overflow:ellipsis).

    Much of the stuff that IE4-6 had was designed for building desktop-like interactions in a web environment. As much as people like to hate on Microsoft for it’s crappy standards-support, it was still a decent platform for building web applications.

  5. Yes, I read that table-layout is very useful property in Eric’s “CSS: The Definitive Guide” This is another thing that Eric said:

    With a fixed-width table layout, the user agent can calculate the layout of the table more quickly than is possible in the automatic-width model.

    And, you Rojer just have found very good application of it. The situation with clients, that you described, happens very frequently. So, thank you! And another idea come to my mind: is it posibble to make table overflow: scroll? May be it is better than hidden. Or you prefer to show on purpose to client that he insert not suitable content? What you think?

  6. Jonathan: It has since been added to Safari as well. Still impressive it’s been in IE for so long, didn’t know.

  7. Luckily I have managed to avoid this conundrum but I will bear this solution in mind should I encounter it in the future. Thanks.

  8. April 25, 2007 by BillyG

    Thx, very timely for my current side-project.

    Hint: you may wanna checkout your demo sidebar again. I have no idea what any of this drunk jibberish is:

    To problems of corruption by imperfect. Have a quite different significance when encoded and so may NEVER be encoded?

    Intended as such must always be encoded as its presence otherwise always. While leaving already encoded characters. , awkward in a given environment Because a % sign always! Not followed by two hexadecimal characters are reserved for future extension (See. But are not followed by two hexadecimal characters are reserved for future extension (See Example. Significance when encoded and so may NEVER be encoded. Otherwise always indicates an encoding Sequences.

  9. Ah, finally, a nice solution to a problem that I haven’t been able to solve in the past. Thank you.

  10. Thank you. I have come across this problem once.

  11. Thanks for this post, I’ve been running into this problem for ages now and haven’t found a satisfactory cross-browser solution. Overflow:hidden probably won’t cut it with our clients, but it’s always an option.

  12. Very nice, Roger! I must say I’ve stumbled upon similar things before, but I’ve never had it be such a problem that I’ve needed to find a solution. But this is quite elegant!

    Regarding the use of overflow: hidden/scroll. If “scroll” would work, I think I’d rather use “auto” to prevent having scrollbars present at all times. Did you have a chance to test this Roger? Instead of just hiding the content I mean.

  13. In regard to word-wrap, “Unfortunately that currently only works in IE/Win, Safari, and Shiira (imagine that… IE/Win, even version 6, is ahead of Firefox in supporting a CSS property).” It’s not so much that Firefox is behind, but that it’s an IE proprietary property that’s being adopted by the community.

    IE does have some good features. If only they would add the 50%+ of css 2.1 they don’t support.

    cheers,

    gary

  14. Had this same issue a couple of months ago - and came up with the same solution! Nice to see that others have come up with the same.

  15. Great article. Given I never work with tables other than for data, I usually have to reach for the handbook when I do use them and a few of the things you mention are going to be really helpful. Thanks

  16. Thanks for the write-up! A very useful technique to keep in mind.

  17. I’m surprised to hear you’re just learning of this Roger.

    Regarding what to do with the unbreakable text, if it is something you can control the output of from the server, you could cut it off at a specified length and use an ellipse to show it’s cut off, and a title attribute to provide the full text.

    If I remember correctly as well from the last time I dealt with data tables, the overflow:hidden did not work properly cross browser on table cells, so the content within each cell had to be wrapped within another tag (I believe I used a span). You didn’t run into this issue with your examples because you simply used overflow on the table and not each table cell. I think your example would change a bit if the long text was in the first column not the last.

    Something else to keep in mind when using table-layout: fixed is that if you have explicit widths set on all your columns and they do not add up to the width you set on the table itself, the browser might ignore the fixed table layout and revert to auto.

  18. Regarding “word-wrap:break-word” not being supported in Firefox. There’s an article that suggest placing “” tags where you would want the long string to break and supposedly Firefox is one of few browser that supports this tag.

    http://tinyurl.com/2667my

  19. Sorry the tag I mention didn’t come through in my comment field. I was referring to the “WBR” tag.

  20. April 26, 2007 by Roger Johansson (Author comment)

    AlastairC:

    I suppose you could use a DOM script to detect large links and cut out the middle?

    Yeah, that’s one possible solution, but I prefer not removing content, at least in this case.

    warmrobot:

    is it posibble to make table overflow: scroll? May be it is better than hidden. Or you prefer to show on purpose to client that he insert not suitable content? What you think?

    I’d go with overflow:auto instead, but I haven’t really tested it. I’ll try to find time to do that tonight.

    I’m all for actively making incorrect markup or “wrong” content appear wrong to the client since it gives them the chance to correct it.

    BillyG:

    Hint: you may wanna checkout your demo sidebar again. I have no idea what any of this drunk jibberish is:

    That’s instead of the standard lorem ipsum. I got it from some online generator (don’t remember the URL).

    Frode: See above - I’ll try to find time to test overflow:auto.

    Gary:

    It’s not so much that Firefox is behind, but that it’s an IE proprietary property that’s being adopted by the community.

    Good point.

    Jeff L:

    I’m surprised to hear you’re just learning of this Roger.

    I almost never have to work with layout tables, so I didn’t have a reason to look into this before :-).

    Good tips about overflow:hidden on tables vs. table cells. I’ll look into that as well.

    soxiam: There will be no invalid wbr tags in my code ;-).

  21. word-wrap:break-word is a great way of protecting your floated layouts from breaking in IE. If a box [erroneously] expands to accommmodate a reall really long word (realistically, likely to be a gigantic amazon-style URL) it might force a box floated to the right of it to drop down, breaking your layout.

    It’s IE-specific pseudo-CSS, that solves an IE-specific problem. So hide it in a conditional comment, if necessary.

  22. To be quite honest I never use this. Haven’t really run in to it. I found it a while ago but haven’t used it since.

    If I would have needed it again I’m not sure if I would heve remembered it. Thanks for the reminder.

  23. Thanks for this, could have been useful to me in the past, and surely will come in handy in the future.

    One thing though, I’m coding a newsletter at the moment, and the table-based-layout completely breaks in both thunderbird and gmail. I tried adding table-layout: fixed; to the main-table and then it looks ok, but there’s no way to set different widths for the table-cells (it’s a 2-column layout). They automatically become exactly 50% each, regardless of what i say in my inline-styling.

    Is that a feature? Or a bug? Any way to fix?

    Thanks

  24. Ok, found the answer right here: CSS Property: table-layout “fixed - column widths is determined by the cells in the first row only.” Sorry to double-post.

  25. Interesting examples, I’ve googled before since I had a similar issue like this one, but this is a very nice article to sum it all in one place

  26. Great post Roger.

    Sorry if this is old news to some of you, but since I only recently discovered this very useful property I thought it would be worthy of a quick write-up.

    Don’t ever worry about posting something that may seem trivial. You just go right ahead and continue sharing these useful nuggets of information.

  27. Roger, Thanks for the tip. I rarely work with tables myself and ran into same problem recently. Legacy data tables in my new CSS-based layout. This would have come in handy a few weeks ago.

  28. I’ve always seemed to overlook that property because I didn’t think IE had support for it. Shame on me. Thanks for the heads up!

  29. Thanks, I was a little shady on the behavior of the table-layout property. Good to know.

    In similar situations, I have always questioned the value of having the url itself generate as the text string. Instead of actually displaying the url as the link, you could use an icon or generic text like “visit web site” in it’s place.

  30. Thanks Roger, That is pretty cool that the time to render the table will be less. I generally don’t use tables too often but I may have to apply this CSS to .NET controls that render specifically as tables.

  31. If you wrap the table into a extra DIV and apply overflow:auto for that DIV the horizontal scroll bar appear in Firefox, and you don’t miss the overlapping content. I’ve hosted a showcase at: http://www.maujor.com/temp/table.html

    I have used inline style in the extra DIV for the sake of clarity.

  32. @Mauricio Samy Silva: great example, thanks for taking the time to share :)

  33. April 28, 2007 by whiskey

    What if the table is intricately more complex?

    I have noticed this in the past with a site design i had to work with, where the client’s documents had been already converted to html via the software they used to create them (MS stuff).

    I finally got them around the idea of making the document available outside the site frame. This was done by simply creating a link to the resource where the information was held, as annex documents rather than inline inserts. So you would end up with a document that had the correct layout and, when needed, could open a new browser window with a data table that could be easily read.

    If the file has to be printed or downloaded, a copy of the original in pdf format was offered so people could still get a hard copy with no mysterious misleading links on it. (I realize that this is not your case, I’m just telling you mine).

    Thanks for the tips…

  34. April 28, 2007 by Wulf

    In case anybody wants to help out, or vote for it (not that voting isn’t helping out), there’s a bug (99447) regarding word-wrap over at Bugzilla@Mozilla.

  35. April 30, 2007 by Steve Avery

    Great article.

    Thought I’d play around for 5 minutes with the styles to hopefully fix it for Firefox and noticed that if you add display: block; to the table declaration in the CSS then all the content for the last coloumn appears. However the content does seem to wrap the full width of the table. (But at least we can now see all the content.)

    I couldn’t seem to constrain the table widths even with adding !important to the declaration to tidy them up.

    Tested this in IE6 & IE 7 and adding the display: block; didn’t affect these browser, but it did interestingly have an affect with Safari. It now displays the content in the same manner as Firefox. If i find some more time later I’ll play around a little more and repost but for now I think this has helped to display the content.

  36. April 30, 2007 by Ty tzmedia

    If you can’t dump the html tables then some table-layout css “smack-down” on it’s candy ass, is indeed called for!! Thanks Roger, I too had never noticed this CSS property and can see a time, it might come in handy for sure. I’m tables free for well over a year, but there are evil tables layouts lurking everywhere :(

  37. One (rather hacky) solution to the word-wrap problem that we use for the app I work on is a script that inserts <wbr> tags into the text every few characters. This of course is only used for potentially long strings in certain situations, but seems to be a good stop-gap solution until there’s more CSS3 support.

  38. Oh whoops I missed soxiam’s comment. Sorry bout that. But I second the suggestion :)

  39. I have come across this same problem recently as well…the CSS3 word-break option is the best, but is not supported in FF 2.0…among others.

    We opted for a “panning” function which scrolls the hidden text into view when the mouse is over that element.

  40. Another way is to put div element inside of problematic td where text cuttig is done, or to use readonly text input element with specified width.

    For example visit my site please.

  41. table-layout:fixed

    Never thought about it, thanks for sharing.

  42. Thank you so much for this. It’s a problem I’ve had from time to time and no hacking in the world has helped to fix it. This is great information to know, works like a charm.

  43. Roger, this is an excellent solution to a problem seen in forums especially (where the whole thread is one huge table), and exactly what was needed for a project I’m involved with, many thanks :)

    Now I just need to convince the other developers that tables are for tabular data; slightly more tricky.

  44. May 16, 2007 by Don Draper

    This was exactly what I needed. I had a very wide, data-driven table to display and wanted to enclose it in a DIV using OVERFLOW:Auto with a 100% width and 500px height. Even thought the scroll bars were rendered around the DIV, the wide table content pushed the right edge of the DIV well past the normal screen width. This would force the user to have to scroll to the right using the browser’s horizontal scroll bar before the vertical scroll bar on the DIV could be seen. This was not very friendly and quite unacceptable.

    This was resolved by using the table-layout:fixed with a 100% width on the table that immediately enclosed the DIV. The table now expands to 100% of its parent cell without pushing wider and the width of the DIV area also stays the same width. The vertical scroll bar on the right edge of the DIV is always visible on the right side of the page. Thanks for sharing this invaluable tip.

  45. June 12, 2007 by developer

    do you think all these story works for a developer

  46. June 14, 2007 by AaronZ

    I would like to thank you for this. I had a table with Excel like functionality (frozen header, 2 frozen columns, scrolls both horz/vert) inside a table with 2 columns. This nifty scrolly table shoved the contents off the page with what seemed like “phantom space” to the right. The table-layout:fixed solved it.

    KUDOS!

  47. Thanks for this article. Just a note that to get table cell widths to ‘stick’ after you use the table-layout: fixed rule, you need to use colgroup and col elements in your table to set cell widths.

  48. Have many problems in FF, Have you checked it?

  49. July 5, 2007 by Roger Johansson (Author comment)

    conan1212: What kind of problems?

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.