<main>
<button id="xray" onclick="toggleXRay(event)">Grid X-Ray Vision!</button>

<h1>Ridiculously responsive lists with CSS Grid</h1>

<p>For those times when you have a long list of short items and you want to be able to lay them out with a bit of density. Click the Grid X-Ray Vision button to get a better idea of what's happening.</p>

<h2>Here be lists!</h2>

<div class="container">
  <h3 class="header1">Segment 1</h3>
  <ul class="list1 responsive green-checkmarks">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Many items</li>
    <li>Coffee</li>
    <li>Milk</li>
    <li>Tea</li>
    <li>Black tea</li>
    <li>Green tea</li>
    <li>I need more items</li>
    <li>Some short</li>
    <li>Some long but not too long</li>
    <li>Last item</li>
  </ul>
  <h3 classs="header2">Second segment</h3>
  <ul class="list2 responsive green-checkmarks">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Some long but not too long</li>
    <li>Many items</li>
    <li>Green tea</li>
    <li>And that should be it</li>
    <li>Some other item</li>
    <li>I need more items</li>
    <li>Last item</li>
  </ul>
</div>

<h2>Things to improve</h2>

<ul class="red-crosses">
  <li>I don't like the fact that I'm setting the minimum column width with a fixed length using <span class="code">repeat(auto-fit, minmax(25ch, 1fr))</span>. I'd like to use <span class="code">max-content</span> instead of <span class="code">25ch</span> so that the columns are as wide as they need to be for the text to fit in one line, but I can't seem to make it work 🤷‍♂️.</li>
</ul>
</main>

<footer>
  <p>If you have questions or comments, <a href="https://twitter.com/raulrpearson">tweet</a> them to me!</p>
</footer>
/* Reset! */

* {
  margin: 0;
  padding: 0;
}

main {
  padding: 1em;
  font-size: 1.1em;
}

// Target all headings
// https://stackoverflow.com/a/21622588
h1, h2, h3,
h4, h5, h6 {
    @extend %headings !optional;
}

%headings {
  font-family: sans-serif;
  font-weight: normal;
}

main > %headings {
  margin: 1em 0 0.5em 0;
}

p {
  margin: 0.5em 0;
}

/* The part that you care about */

.container {
  display: grid;
  grid-template-areas:
    "header1 header2"
    "list1 list2";
  @media (max-width: 700px) {
    grid-template-areas:
      "header1"
      "list1"
      "header2"
      "list2";
  }
}

.header1 { grid-area: header1; }
.header2 { grid-area: header2; }
.list1 { grid-area: list1; }
.list2 { grid-area: list2; }

ul.responsive {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(25ch, 1fr));
  //grid-auto-flow: column;
  //grid-auto-columns: max-content;
  justify-items: start;
  align-self: start;
}

/* Set up Grid X-ray vision */

.container,
ul {
  grid-gap: 2px;
}

.xray {
  background: #0000001f;
}

button#xray {
  font-size: 0.7em;
  position: sticky;
  top: 1em;
  display: block;
  margin: 0 0 0 auto;
  padding: 0.5em;
  border: 0;
  color: white;
  background-color: purple;
  
  &:hover {
    filter: brightness(90%);
  }
}

/* Make things look a bit better */

ul {
  &.green-checkmarks,
  &.red-crosses {
    list-style: none;
    margin-left: 0;
    padding-left: 0;
    
    li {
      padding-left: 1.1em;
      text-indent: -1.1em;
    }
  }
  
  &.green-checkmarks li:before {
   font-family: 'Font Awesome 5 Free';
   content: "\f00c";
   color: green;
   padding-right: 0.3em;
  }
  
  &.red-crosses li:before {
   font-family: 'Font Awesome 5 Free';
   content: "\f00d";
   color: red;
   padding-right: 0.3em;
  }
}

.code {
  font-family: monospace;
  font-weight: bold;
  color: gray;
}

#twitter {
  position: absolute;
  top: 1em;
  left: 1em;
  color: #1da1f2;
  font-size: 1.2em;
}

footer {
  background: purple;
  color: white;
  padding: 0.5em;
  margin-top: 2em;
  text-align: center;
  font-size: 0.7em;
  
  a {
    color: #62BDEE;
    text-decoration: none;
    font-weight: bold;
  }
}
View Compiled
/* Gather up the Grids! (including children and grandchildren) */
let allElements = Array.from(document.querySelector('main').children);
let allGrids = [];
allElements.forEach(
  element => {
    if (window.getComputedStyle(element).getPropertyValue('display') == 'grid') {
      allGrids.push(element);
      Array.from(element.children).forEach(
        child => {
          allGrids.push(child);
          Array.from(child.children).forEach(
            granchild => {
              allGrids.push(granchild);
            }
          )
        }
      )
    }
  }
);

/* Boom, x-ray! */
let xrayActive = false;
function toggleXRay(e) {
  xrayActive ?
    allGrids.forEach(element => element.classList.remove('xray')) :
    allGrids.forEach(element => element.classList.add('xray'));
  xrayActive = !xrayActive;
}
Run Pen

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css

External JavaScript

This Pen doesn't use any external JavaScript resources.