Hunter Turner Hunter Turner - 6 months ago 37
CSS Question

How to make table column's width only take necessary space with ellipsis overflow?

I would like my table to be 100% width, and for each column of the table to only take up the space it needs. If it overflows, then an ellipsis will appear.

Without Table-Layout: Fixed;



html, body {
margin: 0;
padding: 0;
font-family: sans-serif; */
}

.account-products-container .table {
width: 100%;
max-width: 100%;
margin: 20px 0;
border-collapse: collapse;
border-spacing: 0;
display: table;
table-layout: auto;
}

.account-products-container .table-striped>tbody>tr:nth-of-type(odd) {
background-color: #eee;
}

.account-products-container .table>thead>tr>th {
padding: 8px;
line-height: 1.428571429;
font-weight: 600;
text-transform: uppercase;
vertical-align: bottom;
border-bottom: 1px solid #DDD;
text-align: left;
}

.account-products-container .table>tbody>tr>td {
padding: 8px;
line-height: 1.428571429;
vertical-align: top;
border-top: 1px solid #DDD;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}

<div class="account-products-container">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Product</th>
</tr>
</thead>
<tbody>
<tr>
<td>123456789</td>
<td>This is the name of a product that is long</td>
</tr>
<tr>
<td>549490309</td>
<td>This is a product title that is even longer than the first one and longer than the second one because the second one is short, so of course it's longer.</td>
</tr>
<tr>
<td>005948333</td>
<td>This one is short</td>
</tr>
</tbody>
</table>
</div>





This is how I want the column's to look, but without
table-layout: fixed;
, the table overflows instead of resizing due to the
white-space: nowrap;
.

enter image description here

With Table-Layout: Fixed;



html, body {
margin: 0;
padding: 0;
font-family: sans-serif; */
}

.account-products-container .table {
width: 100%;
max-width: 100%;
margin: 20px 0;
border-collapse: collapse;
border-spacing: 0;
display: table;
table-layout: fixed;
}

.account-products-container .table-striped>tbody>tr:nth-of-type(odd) {
background-color: #eee;
}

.account-products-container .table>thead>tr>th {
padding: 8px;
line-height: 1.428571429;
font-weight: 600;
text-transform: uppercase;
vertical-align: bottom;
border-bottom: 1px solid #DDD;
text-align: left;
}

.account-products-container .table>tbody>tr>td {
padding: 8px;
line-height: 1.428571429;
vertical-align: top;
border-top: 1px solid #DDD;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}

<div class="account-products-container">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Product</th>
</tr>
</thead>
<tbody>
<tr>
<td>123456789</td>
<td>This is the name of a product that is long</td>
</tr>
<tr>
<td>549490309</td>
<td>This is a product title that is even longer than the first one and longer than the second one because the second one is short, so of course it's longer.</td>
</tr>
<tr>
<td>005948333</td>
<td>This one is short</td>
</tr>
</tbody>
</table>
</div>





This responds well, and has the ellipsis, but my column's no longer take up the minimal space.

enter image description here

I have included
width: 100%;
to my
<table>
hoping this would fix the problem, but it did not work.

How can I make the column's only take up the space they need, while having my table respond well?

If you want to play around with it: JSFiddle

Answer

You can

  • Use auto layout in order to take content into account
  • Set the width of the table to 100%. It will be treated as a minimum width.
  • Set the width of the second column to 100%. Then it will grow taking all available space, if any.
  • To prevent the second column from growing more due to the contents, wrap them inside absolutely positioned containers.

html, body {
  margin: 0;
  padding: 0;
  font-family: sans-serif; */
}

.account-products-container .table {
  width: 100%;
  max-width: 100%;
  margin: 20px 0;
  border-collapse: collapse;
  border-spacing: 0;
  display: table;
  table-layout: auto;
}

.account-products-container .table-striped>tbody>tr:nth-of-type(odd) {
  background-color: #eee;
}

.account-products-container .table>thead>tr>th {
  padding: 8px;
  line-height: 1.428571429;
  font-weight: 600;
  text-transform: uppercase;
  vertical-align: bottom;
  border-bottom: 1px solid #DDD;
  text-align: left;
}

.account-products-container .table>tbody>tr>td {
  padding: 8px;
  line-height: 1.428571429;
  vertical-align: top;
  border-top: 1px solid #DDD;
  cursor: pointer;
  white-space: nowrap;
}
td:nth-child(2) {
  width: 100%;
  position: relative;
}
td:nth-child(2):not(:empty)::after {
  /* Prevent row from collapsing vertically if the first column is empty */
  content: '';
  display: inline-block;
}
td:nth-child(2) > span {
  position: absolute;
  left: 0;
  right: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
<div class="account-products-container">
  <table class="table table-striped">
   <thead>
     <tr>
       <th>ID</th>
       <th>Product</th>
     </tr>
   </thead>
   <tbody>
     <tr>
       <td>123456789</td>
       <td><span>This is the name of a product that is long</span></td>
     </tr>
     <tr>
       <td>549490309</td>
       <td><span>This is a product title that is even longer than the first one and longer than the second one because the second one is short, so of course it's longer.</span></td>
     </tr>
     <tr>
       <td>005948333</td>
       <td><span>This one is short</span></td>
     </tr>
   </tbody>
 </table>
</div>