Spaced listings

When we begin to have structured, specialized layouts within a list of items, the pattern of a spaced listing emerges. A spaced listing is simply a series of items with an equal amount of space between each item. Within each item, we can place arbitrary containers and/or content. Spaced listings should have modifiers to provide different amounts of space.

Spaced listings can be used to present user-friendly layouts of entities, such as pull requests, comments, messages, price and feature comparisons, etc.

What’s useful about this pattern — compared to adding margins above or below individual items — is the margins never leak out of the listing parent. We never wind up with that extra margin at the bottom of a list that prevents us from getting exactly the layout we intend without massaging it out after the fact. Further, the spacing is controlled by a single modifier on the parent listing, which makes changing the spacing of a listing trivial.

Spaced listings are the ideal way to represent a set of items when the layout is more unique than is suited for a table. They can be used as semantic ol or li lists or as section, div, or any other suitable element.

When using listings, ensure there’s a buffer element representing the immediate listing child/item. Neglecting this buffer could lead to conflicts with the listing items if they define explicit margin: 0;.

.spaceList--small > * + * {
  margin-top: 1.2rem;
}

.spaceList--medium > * + * {
  margin-top: 2.4rem;
}
<ul class="spaceList spaceList--small">
  <li>
    <div class="flag">
      <div class="flag__head">...</div>
      <div class="flag__body">...</div>
    </div>
  </li>
  <li>
    <div class="flag">
      <div class="flag__head">...</div>
      <div class="flag__body">...</div>
    </div>
  </li>
</ul>

<!-- Use with any element, but be sure to retain buffer children: -->
<div class="spaceList spaceList--small">
  <div>
    <div class="flag">
      <div class="flag__head">...</div>
      <div class="flag__body">...</div>
    </div>
  </div>
  <div>
    <div class="flag">
      <div class="flag__head">...</div>
      <div class="flag__body">...</div>
    </div>
  </div>
</div>

Bordered listings

It’s common to extend the spaced listing pattern to into a bordered listing, adding a border between each item. When both patterns exist in a project, it’s convenient to use spacing modifiers that correspond to the same total space for both bordered and non-bordered listings. This allows the two patterns to be used fully interchangeably, with the border added or removed based on the use case.

Similar to the rationale for avoiding leaky margins, avoiding leaky borders is important here. A bordered listing has borders between each item, not below each item. If desired, modifiers can be used to allow for adding borders to the listing as a whole.

.borderList > * + * {
  border-top: 0.1rem solid $COLOR_GRAY_01;
}

.borderList--small > * + * {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
}

.borderList--medium > * + * {
  margin-top: 1.2rem;
  padding-top: 1.2rem;
}
<ul class="borderList borderList--medium">
  <li>
    <div class="flag">
      <div class="flag__head">...</div>
      <div class="flag__body">...</div>
    </div>
  </li>
  <li>
    <div class="flag">
      <div class="flag__head">...</div>
      <div class="flag__body">...</div>
    </div>
  </li>
</ul>