<div class="inlineList inlineList--wrap" role="list">
    <h2 class="inlineList__item u-bold u-step-1">Tags:</h2>
    <ul class="inlineList inlineList--wrap">
        <li class="inlineList__item"><a href="#" class="tagButton ">tag</a>

            <link media="all" rel="stylesheet" href="/tag-button/tag-button.css" />
            <script src="/tag-button/tag-button.js"></script>
        </li>
        <li class="inlineList__item"><a href="#" class="tagButton ">tag</a>

            <link media="all" rel="stylesheet" href="/tag-button/tag-button.css" />
            <script src="/tag-button/tag-button.js"></script>
        </li>
        <li class="inlineList__item"><a href="#" class="tagButton ">tag</a>

            <link media="all" rel="stylesheet" href="/tag-button/tag-button.css" />
            <script src="/tag-button/tag-button.js"></script>
        </li>
    </ul>
</div>

<link media="all" rel="stylesheet" href="/inline-list/inline-list.css" />
<script src="/inline-list/inline-list.js"></script>
<div class="inlineList inlineList--wrap" role="list">
  <h2 class="inlineList__item u-bold u-step-1">Tags:</h2>
  <ul class="inlineList inlineList--wrap">
    {% for i in 0..2 %}
      <li class="inlineList__item">{% render "@tag-button" %}</li>
    {% endfor %}
  </ul>
</div>

{% import "_macros.twig" as h %}
{{ h.componentAssets('inline-list') }}
/* No context defined. */
  • Content:
    import "./inline-list.scss";
    import removeOrphanList from  "./remove-orphan-pipe.js"
    
    removeOrphanList();
  • URL: /components/raw/inline-list/inline-list.js
  • Filesystem Path: src/components/inline-list/inline-list.js
  • Size: 105 Bytes
  • Content:
    .inlineList {
      display: flex;
      gap: var(--inlineListGap, 0.5em);
      align-items: center;
      padding-inline-start: 0; // in the case of ul.inlineList
    }
    .inlineList--wrap {
      flex-wrap: wrap;
    }
    .inlineList__item {
      margin-block-start: 0;
      list-style: none;
    }
    @property --inlineListSep {
      syntax: "*";
      inherits: true;
      initial-value: "|";
    }
    
    .inlineList--pipe {
      .inlineList__item:has( ~ .inlineList__item) {
        &:after {
          content: var(--inlineListSep);
          margin-inline-start: var(--inlineListGap, 0.5em);
        }
      }
    }
    
  • URL: /components/raw/inline-list/inline-list.scss
  • Filesystem Path: src/components/inline-list/inline-list.scss
  • Size: 532 Bytes
  • Content:
    /**
     * For any list of `.inlineList--pipe > .inlineList__item`, if an item is teh last one on the line, it will remove the `|` separator
     */
    export default function () {
      const items = document.querySelectorAll(".inlineList--pipe .inlineList__item");
      let previousY;
      items.forEach((item, index) => {
        const bbox = item.getBoundingClientRect();
    
        if (bbox.y !== previousY) {
          const previous = items[index - 1];
          if (previous) {
            previous.style.setProperty("--inlineListSep", "''");
          }
        }
    
        previousY = bbox.y;
      })
    }
  • URL: /components/raw/inline-list/remove-orphan-pipe.js
  • Filesystem Path: src/components/inline-list/remove-orphan-pipe.js
  • Size: 553 Bytes

Accessibility

Lists are lists, regardless of direction. Hence, even an ‘inline’ list should get marked up as such for accessibility.

Ideally, use semantic HTML (<ul> and <li>) when possible. Alternatively, you can also use role="list" and role="listitem".

Modifiers

–wrap

.inlineList--wrap

Allows the list to wrap to new lines by applying flex-wrap: wrap.

–pipe

.inlineList--pipe

Adds a separator, pipe (|) by default, after each .inlineList__item, except for the last one.

Separators

Use .inlineList--pipe to add a separator to the lists. The default is a pipe |. Modify it with the --inlineListSep css custom property:

.inlineList.inlineList--pipe {
    --inlineListSep: "-";
}

Removing Hanging Separators

If the pipe and wrap modifiers are combined, a likely situation is that the wrapping will occur between items, in which case the last item on each line with have a hanging (or orphan) separator.

To deal with this, a utility JS function is included in this component which will remove any such separators on all .inlineList--pipe lists:

import removeOrphanPipe from "./remove-orphan-pipe.js";

removeOrphanPipe();

Note: despite the apparent misnomer, this JS function will remove the separator regardless if it is a pipe or something else.