<div class="filterButtons ">
    <ul class="filterButtons__list filterButtons__list--wrap">
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--removable" title="Remove">
                At School
            </button>
        </li>
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--removable" title="Remove">
                At Work
            </button>
        </li>
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--removable" title="Remove">
                In Your Backyard
            </button>
        </li>
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--removable" title="Remove">
                In Your Home
            </button>
        </li>
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--removable" title="Remove">
                On The Road
            </button>
        </li>
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--removable" title="Remove">
                On The Water
            </button>
        </li>
        <li class="filterButtons__item">
            <button class="filterButtons__label filterButtons__label--primary u-uppercase">Clear All</button>
        </li>
    </ul>
</div>

<link media="all" rel="stylesheet" href="/filter-buttons/filter-buttons.css" />
<script src="/filter-buttons/filter-buttons.js"></script>
<div class="filterButtons {{ containerClass }}">
  <ul class="filterButtons__list filterButtons__list--wrap">
    {% for button in buttons %}
      <li class="filterButtons__item">
        <button class="filterButtons__label filterButtons__label--removable" title="Remove">
          {{ button.label }}
        </button>
      </li>
    {% endfor %}
    <li class="filterButtons__item">
      <button class="filterButtons__label filterButtons__label--primary u-uppercase">Clear All</button>
    </li>
  </ul>
</div>

{% import "_macros.twig" as h %}
{{ h.componentAssets('filter-buttons') }}
{
  "containerClass": null,
  "itemsClass": null,
  "buttons": [
    {
      "label": "At School",
      "value": "at-school",
      "iconClass": "fa-solid fa-school"
    },
    {
      "label": "At Work",
      "value": "at-work",
      "iconClass": "fa-solid fa-briefcase"
    },
    {
      "label": "In Your Backyard",
      "value": "in-your-backyard",
      "iconClass": "fa-solid fa-squirrel"
    },
    {
      "label": "In Your Home",
      "value": "in-you-home",
      "iconClass": "fa-solid fa-house-chimney",
      "checked": true
    },
    {
      "label": "On The Road",
      "value": "on-the-road",
      "iconClass": "fa-solid fa-car"
    },
    {
      "label": "On The Water",
      "value": "on-the-water",
      "iconClass": "fa-solid fa-ship"
    }
  ]
}
  • Content:
    @use "../_layout/mixins";
    
    .filterButtons__heading {
      font-weight: var(--bold-weight);
      font-size: var(--step-1);
    }
    .filterButtons__list {
      display: flex;
      gap: var(--gap, 0.5em);
      margin-block-start: 0.5em;
      padding-inline-start: 0; //if <ul> clear inline start padding
    }
    .filterButtons__list--wrap {
      flex-wrap: wrap;
    }
    .filterButtons__item {
      list-style: none;
      margin-block-start: 0;
    }
    .filterButtons__input {
      position: absolute;
      opacity: 0;
      cursor: pointer;
      height: 0;
      width: 0;
    
      &:focus-visible {
        & + .filterButtons__label {
          outline: auto -webkit-focus-ring-color;
          outline: var(--blue--dark) auto 1px;
        }
      }
    }
    .filterButtons__label {
      @include mixins.button();
      --button-color: var(--neutral--ultraDark);
      --button-bg: var(--neutral--light);
      --button-border: 1px solid var(--neutral--dark);
      --button-padding: 0.6em 1em;
      --button-size: var(--step--1);
    
      @media (hover: hover) and (pointer: fine) {
        &:hover,
        &:focus {
          --button-bg: var(--neutral--dark);
          cursor: pointer;
        }
      }
    }
    .filterButtons__label--removable {
      display: flex;
      align-items: center;
      gap: 0.5em;
    
      &:before {
        /* https://fontawesome.com/icons/times?f=classic&s=solid */
        content: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20640%20640%22%3E%3Cpath%20d%3D%22M183.1%20137.4C170.6%20124.9%20150.3%20124.9%20137.8%20137.4C125.3%20149.9%20125.3%20170.2%20137.8%20182.7L275.2%20320L137.9%20457.4C125.4%20469.9%20125.4%20490.2%20137.9%20502.7C150.4%20515.2%20170.7%20515.2%20183.2%20502.7L320.5%20365.3L457.9%20502.6C470.4%20515.1%20490.7%20515.1%20503.2%20502.6C515.7%20490.1%20515.7%20469.8%20503.2%20457.3L365.8%20320L503.1%20182.6C515.6%20170.1%20515.6%20149.8%20503.1%20137.3C490.6%20124.8%20470.3%20124.8%20457.8%20137.3L320.5%20274.7L183.1%20137.4z%22%2F%3E%3C%2Fsvg%3E");
        font-size: 1.3em;
        line-height: 0.9;
        width: 1em;
        height: 1em;
        vertical-align: -0.125em;
      }
    }
    .filterButtons__label--primary {
      @include mixins.buttonPrimary();
      --button-border: 2px solid var(--blue--dark);
      --button-padding: calc(0.6em - 1px) 2em; //because filterButtons__label has 1px border, but button--primary has 2px
    }
    .filterButtons__input:checked + .filterButtons__label,
    .filterButtons__label--active {
      --button-color: var(--white);
      --button-bg: var(--blue);
      --button-border-color: var(--blue);
    }
    span.filterButtons__label--active {
      &:hover,
      &:focus {
        cursor: default;
        --button-color: var(--white);
        --button-bg: var(--blue);
        --button-border-color: var(--blue);
      }
    }
    
  • URL: /components/raw/filter-buttons/filter-buttons.scss
  • Filesystem Path: src/components/filter-buttons/filter-buttons.scss
  • Size: 2.6 KB

Filter buttons are a UI filtering component. They display a list of checkboxes styled as buttons in an on/off state. Since, under the hood, they are checkboxes (are radio boxes), they can be queried for state with JS just as you would with normal form inputs.