Search code examples
htmlcssresponsive

How can I create a responsive table that changes to a list in mobile view?


I want to create a responsive table with artists' names that should like like this: http://daggerforest.com/artists.html

I've found code for the table online and tweaked it to my liking. However when it collapses to mobile view the elements that should be invisible are still "taking space" and the list of names has gaps: See: https://codepen.io/alanvkarlik/pen/GReVOjV (in the final version I want no borders around cells, I've left them to show the issue)

I know the code looks probably more complicated than it should be but I don't know how to tackle it.

In Desktop view I want each row with names to be divided with another row with ✧ symbols, like it's currently on http://daggerforest.com/artists.html

/* Page styling
    ================================== */

html {
  height: 100%;
  background-color: #EEE;
}

body {
  box-sizing: border-box;
  min-height: 100%;
  margin: 0 auto;
  padding: 2em;
  max-width: 800px;
  font-size: 1.2em;
  background-color: white;
  text-align: center;
}


/* Tables
    ================================== */

.Rtable {
  display: flex;
  flex-wrap: wrap;
  margin: 0 0 3em 0;
  padding: 0;
  position: relative;
  top: 3px;
  left: 3px;
}

.Rtable-cell {
  box-sizing: border-box;
  flex-grow: 1;
  width: 100%;
  padding: 4px;
  overflow: hidden;
  list-style: none;
  border: solid 3px white;
  background: rgba(112, 128, 144, 0.2);
}

.Rtable-cell-gap {
  border: solid 3px white;
  background: rgba(112, 128, 144, 0.2);
}

.Rtable-cell,
.Rtable-cell-gap {
  margin: -3px 0 0 -3px;
  background-color: white;
  border-color: #e2e6e9;
}


/* Table column sizing
    ================================== */

.Rtable--5cols>.Rtable-cell {
  width: 30%;
}

.Rtable--5cols>.Rtable-cell-gap {
  width: 5%;
}


/* Responsive
    ==================================== */

@media all and (max-width: 500px) {
  .Rtable--collapse {
    display: block;
  }
  .Rtable--collapse>.Rtable-cell {
    width: 100% !important;
  }
  .Rtable--collapse>.Rtable-cell--foot {
    margin-bottom: 1em;
  }
}

.no-flexbox .Rtable {
  display: block;
}

.no-flexbox .Rtable>.Rtable-cell {
  width: 100%;
}

.no-flexbox .Rtable>.Rtable-cell--foot {
  margin-bottom: 1em;
}
<div class="Rtable Rtable--5cols Rtable--collapse">
  <div class="Rtable-cell"><a href="https://aplaceboth.bandcamp.com/" target="_blank">APBWAS</a></div>
  <div class="Rtable-cell-gap">&nbsp;</div>
  <div class="Rtable-cell"><a href="https://soundcloud.com/daanmol" target="_blank">Daan Mol</a></div>
  <div class="Rtable-cell-gap">&nbsp;</div>
  <div class="Rtable-cell"><a href="https://salemanhedonia.bandcamp.com/" target="_blank">Edith Underground</a></div>

  <div class="Rtable-cell">&nbsp;</div>
  <div class="Rtable-cell-gap">✧</div>
  <div class="Rtable-cell">&nbsp;</div>
  <div class="Rtable-cell-gap">✧</div>
  <div class="Rtable-cell">&nbsp;</div>

  <div class="Rtable-cell"><a href="https://soundcloud.com/eyeshadows" target="_blank">Eyeshadows</a></div>
  <div class="Rtable-cell-gap">&nbsp;</div>
  <div class="Rtable-cell"><a href="https://hereinheven.bandcamp.com/" target="_blank">HeveN</a></div>
  <div class="Rtable-cell-gap">&nbsp;</div>
  <div class="Rtable-cell"><a href="https://howtodresswellmusic.bandcamp.com/" target="_blank">How To Dress Well</a></div>

  <div class="Rtable-cell">&nbsp;</div>
  <div class="Rtable-cell-gap">✧</div>
  <div class="Rtable-cell">&nbsp;</div>
  <div class="Rtable-cell-gap">✧</div>
  <div class="Rtable-cell">&nbsp;</div>

  <div class="Rtable-cell"><a href="https://make-up.bandcamp.com/" target="_blank">Makeup</a></div>
  <div class="Rtable-cell-gap">&nbsp;</div>
  <div class="Rtable-cell"><a href="https://soundcloud.com/mascara" target="_blank">Mascara</a></div>
  <div class="Rtable-cell-gap">&nbsp;</div>
  <div class="Rtable-cell"><a href="https://matersuspiriavision.bandcamp.com/" target="_blank">Mater Suspiria Vision</a></div>
</div>


Solution

  • It is not very comfortable having HTML elements in the DOM which are only there for decorative reasons.

    And using a table for layout introduces spurious semantics.

    An alternative way of doing this is to have a CSS grid - 3 cols for wider viewports, 1 col for narrow ones.

    And the stars can be added, outside the DOM, by positioning absolute pseudo after elements.

    .container {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      gap: 2em;
    }
    
    .container>div {
      position: relative;
      text-align: center;
    }
    
    .container>div:not(:nth-child(3n-2))::after {
      position: absolute;
      content: '✧';
      top: 100%;
      left: 0;
    }
    
    .container>div:last-child::after,
    .container>div:nth-last-child(2)::after {
      display: none;
    }
    
    @media (max-width: 768px) {
      .container {
        grid-template-columns: 1fr;
      }
      .container>div::after {
        display: none;
      }
    }
    <div class="container">
      <div>name</div>
      <div>name</div>
      <div>name</div>
      <div>name</div>
      <div>name</div>
      <div>name</div>
      <div>name</div>
      <div>name</div>
      <div>name</div>
    </div>