Check

Use tags to convey information, apply filters or display a selection of items.

Examples

A tag is basically a rounded <span> that can contain text, and optionally an image and/or a close button. Please adapt the HTML to be semantically correct. Here are some hints to build accessible tags.

There are some built-in examples that you can find on our tags example page

You shouldn’t mix the different tags versions in the same area since they look the same and have different behaviors.

Informative

Informative tags are built on top of <span> and are usually used to display categories. They have no specific interaction.

For a list of tags of an article, for example, add a heading (<h1>–<h6>) to explain that we are in a tags list and use <ul> or <ol> depending on the use case.

  • Bird
  • Twitter
html
<ul class="list-unstyled m-0 d-flex gap-2 flex-wrap m-0">
  <li><span class="tag">Bird</span></li>
  <li>
    <span class="tag">
      <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M32 7a13 13 0 01-3.8 1.1 6.6 6.6 0 003-3.6c-1.4.7-2.8 1.3-4.3 1.6a6.6 6.6 0 00-11.1 6A18.6 18.6 0 012.2 5a6.6 6.6 0 002 8.9c-1 0-2-.4-3-.9v.1c0 3.2 2.4 5.9 5.4 6.5a6.6 6.6 0 01-3 0 6.6 6.6 0 006.1 4.6A13.2 13.2 0 010 27.1a18.6 18.6 0 0028.7-16.6C30 9.5 31.1 8.4 32 7z'/></svg>
      Twitter
    </span>
  </li>
</ul>

Filter

A tag can be actionable either when built on top of a <button> or a <label>. These <label>s are based on either checkboxes or radios <input>. These tags are usually used as filters and have an .active state.

Most of the time, tags must be inside a list (<ul> or <ol>).

html
<ul class="list-unstyled d-flex gap-2 flex-wrap m-0">
  <li>
    <input type="checkbox" class="btn-check" id="btncheck-mobile" autocomplete="off">
    <label class="tag" for="btncheck-mobile"><span class="visually-hidden">Filter by</span>Mobile</label>
  </li>
  <li>
    <input type="checkbox" class="btn-check" id="btncheck-tv" autocomplete="off" checked>
    <label class="tag" for="btncheck-tv">
      <svg width="1.5rem" height="1.5rem" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
        <path fill="currentColor" d="M2.5 13.5A.5.5 0 0 1 3 13h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zM13.991 3l.024.001a1.46 1.46 0 0 1 .538.143.757.757 0 0 1 .302.254c.067.1.145.277.145.602v5.991l-.001.024a1.464 1.464 0 0 1-.143.538.758.758 0 0 1-.254.302c-.1.067-.277.145-.602.145H2.009l-.024-.001a1.464 1.464 0 0 1-.538-.143.758.758 0 0 1-.302-.254C1.078 10.502 1 10.325 1 10V4.009l.001-.024a1.46 1.46 0 0 1 .143-.538.758.758 0 0 1 .254-.302C1.498 3.078 1.675 3 2 3h11.991zM14 2H2C0 2 0 4 0 4v6c0 2 2 2 2 2h12c2 0 2-2 2-2V4c0-2-2-2-2-2z"></path>
      </svg>
      <span class="visually-hidden">Filter by</span>TV
    </label>
  </li>
</ul>

If the tag filter triggers some action, you should use the version built on top of a <button>. The text of the button must be clear enough to explain the function.

html
<ul class="list-unstyled d-flex gap-2 flex-wrap m-0">
  <li><button class="tag"><span class="visually-hidden">Filter by</span>Mobile</button></li>
  <li>
    <button class="tag active">
      <svg width="1.5rem" height="1.5rem" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
        <path fill="currentColor" d="M2.5 13.5A.5.5 0 0 1 3 13h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zM13.991 3l.024.001a1.46 1.46 0 0 1 .538.143.757.757 0 0 1 .302.254c.067.1.145.277.145.602v5.991l-.001.024a1.464 1.464 0 0 1-.143.538.758.758 0 0 1-.254.302c-.1.067-.277.145-.602.145H2.009l-.024-.001a1.464 1.464 0 0 1-.538-.143.758.758 0 0 1-.302-.254C1.078 10.502 1 10.325 1 10V4.009l.001-.024a1.46 1.46 0 0 1 .143-.538.758.758 0 0 1 .254-.302C1.498 3.078 1.675 3 2 3h11.991zM14 2H2C0 2 0 4 0 4v6c0 2 2 2 2 2h12c2 0 2-2 2-2V4c0-2-2-2-2-2z"></path>
      </svg>
      <span class="visually-hidden">Filter by</span>TV
    </button>
  </li>
</ul>

Another way to build actionable tags is to build them on top of <a>. These kind of tags are usually used as anchor links.

Put an explicit heading to add semantics. The text of the link must be clear enough to explain the destination of the tag. Most of the time, tags must be inside a list (<ul> or <ol>).

html
<ol class="list-unstyled d-flex gap-2 flex-wrap m-0">
  <li><a class="tag" href="#">1. Introduction</a></li>
  <li><a class="tag" href="#">2. Exposure</a></li>
</ol>

Input

This kind of tags are built on <span>.

For a list of selected items use <ul> or <ol>.

Here is an accessible example of a component that can be built on top of this variant.

  • Dismissible tag
  • Dismissible tag
html
<ul class="list-unstyled d-flex gap-2 flex-wrap m-0">
  <li><span class="tag" id="labelTag1">
    Dismissible tag
    <button class="close" aria-labelledby="labelTag1"><span class="visually-hidden">Close</span></button>
  </span></li>
  <li><span class="tag" id="labelTag2">
    <svg width="1rem" height="1rem" fill="currentColor" aria-hidden="true" focusable="false">
      <use xlink:href="/innovation-cup/docs/0.2/assets/img/boosted-sprite.svg#buy"/>
    </svg>
    Dismissible tag
    <button class="close" aria-labelledby="labelTag2"><span class="visually-hidden">Close</span></button>
  </span></li>
</ul>

Dark variant

We add an extra <p> around the <span> here for accessibility concerns.

Add .tag-dark to the .tag for a dark variant.

Informative

Navigation

Input

html
<p class="mb-0"><span class="tag tag-dark">Informative</span></p>
<button class="tag tag-dark">Filter</button>
<a class="tag tag-dark" href="#">Navigation</a>
<p><span class="tag tag-dark" id="labelTag3">
  <svg fill="currentColor" width="1.5rem" height="1.5rem" aria-hidden="true" focusable="false">
    <use xlink:href="/innovation-cup/docs/0.2/assets/img/boosted-sprite.svg#buy"/>
  </svg>
  Input
  <button class="close" aria-labelledby="labelTag3"><span class="visually-hidden">Close</span></button>
</span></p>

Sizes

We add an extra <p> around the <span> here for accessibility concerns.

Add .tag-sm to the .tag for a small variant.

Small tag variant

Informative

Navigation

Input

html
<h3 class="visually-hidden">Small tag variant</h3>
<p class="mb-0"><span class="tag tag-sm">Informative</span></p>
<button class="tag tag-sm">Filter</button>
<a class="tag tag-sm" href="#">Navigation</a>
<p><span class="tag tag-sm" id="labelTag4">
  <svg fill="currentColor" width="1.5rem" height="1.5rem" aria-hidden="true" focusable="false">
    <use xlink:href="/innovation-cup/docs/0.2/assets/img/boosted-sprite.svg#buy"/>
  </svg>
  Input
  <button class="close" aria-labelledby="labelTag4"><span class="visually-hidden">Close</span></button>
</span></p>

Disabled state

We add an extra <p> around the <span> here for accessibility concerns.

Add .disabled to the .tag for a disabled variant. Don’t forget to add aria-disabled to <span> and disabled attribute to <button>.

Disabled tags using the <a> element behave a bit different:

  • <a>s don’t support the disabled attribute, so you must add the .disabled class to make it visually appear disabled.
  • Some future-friendly styles are included to disable all pointer-events on anchor tags.
  • Disabled tags using <a> should include the aria-disabled="true" attribute to indicate the state of the element to assistive technologies.
  • Disabled tags using <a> should not include the href attribute.

Disabled tags for the different variants

Informative

Navigation

Input

html
<h3 class="visually-hidden">Disabled tags for the different variants</h3>
<p class="mb-0"><span class="tag disabled" aria-disabled="true">Informative</span></p>
<button class="tag" disabled>Filter</button>
<a class="tag disabled" aria-disabled="true">Navigation</a>
<p><span class="tag disabled" id="labelTag5" aria-disabled="true">
  <svg fill="currentColor" width="1.5rem" height="1.5rem" aria-hidden="true" focusable="false">
    <use xlink:href="/innovation-cup/docs/0.2/assets/img/boosted-sprite.svg#buy"/>
  </svg>
  Input
  <button class="close" aria-labelledby="labelTag5" disabled><span class="visually-hidden">Close</span></button>
</span></p>

CSS

Variables

Values for the CSS variables are set via Sass, so Sass customization is still supported, too.

  --#{$prefix}tag-gap: #{$tag-gap};
  --#{$prefix}tag-padding-x: #{$tag-padding-x};
  --#{$prefix}tag-padding-y: #{$tag-padding-y};
  @include rfs($tag-font-size, --#{$prefix}tag-font-size);
  --#{$prefix}tag-font-shift: #{$tag-font-shift};
  --#{$prefix}tag-font-weight: #{$tag-font-weight};
  --#{$prefix}tag-icon-size: #{$tag-icon-size};
  --#{$prefix}tag-icon-margin-start: #{$tag-icon-margin-start};
  --#{$prefix}tag-close-size: #{add(var(--#{$prefix}tag-font-size), .375rem)};
  --#{$prefix}tag-close-margin-end: #{$tag-close-margin-end};
  --#{$prefix}tag-close-margin-start: #{$tag-close-margin-start};
  --#{$prefix}tag-border-width: #{$tag-border-width};
  --#{$prefix}tag-border-radius: #{$tag-border-radius};
  --#{$prefix}tag-border-color: #{$tag-border-color};
  --#{$prefix}tag-active-color: #{$tag-active-color};
  --#{$prefix}tag-active-decoration-color: #{$tag-active-decoration-color};
  --#{$prefix}tag-disabled-color: #{$tag-disabled-color};
  --#{$prefix}tag-outline-color: var(--#{$prefix}link-hover-color);
  

Customization through CSS variables can be seen on the .tag-dark class where we override specific values without adding duplicate CSS selectors.

  --#{$prefix}tag-border-color: #{$tag-border-color-dark};
  --#{$prefix}tag-active-color: #{$tag-active-color-dark};
  --#{$prefix}tag-active-decoration-color: #{$tag-active-decoration-color-dark};
  --#{$prefix}tag-disabled-color: #{$tag-disabled-color-dark};
  

Customization through CSS variables can be seen on the .tag-sm class where we override specific values without adding duplicate CSS selectors.

  --#{$prefix}tag-padding-x: #{$tag-padding-x-sm};
  --#{$prefix}tag-padding-y: #{$tag-padding-y-sm};
  --#{$prefix}tag-font-size: #{$tag-font-size-sm};
  --#{$prefix}tag-icon-size: #{$tag-icon-size-sm};
  --#{$prefix}tag-icon-margin-start: #{$tag-icon-margin-start-sm};
  --#{$prefix}tag-close-margin-end: #{$tag-close-margin-end-sm};
  --#{$prefix}tag-close-margin-start: #{$tag-close-margin-start-sm};
  

Sass Variables

Variables for all tags:

$tag-gap:                           map-get($spacers, 1);
$tag-font-shift:                    $spacer * .1;
$tag-font-weight:                   $font-weight-bold;
$tag-border-width:                  $border-width;
$tag-border-radius:                 $border-radius-pill;

$tag-padding-x:                     $spacer * .65;
$tag-padding-y:                     $spacer * .45;
$tag-icon-size:                     $spacer * 1.2;
$tag-icon-margin-start:             -$spacer * .35;
$tag-close-margin-end:              -$spacer * .3;
$tag-close-margin-start:            $spacer * .2;
$tag-font-size:                     $font-size-base;

$tag-active-color:                  $white;
$tag-disabled-color:                $gray-500;
$tag-border-color:                  $gray-500;
$tag-active-decoration-color:       $black;

Variables for the dark tag:

$tag-active-color-dark:             $black;
$tag-disabled-color-dark:           $gray-700;
$tag-border-color-dark:             $gray-700;
$tag-active-decoration-color-dark:  $white;

Variables for the small tag:

$tag-padding-x-sm:                  $spacer * .4;
$tag-padding-y-sm:                  $spacer * .25;
$tag-icon-size-sm:                  $spacer;
$tag-icon-margin-start-sm:          -$spacer * .1;
$tag-close-margin-end-sm:           -$spacer * .25;
$tag-close-margin-start-sm:         0;
$tag-font-size-sm:                  $font-size-sm;