Daniel Däschle
Daniel Däschle

Reputation: 807

Responsive table with first column minimum width; second column stretch; third column always at the end; how can i do that?

I need a table in html

The mockup below shows which cases should be covered.

  1. The table shouldn't overflow the screen, even on small devices (mobile support)
  2. The first row should be as small as possible (width); The smalles width is the width of the biggest element in it
  3. The second column should stretch over the rest of the space
  4. The third column should be always at the end and shall be small as possible (like the first column)
  5. The height of a row should be dynamic
  6. All cells of a row should be in one line / should have the same height

I tried it already with flex and table

Some specials

Responsive table

Edit 15/01/2020

Those elements in the second column shouldn't break and the table shouldn't scroll on mobile view. Otherwise all items in the second column should truncate.

I already found the solution (below) but if someone have the same result without grid - you're welcome!

Upvotes: 0

Views: 2252

Answers (5)

bron
bron

Reputation: 1548

This html and css will match your requirements. Note that the parent div around the table is required.

Update

  • You'll find a JSFiddle on https://jsfiddle.net/uwpLrd1e/
  • <th> will center text by default. Use text-align:left to align it left.
  • Add padding, colors and borders wherever you wish.
  • Please use padding (not margin) because margin will overflow the width.

.

<div class="table-wrapper">
  <table>
    <tbody>
      <tr>
        <td>23:59</td>
        <td>Second column</td>
        <td>[]</td>
      </tr>
      <tr>
        <td>1:11</td>
        <td>Column 2 on row 2</td>
        <td>[X]</td>
      </tr>
    </tbody>
  </table>
</div>

/* table wrapper is required!! */
.table-wrapper {
  max-width: 100%;
}
.table-wrapper,
.table-wrapper * {
  box-sizing: border-box;
}
table, thead, tbody, tr {
  width: 100%;
}
table {
  max-width: 100%;
  border-spacing: 0;
  border-collapse: collapse;
  background-color: transparent;
}
th, td {
  vertical-align: top;
  border-left: 1px solid #ccc;
  line-height: 1;
  hyphens: auto;
  white-space: normal;
}
th:first-child,
td:first-child {
  border-left: 0;
}
/* stretch middle column (of three columns) */
th:nth-child(2),
td:nth-child(2) {
  width: 99.99%;
}
/* mobile support */
@media (max-width: 767.9px) {
  table {
    display: block;
    border: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    -ms-overflow-style: -ms-autohiding-scrollbar;
  }
  th, td {
    font-size: 95%;
  }
}

Upvotes: 1

Daniel D&#228;schle
Daniel D&#228;schle

Reputation: 807

The final solution:

CSS Grid (93.43% support)

.flex {
    display: flex;
    flex-wrap: wrap;
    overflow: hidden;
}

.item {
    margin-right: .6em;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

.my-grid {
    display: grid;
    grid-template-columns: max-content auto max-content;
    grid-gap: .6rem;
}
<div class="my-grid">

    <!-- first row -->
    <span>first column</span>
    <div class="flex">
        <div class="item">some div with very looooong content that truncate</div>
        <div class="item">some div with very looooong content that truncate</div>
    </div>
    <div>here some actions</div>

    <!-- second row -->
    <span>first column</span>
    <div class="flex">
        <div class="item">some div with very looooong content that truncate</div>
        <div class="item">some div with very looooong content that truncate</div>
    </div>
    <div>here some actions</div>

</div

Upvotes: 0

G-Cyrillus
G-Cyrillus

Reputation: 106008

You can also relay on the table-layout set to auto(default value) and set width to 0 for the first and last td, so it will expand only to the width needed by its content. the middle td will span the entire space left. it requires to set a width to table.

example

table {
  width: 100%;
  border: solid 1px;
  table-layout:auto;
}

th,td {
  border: solid 1px;
  padding: 0.25em
}

tr > :first-child,
tr > :last-child {
  width: 0 ; /* !! make sure table-layout is set to auto */
  /* white-space : nowrap; could be handy here */
}
<table>
  <tr>
    <td><input value="input"></td>
    <td> use room left</td>
    <td><input type="checkbox"></td>
  </tr>
</table>
<hr>
<table>
  <tr>
    <th>A.1</th>
    <td> use room left</td>
    <td>(....)</td>
  </tr>
  <tr>
    <th>A.2</th>
    <td> </td>
    <td> </td>
  </tr>
  <tr>
    <th>A.3</th>
    <td> use room left</td>
    <td>( / )</td>
  </tr>
</table>
<hr>
<p>to clear some question via a visual: </p>

<table>
  <tr>    
    <td>What if only 2 cells </td>
    <td> </td>
  </tr>
</table>
<hr>

<table>
  <tr>  
    <td> </td>  
    <td>What if only 2 cells </td>
  </tr>
</table>
<hr>

<table>
  <tr>    
    <td>What if only 1 cell</td>
  </tr>
</table>

https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout

The table-layout CSS property sets the algorithm used to lay out <table> cells, rows, and columns.

auto

By default, most browsers use an automatic table layout algorithm. The widths of the table and its cells are adjusted to fit the content.

Upvotes: 0

Alexandru Iancu
Alexandru Iancu

Reputation: 71

You can also use the table method without losing the responsiveness and with a second column that stretches even though its width was not specified.

In my code, the table stretches to 100% of its parent, which is the body. Make sure that the parent of your table will have a defined width.

<table cellspacing="0">
  <tr>
    <th>Time column</th>
    <th>Column 2</th>
    <th>Column 3</th>
  </tr> 
  <tr>
   <td>3:00</td>
    <td>Longer text for a longer column</td>
    <td><input type="checkbox"></td>
  </tr>
  <tr>
    <td>11:00</td>
    <td>Longer text for a longer column</br>and a row break</td>
    <td><input type="checkbox"></td>
  </tr>
  <tr>
   <td>06:00</td>
    <td><div>Here's a div containing a <span style="color: red;">span</span></div></td>
    <td><input type="checkbox"></td>
  </tr>
</table>

table, td, th {
  border: 1px solid white;
  background: orange;
}

table {
  width: 100%;
}

tr td:first-of-type, tr td:last-of-type { 
  width: 1px;
  text-align: center;
}

This codePen is also styled, you can test the table's responsiveness by resizing the window: https://codepen.io/ialexandru/pen/mdyKqRX

Upvotes: 1

Alisson R. Galindo
Alisson R. Galindo

Reputation: 50

If I understood correctly you can try this:

<table class='table'>
  <thead>
    <th class='time'>time</th>
    <th class='text'>information</th>
    <th class='actions'>actions</th>
  </thead>
  <tbody>
    <tr>
      <td>04:00</td>
      <td>
          <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer blandit consequat dui, id lacinia est. Integer blandit, felis nec condimentum ornare, ex diam cursus leo, id rutrum dolor nibh vel libero. Integer ut augue semper, convallis libero id, finibus ipsum. Cras nec metus bibendum, dictum mi ut, ullamcorper lectus.           </span>
      </td>
      <td>
        <button>Action</button>
      </td>
    </tr>
  </tbody>
</table>


.table
  text-align: left
  width: 100%
  .time 
    min-width: 30px
    max-width: 50px
  .actions
    min-width: 80px //This value is a example

You can test: https://codepen.io/AlissonRGalindo/pen/VwYdMRm

Upvotes: 1

Related Questions