-1

I have a simple table with address and id:

table, td, th {
  border: 1px solid black;
}
table {
  table-layout: fixed;
  width: 300px;
}
.id-col {
  width: 10%;
  min-width: 40px;
}
<table>
  <tr>
    <th class="id-col">id</th>
    <th class="address-col">Address</th>
  </tr>
  <tr>
    <td>1934</td>
    <td>Fieldstone Drive North Miami Beach, FL 33160</td>
  </tr>
  <tr>
    <td>34</td>
    <td>Grove Street Macon, GA 31204</td>
  </tr>
</table>

As you can see, content in id column can overflow its table cell. I tried to fix it with min-width, but it seems not to work for tables.

I solved it with flexbox: https://jsfiddle.net/bkn37qtt/ Now it works as expected, but I am not sure that is good because I lost table semantics.

Is there a way to do it with table? Maybe I missed something, or anything changed since 2011 (when mentioned above question was asked)?

Community
  • 1
  • 1
just-boris
  • 9,468
  • 5
  • 48
  • 84

5 Answers5

1

Just drop the table-layout: fixed; and your are good to go.

Here I shortened column names as well, to make an empty content column smallest possible.

For users with bigger screen and where you can set wider table, you can add a media query to interact with an inner element of each header and set it to a fixed width, overflow hidden and ellipsis.

That will avoid the unwanted scroll to its maximum without the need of a fixed table.

.scroll-container {
  width: 300px;
  overflow-x: auto;
  border: 1px solid #eee;
}
table, tr, td, th {
  padding: 0;        /* remove padding/margin to make cells smallest possible */
  margin: 0;
}

table, td, th {
  border: 1px solid black;
}
table {
  max-width: 300px;
}
.id-col {
  width: 10%;
  /*min-width: 40px;    removed this as well to make it smallest possible *
}
<div class="scroll-container">
  <table>
  <tr>
    <th class="id-col">id</th>
    <th class="address-col">Address</th>
    <th>Col3</th>
    <th>Col4</th>
    <th>Col5</th>
  </tr>
  <tr>
    <td>1934</td>
    <td>Fieldstone Drive North Miami Beach, FL 33160</td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td>34</td>
    <td>Grove Street Macon, GA 31204</td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • I can't drop it because it is necessary for some reason. I don't want horizontal scroll, but table cause it sometimes – just-boris Dec 30 '15 at 10:25
  • @just-boris You can drop it, as using `table-layout: fixed;` means _Table and column widths are set by the widths of table and col elements or by the width of the first row of cells. Cells in subsequent rows do not affect column widths._ and you can read more about it here: https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout – Asons Dec 30 '15 at 10:29
  • @just-boris Show me how the table overflow cause scroll and I fix that for you, as the above answer is how to do what you ask. – Asons Dec 30 '15 at 10:36
  • Yes, I tried to do it: https://jsfiddle.net/8jg8msw0/ The thing is my real example has more columns rather than my initial question. – just-boris Dec 30 '15 at 10:38
  • @just-boris I assume you want all content visible, right?, so where do you want the scroll to appear when content doesn't fit the width? – Asons Dec 30 '15 at 10:44
  • In that case, I am able to add ellipsis to column headers. As I understand, my table is aligned by header content width. Can I say to table that header size doesn't matter for me? – just-boris Dec 30 '15 at 10:49
  • @just-boris Your table/cell size is content based, header also, so you can't say to header to shrink if empty content, and if setting a max-width to header will clip content too. So if this is what you want you need a script to check if there is content and set header accordingly. ... If not script is an option, I updated my answer and took out any padding and shortened header text in a way you might could too, to make a column smallest possible when no content. – Asons Dec 30 '15 at 11:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/99298/discussion-between-just-boris-and-lgson). – just-boris Dec 30 '15 at 11:12
  • @just-boris Updated my answer with something that might be interested, still, what you suggested in the chat will work good as well. – Asons Dec 30 '15 at 11:48
  • To summarize our discussion, I'd say that I have chosen to use `table`, but override display to `flexbox`: https://jsfiddle.net/8jg8msw0/4/ It doesn't do any predictions for column widths, just follows my rules. – just-boris Dec 30 '15 at 12:45
0

Try like this:

<html>
<style>
table, td, th {
border: 1px solid black;
}
table {
width: 300px;
}
.id-col {
width: 10%;
min-width: 40px;
}
</style>
<table>
    <tr>
        <th class="id-col"><span>id</span></th>
        <th class="address-col">Address</th>
    </tr>
    <tr>
        <td>1934</td>
        <td>Fieldstone Drive North Miami Beach, FL 33160</td>
    </tr>
    <tr>
        <td>34</td>
        <td>Grove Street Macon, GA 31204</td>
    </tr>
</table>
</html>
soorapadman
  • 4,451
  • 7
  • 35
  • 47
0

If I understood correctly, You do not need fixed layout for table because ideally the table behaviour is the release the available space to the next available cell. Also you just need to get rid of any of these classes which you have added to TH to control width. Because think about a scenario when you have bigger text without spaces. It will screw design. Hence I have made changes to your codes to be more responsive.

CSS:

table, td, th {
  border: 1px solid black;
}
table {
 width: 300px;
}
table tr>th:first-of-type,table tr>td:first-of-type{
  min-width: 40px;
  max-width:80px;
  word-break: break-all;
}

HTML:

<table>
  <tr>
    <th >id</th>
    <th >Address</th>
  </tr>
  <tr>
    <td>1984</td>
    <td>Fieldstone Drive North Miami Beach, FL 33160</td>
  </tr>
  <tr>
    <td>34</td>
    <td>Grove Street Macon, GA 31204</td>
  </tr>
  <tr>
    <td>123218736218736</td>
    <td>Fieldstone Drive North Miami Beach, FL 33160</td>
  </tr>
</table>

DEMO

Cheers,

Ashok

0

After some discussions, I came up with the solution that flexboxes properly solves my issue

  • I need to specify proportional sizes of columns
  • I don't want columns to grow and overflow container (Tables without table-layout: fixed do it sometimes)
  • I don't care about fit table head content. It is okay for me to add ellipsis
  • I want to set minimal size for each column to prevent collapsing cell content

The markup on divs with display: flex solves this issues better, so if you have a similar issue with my, use flexboxes for it.

Here is my final version: https://jsfiddle.net/8jg8msw0/5/

P.S. Also it worth to note that you have to specify size for each row. With table, it is enough just set it on header.

just-boris
  • 9,468
  • 5
  • 48
  • 84
-1

My Modification:

Use padding
Use Colgroup
Increase id-col percentage
and finally remove table-layout

      table, td, th {
        border: 1px solid black;
        padding:2px;
      }
      table {
        /*table-layout: fixed;*/
        width: 300px;
      }
      .id-col {
        width: 15%;
        min-width: 40px;
      }
<table>
    <colgroup>
      <col class="con1" style="align: center; width: 15%" />
      <col class="con1" style="align: center; width: 80%" />    
    </colgroup>
    <thead>      
      <tr>
        <th class="id-col">id</th>
        <th class="address-col">Address</th>
      </tr>
    </thead>  
    <tbody>    
      <tr>
        <td>1934</td>
        <td>Fieldstone Drive North Miami Beach, FL 33160</td>
      </tr>
      <tr>
        <td>34</td>
        <td>Grove Street Macon, GA 31204</td>
      </tr>
    </tbody>
  </table>
Uttam Kumar Roy
  • 2,060
  • 4
  • 23
  • 29