HarshVardhan Bandta
HarshVardhan Bandta

Reputation: 139

Change table structure for mobile using single markup

I have a simple bootstrap table(as in the code below). I want that in my mobile view each row entry should be displayed separately inside a box or a card. For example, First card -

First: Mark
Last : Otto
Handle: @mdo

Second card-

First:Jacob
Last:Thornton
Handle:@fat

and so on. Is it possible to manipulate this design without having to write separate HTML for mobile view? Either through css or javascript? ( I am using bootstrap 4)

<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col">Handle</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Mark</td>
      <td>Otto</td>
      <td>@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jacob</td>
      <td>Thornton</td>
      <td>@fat</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td>Larry</td>
      <td>the Bird</td>
      <td>@twitter</td>
    </tr>
  </tbody>
</table>

Upvotes: 2

Views: 497

Answers (1)

Olian04
Olian04

Reputation: 6872

You can simply restyle each element the way you like them to look. However you can't insert information unless it's static, or present as an attribute on an element, that's why I've inserted the col attribute on each td element. For example:

document.getElementById('toggle').onclick = () => {
  const table = document.getElementById('table');
  table.classList.toggle('cards');
}
.cards thead {
  display: none;
}

.cards tr {
  display: flex;
  flex-direction: column;
  
  margin-bottom: 5px;
  border: 1px solid black;
}

.cards tr > th {
  display: none;
}

.cards tr > td::before {
  content: attr(col) ': ';
  font-weight: bold;
}
<button id="toggle">Toggle Style</button>
<table class="table" id="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col">Handle</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td col="First">Mark</td>
      <td col="Last">Otto</td>
      <td col="Handle">@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td col="First">Jacob</td>
      <td col="Last">Thornton</td>
      <td col="Handle">@fat</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td col="First">Larry</td>
      <td col="Last">the Bird</td>
      <td col="Handle">@twitter</td>
    </tr>
  </tbody>
</table>

Q: How can I increase the space between the heading and data in the flex view?
A: By adjusting the padding on the right hand side of the ::before element.

document.getElementById('toggle').onclick = () => {
  const table = document.getElementById('table');
  table.classList.toggle('cards');
}
.cards thead {
  display: none;
}

.cards tr {
  display: flex;
  flex-direction: column;
  
  margin-bottom: 5px;
  border: 1px solid black;
}

.cards tr > th {
  display: none;
}

.cards tr > td::before {
  content: attr(col) ': ';
  font-weight: bold;
  padding-right: 100px;
}
<button id="toggle">Toggle Style</button>
<table class="table" id="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col">Handle</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td col="First">Mark</td>
      <td col="Last">Otto</td>
      <td col="Handle">@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td col="First">Jacob</td>
      <td col="Last">Thornton</td>
      <td col="Handle">@fat</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td col="First">Larry</td>
      <td col="Last">the Bird</td>
      <td col="Handle">@twitter</td>
    </tr>
  </tbody>
</table>

Upvotes: 3

Related Questions