Skip to content

Badge

Use the aria-label tag to add content inside the Badge.

Variants

Default, and .dot.

html
<span class="badge" aria-label="5">
  <svg></svg>
</span>

<span class="badge dot">
  <svg></svg>
</span>

Color

Primary (default), .danger, .info, .success, .warning.

html
<span class="badge danger" aria-label="5">
  <!--  -->
</span>

<span class="badge info" aria-label="5">
  <!--  -->
</span>

<span class="badge success" aria-label="5">
  <!--  -->
</span>

<span class="badge warning" aria-label="5">
  <!--  -->
</span>

Visibility

html
<span class="badge invisible" aria-label="5">
  <!--  -->
</span>

<span class="badge dot invisible">
  <!--  -->
</span>

Alignment

.start-start, .start-end (default), .end-start, .end-end.

html
<span class="badge start-start" aria-label="35">
  <!--  -->
</span>

<span class="badge start-end" aria-label="99+">
  <!--  -->
</span>

<span class="badge end-start" aria-label="OK!">
  <!--  -->
</span>

<span class="badge end-end" aria-label="3K">
  <!--  -->
</span>

Anatomy

  1. Element to wrap
  2. Badge
html
<span class="badge" aria-label="5">
  <!--  -->
</span>

API

TypeModifiersDefaultDescription
Alignment&.start-start, &.start-end, &.end-start, &.end-end.start-endWhere the badge should be placed over the child.
Color&.danger, &.info, &.success, &.warning-Optional colors.
VariantsDefault, .dotDefaultThe variant to use.
VisibilityDefault, .invisibleDefaultDefines if the badges visibility.

Installation

css
:where(.badge) {
  --_bg-color: var(--primary);
  --_border-color: var(--primary);
  --_color: var(--gray-0);
  --_inset: -8px -8px auto auto;
  --_translate: 0;

  display: inline-flex;
  position: relative;

  &:after {
    background-color: var(--_bg-color);
    border: 2px solid var(--_border-color);
    border-radius: 100vmax;
    color: var(--_color);
    content: attr(aria-label);
    font-size: 12px;
    font-weight: 500;
    block-size: var(--size-4, 1.25rem);
    line-height: normal;
    min-inline-size: var(--size-4, 1.125rem);
    padding-inline: var(--size-1);
    inset: var(--_inset);
    position: absolute;
    text-align: center;
    translate: var(--_translate);
    transition: opacity 0.2s var(--ease-out-1);
    inline-size: max-content;
  }

  /* Alignment */
  &.start-start {
    --_inset: -8px auto auto -8px;
  }
  &.start-end {
    --_inset: -8px -8px auto auto;
  }
  &.end-start {
    --_inset: auto auto -8px -8px;
  }
  &.end-end {
    --_inset: auto -8px -8px auto;
  }

  /* Dot */
  &.dot {
    --_inset: 0 -1px auto auto;
    &:after {
      content: "";
      min-inline-size: var(--size-2);
      block-size: var(--size-2);
      inline-size: var(--size-2);
      padding: 0;
    }
  }

  /* Visibility */
  &.invisible {
    &:after {
      opacity: 0;
      pointer-events: none;
    }
  }

  /* Colors */
  &.danger,
  &.info,
  &.success,
  &.warning {
    --_bg-color: var(--color-8);
    --_border-color: var(--color-8);
  }
}