<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. */
import "./inline-list.scss";
import removeOrphanList from "./remove-orphan-pipe.js"
removeOrphanList();
.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);
}
}
}
/**
* 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;
})
}
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".
.inlineList--wrap
Allows the list to wrap to new lines by applying flex-wrap: wrap.
.inlineList--pipe
Adds a separator, pipe (|) by default, after each .inlineList__item, except for the last one.
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: "-";
}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.