Search code examples
htmlcsscss-grid

mobile adaptive tables on grid


I have a table built on grid. And I want to make this table adaptive. Adaptive for mobile devices. I do not know how I can do this using a grid-based table. Please tell me how I can adapt it for mobile screens? auto-fill is not exactly what you need. It simply moves blocks down, similar to flex wrap. With display:table, this is easier. Help me please.

.table {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-gap: 1px;
}

.table_unit {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background-color: #FAFAFA;
  padding: 20px 20px 20px 20px;
}

.table_content {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background-color: #F0F6F8;
  padding: 20px 20px 20px 20px;
}
<div class="table">
  <div class="table_unit">
    <p>This is text</p>
  </div>
  <div class="table_unit">
    <p>This is text</p>
  </div>
  <div class="table_unit">
    <p>This is text</p>
  </div>
  <div class="table_unit">
    <p>This is text</p>
  </div>
  <div class="table_unit">
    <p>This is text</p>
  </div>
  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <p></p>
  </div>
  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <p></p>
  </div>

  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <p>Simple text</p>
  </div>
  <div class="table_content">
    <input type="submit" class="log_button_replace" value="Simple button">
  </div>
</div>


Solution

  • You could add a extra p element in .table_content element which will only be visible on small screens. Add a media query which on smaller screens, will make .table element a grid of 1 column and .table_column element a grid of 2 columns.

    P.S. In code snippet below, i have removed empty columns.

    .table p {
      margin: 0;
    }
    
    .table {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-gap: 1px;
    }
    
    .table_unit {
      display: flex;
      justify-content: center;
      align-items: center;
      text-align: center;
      background-color: #FAFAFA;
      padding: 20px;
    }
    
    .responsive-header {
      display: none;
      background: #fafafa;
    }
    
    .table_content {
      display: flex;
      justify-content: center;
      align-items: center;
      text-align: center;
      background-color: #F0F6F8;
      padding: 20px;
    }
    
    @media (max-width: 500px) {
      .table_unit {
        display: none;
      }
      .table {
        grid-template-columns: repeat(1, 1fr);
      }
      .responsive-header {
        display: inline-block;
      }
      .table_content,
      .responsive-header {
        padding: 10px;
      }
      .table_content {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        padding: 0;
      }
    }
    <div class="table">
      <div class="table_unit">
        <p>This is text</p>
      </div>
      <div class="table_unit">
        <p>This is text</p>
      </div>
      <div class="table_unit">
        <p>This is text</p>
      </div>
      
      <div class="table_content">
        <p class="responsive-header">This is text</p>
        <p>Simple text</p>
      </div>
      <div class="table_content">
        <p class="responsive-header">This is text</p>
        <p>Simple text</p>
      </div>
      <div class="table_content">
        <p class="responsive-header">This is text</p>
        <p>Simple text</p>
      </div>
      <div class="table_content">
        <p class="responsive-header">This is text</p>
        <p>Simple text</p>
      </div>
      <div class="table_content">
        <p class="responsive-header">This is text</p>
        <p>Simple text</p>
      </div>
      <div class="table_content">
        <p class="responsive-header">This is text</p>
        <input type="submit" class="log_button_replace" value="Simple button">
      </div>
    </div>

    Output on screens smaller or equal to 500px

    enter image description here

    You could also achieve the desired layout using :before pseudo-element. This approach will help avoid duplicating html code

    .table p {
      margin: 0;
    }
    
    .table {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-gap: 1px;
    }
    
    .table_unit {
      text-align: center;
      background-color: #FAFAFA;
      padding: 20px;
    }
    
    .table_content {
      display: flex;
      justify-content: center;
      align-items: center;
      text-align: center;
      background-color: #F0F6F8;
      padding: 20px;
      position: relative;
    }
    
    @media (max-width: 500px) {
      .table_unit {
        display: none;
      }
      .table {
        grid-template-columns: repeat(1, 1fr);
      }
      .table_content div:before {
        content: 'This is text';
        background: #fafafa;
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      .table_content div:before,
      .table_content div {
        width: 50%;
        padding: 10px;
        box-sizing: border-box;
        text-align: left;
      }
      .table_content {
        justify-content: flex-end;
        padding: 0;
      }
    }
    <div class="table">
      <div class="table_unit">
        <p>This is text</p>
      </div>
      <div class="table_unit">
        <p>This is text</p>
      </div>
      <div class="table_unit">
        <p>This is text</p>
      </div>
      
      <div class="table_content">
        <div>
          <p>Simple text</p>
        </div>
      </div>
      <div class="table_content">
        <div>
          <p>Simple text</p>
        </div>
      </div>
      <div class="table_content">
        <div>
          <p>Simple text</p>
        </div>
      </div>
      <div class="table_content">
        <div>
          <p>Simple text</p>
        </div>
      </div>
      <div class="table_content">
        <div>
          <p>Simple text</p>
        </div>
      </div>
      <div class="table_content">
        <div>
          <input type="submit" class="log_button_replace" value="Simple button">
        </div>
      </div>
    </div>

    Output on screens smaller or equal to 500px

    P.S. in second snippet, i have aligned text to the left on smaller screen size

    enter image description here