9

I have tables on my web page set to width:100%. This stretches the table to the full width of my page if needed, or causes the contents of the table to wrap if the page is too narrow. Everything in the table is kept in a grid.

Unfortunately, some issues arise if there are long words in the table which prevents the td from getting narrower. When this happens, the page starts to developing a horizontal scroll bar to accommodate the table, put other elements on the page, such as paragraphs, stay the width of the original page.

I tried to set the table to overflow:scroll to prevent the webpage from getting wider, limiting it to just the table, but this didn't fix the issue. I even tried overflow:hidden to see if it would respond, but I couldn't get it to work.

The overflow would work if I set the table to display:block, but I can't get the table rows and table data cells to stretch across the full table and maintain its table-like appearance.

Is it possible to always have a table be 100% the width of a page, and to use overflow scroll if the table exceeds this width?

I added this example below. It works nicely except when the page gets very narrow, like around 150px for this example. The table cells get so narrow that it can't wrap any more. I'd like for the table to overflow, but instead the whole page overflows.

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra. Fusce sit amet nisi sed ante semper porta non in velit. Aenean euismod finibus nibh id mollis. Duis finibus, urna eu gravida posuere, nisl tortor condimentum dui, sed suscipit ante lacus et augue. Vestibulum ut leo hendrerit, convallis lectus quis, mollis purus. Mauris vitae libero aliquam, porttitor nisi vitae, pellentesque odio. Mauris vestibulum lacinia sem. Aenean sit amet nulla ipsum. Mauris pellentesque dui feugiat odio feugiat, vel egestas eros pellentesque. Cras porttitor metus eu porttitor lacinia.</p>
<table style="width:100%;overflow:scroll;background:#555">
<tr><td>column one</td><td>column two</td><td>column three</td></tr>
</table>
5
  • Please include an example of the code you are having problems with in a minimal, reproducible example so we can see what is happening and be able to help. Commented Aug 31, 2020 at 7:31
  • put element with an ellipsis style inside the td Commented Aug 31, 2020 at 7:35
  • Maybe word-break is what you're looking for, or the white-space property Commented Aug 31, 2020 at 7:37
  • did you try overflow:auto? Commented Aug 31, 2020 at 7:44
  • @FluffyKitten example added. elad I'm not trying to cut off any text, just trying to make the table overflow. Itay and Hisham Bawa, unfortunately it did not resolve it. Commented Sep 1, 2020 at 8:22

4 Answers 4

9

You can't do it by changing display alone for the table, but there are a couple of ways you can achieve this.

1. Add a "scrolling" container div

You can up the standard table in a container div and give it the overflow: auto;, so it will have the scroll bar.

table          { width: 100%; }
.scrollwrapper { overflow: auto; }

This means the table will stretch to at least 100% of the width even if it is not wide enough on its own, and if the content makes it wider than 100% them the div gets a scrollbar.

Working Example:

table {
  width: 100%;
  border: 1px solid blue;
}

.scrollwrapper {
  overflow: auto;
}

td {
  border: 1px solid #aaa;
}
<h3>Scrolling Wrapper - Wide Table</h3>

<div class="scrollwrapper">
  <table>
    <tr>
      <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
      <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
      <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    </tr>
    <tr>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    </tr>
  </table>
</div>

<h3>Scrolling Wrapper - Narrow Table</h3>

<div class="scrollwrapper">
  <table>
    <tr>
      <td>Column 1</td>
      <td>Column 2</td>
      <td>Column 3</td>
    </tr>
    <tr>
      <td>Short text</td>
      <td>Short text</td>
      <td>Short text</td>
    </tr>
  </table>
</div>

2. Table with display:block

This doesn't do what you want, but lets look at why...

When you give the table display:block property, it adds the scrollbar to tables if they are wider than the available space, which is what you want. However as you noted, if the table isn't as wide as the available space, width:100% doesn't make the columns stretch to fill the width:

Working Example of display:block on tables

table {
  width: 100%;
  border: 1px solid red;
  overflow: auto;
  display: block;
}

td {
  border: 1px solid #aaa;
}
<h3>Display:Block - Wide Table</h3>

<table>
  <tr>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
  </tr>
  <tr>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
  </tr>
</table>

<h3>Display:Block - Narrow Table</h3>

<table>
  <tr>
    <td>Column 1</td>
    <td>Column 2</td>
    <td>Column 3</td>
  </tr>
  <tr>
    <td>Short text</td>
    <td>Short text</td>
    <td>Short text</td>
  </tr>
</table>

As we can see in the example above, the table is actually stretching to 100%, however because the table row and cells don't fill the table. This is when I discovered the tbody hack...

3. Table with Display:block and tbody "hack"

Note that this is very much a hack and I've no idea how well supported it might be!

While playing around with this, I realised that the problem is that the rows and cells are not acting as normal rows and cells because they are not in a parent with display:table.

That's when I discovered that when I added display:table to the tbody, it gave the rows and cells a parent with the correct display type and it worked!

table       { display: block; overflow: auto; }
table tbody { display: table; width: 100%; }

It seems to work even when the tbody is not explicitly added in the html.

Working Example of tbody hack

table {
  border: 1px solid blue;
  overflow: auto;
  display: block;
}

table tbody {
  display: table;
  width: 100%;
}

td {
  border: 1px solid #aaa;
}
<h3>Tbody "Hack" - Wide Table</h3>

<table>
  <tr>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
  </tr>
  <tr>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
  </tr>
</table>

<h3>Tbody "Hack" - Narrow Table</h3>

<table class="tbody-hack">
  <tr>
    <td>Column 1</td>
    <td>Column 2</td>
    <td>Column 3</td>
  </tr>
  <tr>
    <td>Short text</td>
    <td>Short text</td>
    <td>Short text</td>
  </tr>
</table>

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

2 Comments

This is perfect. Thank you very much. And your explanations really helped.
This should be canonical answer for this issue. The point 3 with tbody hack is very interesting, no need to add extra html markup, but it has some issues.
9

Using CSS grid.

.table-wrapper {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  overflow: auto;
  white-space: nowrap;
}
<div class="table-wrapper">
<table>
  <thead>
    <tr>
        <th>Head 1</th>
        <th>Head 2</th>
        <th>Head 3</th>
        <th>Head 4</th>
        <th>Head 5</th>
        <th>Head 1</th>
        <th>Head 2</th>
        <th>Head 3</th>
        <th>Head 4</th>
        <th>Head 5</th>
        <th>Head 1</th>
        <th>Head 2</th>
        <th>Head 3</th>
        <th>Head 4</th>
        <th>Head 5</th>
        <th>Head 1</th>
        <th>Head 2</th>
        <th>Head 3</th>
        <th>Head 4</th>
        <th>Head 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
    </tr>
  </tbody>
</table>
</div>

1 Comment

easiest, modern way
0

Would this work? The overflow will pop in if the width of the table is greater than the width of the <div>

<div id="table" style="width:200px">

  <table style="width:100%; overflow:auto;display:block">
    <tr>
      <th>header</th>
      <th>header</th>
      <th>header</th>
      <th>header</th>
      <th>header</th>
      <th>header</th>
    </tr>

    <tr>
      <td>body</td>
      <td>body</td>
      <td>body</td>
      <td>body</td>
      <td>body</td>
      <td>body</td>
    </tr>

  </table>

</div>

4 Comments

Not sure why display:block didnt work for you though
I'm not sure who down voted you but it wasn't me, though this solution didn't work. It overflows nicely, but it doesn't expand to the full width of the parent div if its wider than the table like if a normal table was set to width:100%.
Yeah fixed width I can imagine this would work. I have no clue myself why its not working
Could it have anything to do with the fact the parent is a container which has flex-grow on it?
0

The @FluffyKitten answer will not work properly if you have full HTML table markup including explicit thead and tbody tags. In such case columns and headers will not align properly:

table {
  border: 1px solid blue;
  overflow: auto;
  display: block;
}

table tbody, table thead {
  display: table;
  width: 100%;
}

td {
  border: 1px solid green;
  white-space:nowrap;
}

th {
  border: 1px solid red;
  white-space:nowrap;
}
<h3>Tbody "Hack" - Wide Table</h3>

<table>
  <thead>
  <tr>
    <th>col 1</th>
    <th>col 2</th>
    <th>col 3</th>
  </tr>
  </thead>
  <tbody>
  <tr>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
    <td>thisisoneverylongwordthatwillnotwrapinthetablecell</td>
  </tr>
  <tr>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
    <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent finibus nulla et lorem imperdiet, eu malesuada enim viverra.</td>
  </tr>
  </tbody>
</table>

<h3>Tbody "Hack" - Narrow Table</h3>

<table class="tbody-hack">
  <tr>
    <td>Column 1</td>
    <td>Column 2</td>
    <td>Column 3</td>
  </tr>
  <tr>
    <td>Short text</td>
    <td>Short text</td>
    <td>Short text</td>
  </tr>
</table>

Comments

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.