<alert-element>

A custom HTML element for displaying dismissible alerts and toast notifications

Source code & documentation

Examples

  1. Variants
  2. Icons
  3. Closable
  4. Custom close button
  5. Duration
  6. Countdown
  7. Custom variant
  8. Custom styling
  9. Toast notifications
  10. Creating toasts imperatively
  11. Custom toast stack position
  12. Custom animations
  13. No animations
  14. User interaction
  15. Invoker commands

Variants

Set the variant attribute to change the alert’s variant.

New feature available!
You can now schedule reports to be sent automatically to your inbox every week.
Your profile has been updated
All changes have been saved and will take effect immediately.
Scheduled maintenance
Our servers will be undergoing maintenance this Saturday from 2 AM to 4 AM UTC.
Password expires soon
Your current password will expire in 5 days. Please update it to avoid losing access.
Failed to connect to database
Please check your configuration settings and try again. Contact support if the issue persists.
Source code
<alert-element open variant="info">
  <strong>New feature available!</strong><br>
  You can now schedule reports to be sent automatically to your inbox every week.
</alert-element>

<alert-element open variant="success">
  <strong>Your profile has been updated</strong><br>
  All changes have been saved and will take effect immediately.
</alert-element>

<alert-element open variant="neutral">
  <strong>Scheduled maintenance</strong><br>
  Our servers will be undergoing maintenance this Saturday from 2 AM to 4 AM UTC.
</alert-element>

<alert-element open variant="warning">
  <strong>Password expires soon</strong><br>
  Your current password will expire in 5 days. Please update it to avoid losing access.
</alert-element>

<alert-element open variant="danger">
  <strong>Failed to connect to database</strong><br>
  Please check your configuration settings and try again. Contact support if the issue persists.
</alert-element>

Icons

Use the icon slot to display an icon next to the alert message.

Your profile has been updated!
All changes have been saved and will take effect immediately.
Source code
<alert-element open variant="success">
  <span slot="icon">
    <svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
      <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
      <path d="m10.97 4.97-.02.022-3.473 4.425-2.093-2.094a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05"/>
    </svg>
  </span>
  <strong>Your profile has been updated!</strong><br>
  All changes have been saved and will take effect immediately.
</alert-element>

Closable

Set the closable attribute to display a close button that hides the alert when clicked.

Click the close button (X) to hide this alert.
Source code
<alert-element variant="info" open closable>
  Click the close button (X) to hide this alert.
</alert-element>

Custom close button

Use the close slot to provide a custom close button.

This is an alert with a custom close button. Close
Source code
<alert-element variant="info" open closable>
  This is an alert with a custom close button.
  <span slot="close">Close</span>
</alert-element>

Duration

Set the duration attribute to automatically hide the alert after a specified period of time, unless you interact with it while still open.

This alert will automatically hide itself after 3 seconds, unless you interact with it.
Source code
<alert-element variant="info" closable duration="3000">
  This alert will automatically hide itself after 3 seconds, unless you interact with it.
</alert-element>

Countdown

Set the countdown attribute to display a countdown bar that indicates the remaining time before the alert automatically hides itself.

This alert will automatically hide itself after 10 seconds, unless you interact with it.
Source code
<alert-element variant="info" closable duration="10000" countdown>
  This alert will automatically hide itself after 3 seconds, unless you interact with it.
</alert-element>

Custom variant

You can create custom variants by using the variant attribute with a custom value and applying your own CSS styles.

Custom variant alert
This alert uses a custom variant and style.
Source code
<style>
  alert-element[variant="custom"] {
    --alert-base-variant-color: #823ff2;
  }

  @media (prefers-color-scheme: dark) {
    alert-element[variant="custom"] {
      --alert-base-variant-color: #b5a1ff;
    }
  }
</style>

<alert-element open variant="custom">
  <span slot="icon">
    <svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
      <path fill-rule="evenodd" d="m4.736 1.968-.892 3.269-.014.058C2.113 5.568 1 6.006 1 6.5 1 7.328 4.134 8 8 8s7-.672 7-1.5c0-.494-1.113-.932-2.83-1.205l-.014-.058-.892-3.27c-.146-.533-.698-.849-1.239-.734C9.411 1.363 8.62 1.5 8 1.5s-1.411-.136-2.025-.267c-.541-.115-1.093.2-1.239.735m.015 3.867a.25.25 0 0 1 .274-.224c.9.092 1.91.143 2.975.143a30 30 0 0 0 2.975-.143.25.25 0 0 1 .05.498c-.918.093-1.944.145-3.025.145s-2.107-.052-3.025-.145a.25.25 0 0 1-.224-.274M3.5 10h2a.5.5 0 0 1 .5.5v1a1.5 1.5 0 0 1-3 0v-1a.5.5 0 0 1 .5-.5m-1.5.5q.001-.264.085-.5H2a.5.5 0 0 1 0-1h3.5a1.5 1.5 0 0 1 1.488 1.312 3.5 3.5 0 0 1 2.024 0A1.5 1.5 0 0 1 10.5 9H14a.5.5 0 0 1 0 1h-.085q.084.236.085.5v1a2.5 2.5 0 0 1-5 0v-.14l-.21-.07a2.5 2.5 0 0 0-1.58 0l-.21.07v.14a2.5 2.5 0 0 1-5 0zm8.5-.5h2a.5.5 0 0 1 .5.5v1a1.5 1.5 0 0 1-3 0v-1a.5.5 0 0 1 .5-.5"/>
    </svg>
  </span>
  <strong>Custom variant alert</strong><br>
  This alert uses a custom variant and style.
</alert-element>

Custom styling

You can apply custom styles to the alert element using CSS custom properties and the ::part() pseudo-element.

This alert has custom styling applied to it.
Source code
<style>
  .custom-alert {
    --alert-bg-color: #cfe2ff;
    --alert-fg-color: #072c65;
    --alert-border-color: #9ec5fe;
  }

  @media (prefers-color-scheme: dark) {
    .custom-alert {
      --alert-bg-color: #061633;
      --alert-fg-color: #6ea8fe;
      --alert-border-color: #0a4298;
    }
  }

  .custom-alert::part(close) {
    background-color: var(--alert-fg-color);
    color: var(--alert-bg-color);
    border-radius: 0.25rem;
    padding: 0.25rem;
  }
</style>

<alert-element open closable class="custom-alert">
  <span slot="icon">
    <svg xmlns="http://www.w3.org/2000/svg" width="1.25em" height="1.25em" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
      <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2"/>
    </svg>
  </span>
  This alert has custom styling applied to it.
</alert-element>

Toast notifications

To display an alert as a toast notification, create the alert element and call its toast() method. For more information, check the documentation.

When checked, immediately cancels the active toast and starts a new one. Otherwise, if a toast is still active, any subsequent calls to toast() will be ignored.

This is an info toast notification. This is a success toast notification. This is a neutral toast notification. This is a warning toast notification. This is a danger toast notification.
Source code
<button type="button" data-variant="info">Info</button>
<button type="button" data-variant="success">Success</button>
<button type="button" data-variant="neutral">Neutral</button>
<button type="button" data-variant="warning">Warning</button>
<button type="button" data-variant="danger">Danger</button>

<input type="checkbox" id="forceRestart">
<label for="forceRestart">Force restart</label>

<alert-element variant="info" duration="3000" closable>
  This is an info toast notification.
</alert-element>

<alert-element variant="success" duration="3000" closable>
  This is a success toast notification.
</alert-element>

<alert-element variant="neutral" duration="3000" closable>
  This is a neutral toast notification.
</alert-element>

<alert-element variant="warning" duration="3000" closable>
  This is a warning toast notification.
</alert-element>

<alert-element variant="danger" duration="3000" closable>
  This is a danger toast notification.
</alert-element>

<script>
  const variants = ['info', 'success', 'neutral', 'warning', 'danger'];

  variants.forEach(variant => {
    const button = document.querySelector(`button[data-variant="${variant}"]`);
    const alert = document.querySelector(`alert-element[variant="${variant}"]`);

    button.addEventListener('click', () => {
      alert.toast({ forceRestart });
    });
  });

  let forceRestart = false;
  const restartCheckbox = document.querySelector('input[type="checkbox"]');

  restartCheckbox.addEventListener('change', evt => {
    forceRestart = evt.target.checked;
  });
</script>

Creating toasts imperatively

For convenience, you can create a utility function that creates a toast notification imperatively, instead of creating the alert elements in your markup. To do this, you can generate the alert element using JavaScript and call the toast() method on it. For more information, check the documentation.

Source code
<button type="button">Create Toast</button>

<script>
  const button = document.querySelector('button');

  let count = 0;

  button.addEventListener('click', () => {
    toastify(`This is a custom toast alert #${++count}`, {
      icon: `
        <svg xmlns="http://www.w3.org/2000/svg" width="1.25em" height="1.25em" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
          <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
          <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
        </svg>
      `,
      variant: 'info'
    });
  });

  function toastify(message, options = {}) {
    const defaults = {
      duration: 3000,
      variant: 'neutral',
      icon: ''
    };

    options = { ...defaults, ...options };

    const icon = options.icon ? `<span slot="icon">${options.icon}</span>` : '';

    const alert = Object.assign(document.createElement('alert-element'), {
      closable: true,
      duration: options.duration,
      variant: options.variant,
      innerHTML: `${icon}${escapeHtml(message)}`
    });

    return alert.toast();
  }

  function escapeHtml(html) {
    const div = document.createElement('div');
    div.textContent = html;
    return div.innerHTML;
  }
</script>

Custom toast stack position

You can customize the position of the toast stack by targeting the .alert-toast-stack class in your stylesheet.

NOTE
In real-world applications, toast alerts should be displayed in a single position on the screen for better user experience. This example uses multiple positions for demonstration purposes only.
Toast stack position
Source code
<style>
  [data-toast-stack-position="top-left"] .alert-toast-stack::part(base) {
    right: auto;
    left: 0;
  }

  [data-toast-stack-position="top-center"] .alert-toast-stack::part(base) {
    right: 50%;
    transform: translateX(50%);
  }

  [data-toast-stack-position="top-right"] .alert-toast-stack::part(base) {
    top: 0;
    right: 0;
  }

  [data-toast-stack-position="bottom-left"] .alert-toast-stack::part(base) {
    right: auto;
    left: 0;
    top: auto;
    bottom: 0;
  }

  [data-toast-stack-position="bottom-center"] .alert-toast-stack::part(base) {
    right: 50%;
    transform: translateX(50%);
    top: auto;
    bottom: 0;
  }

  [data-toast-stack-position="bottom-right"] .alert-toast-stack::part(base) {
    top: auto;
    bottom: 0;
  }
</style>

<label><input type="radio" value="top-left" name="toast-stack-poisiton" checked> Top left</label>
<label><input type="radio" value="top-center" name="toast-stack-poisiton"> Top center</label>
<label><input type="radio" value="top-right" name="toast-stack-poisiton"> Top right</label>
<label><input type="radio" value="bottom-left" name="toast-stack-poisiton"> Bottom left</label>
<label><input type="radio" value="bottom-center" name="toast-stack-poisiton"> Bottom center</label>
<label><input type="radio" value="bottom-right" name="toast-stack-poisiton"> Bottom right</label>

<button type="button">Create Toast</button>

<script>
  const button = document.querySelector('button');
  const alert = Object.assign(document.createElement('alert-element'), {
    variant: 'info',
    duration: 3000,
    closable: true
  });

  alert.addEventListener('alert-after-hide', () => {
    document.body.removeAttribute('data-toast-stack-position');
  });

  button.addEventListener('click', () => {
    const checkedRadio = document.querySelector('input[type="radio"]:checked');
    const position = checkedRadio ? checkedRadio.value : 'top-right';

    alert.textContent = `This alert is currently positioned at ${position}.`;
    alert.toast({ forceRestart: true });

    document.body.setAttribute('data-toast-stack-position', position);
  });
</script>

Custom animations

You can customize the animations of the alert element using the customAnimations property. For more information, check the documentation.

This alert has custom animations applied to it.
Source code
<alert-element variant="info" closable>
  This alert has custom animations applied to it.
</alert-element>

<script>
  const alert = document.querySelector('alert-element');

  alert.customAnimations = {
    show: {
      keyframes: [
        { opacity: 0, transform: 'rotateX(90deg) scale(0.8)', filter: 'blur(8px)' },
        { opacity: 1, transform: 'rotateX(-10deg) scale(1.05)', filter: 'blur(2px)' },
        { opacity: 1, transform: 'rotateX(5deg) scale(0.97)', filter: 'blur(1px)' },
        { opacity: 1, transform: 'rotateX(0deg) scale(1)', filter: 'blur(0)' }
      ],
      options: {
        duration: 700,
        easing: 'cubic-bezier(0.22, 1, 0.36, 1)',
        fill: 'forwards'
      }
    },
    hide: {
      keyframes: [
        { opacity: 1, transform: 'scale(1)', filter: 'blur(0)' },
        { opacity: 0, transform: 'scale(0.8)', filter: 'blur(6px)' }
      ],
      options: {
        duration: 450,
        easing: 'ease-in',
        fill: 'forwards'
      }
    }
  };
</script>

No animations

You can disable animations by adding the no-animations attribute to the alert element.

This is an alert with no animations.
Source code
<alert-element variant="warning" closable no-animations>
  This is an alert with no animations.
</alert-element>

User interaction

When the user interacts with the alert (e.g., hovers over it or focuses it), the auto-hide countdown is paused. Once the user stops interacting with the alert, the countdown resumes.

Auto-dismiss in 10s
Interact to pause the timer — try tabbing to this focusable link or hovering over the alert.
Source code
<alert-element closable countdown duration="10000">
  <strong>Auto-dismiss in 10s</strong><br>
  Interact to pause the timer — try tabbing to this
  <a href="#" onclick="event.preventDefault()">focusable link</a> or hovering over the alert.
</alert-element>

Invoker commands

With invoker commands you can toggle alert's visibility in a declarative way using command and commandfor attributes on a button element, targeting the alert element element by its id attribute.

The Invoker Commands API is a new API that allows you to create declarative commands for HTML elements. It is currently in the early stages and may not be supported by all browsers. Check the supported browsers.

Control the alert's visibility using invoker commands:

Alert with invoker commands
This alert uses invoker commands to toggle its visibility.
Source code
<button type="button" commandfor="myAlert" command="--alert-show">Show Alert</button>
<button type="button" commandfor="myAlert" command="--alert-hide">Hide Alert</button>

<alert-element variant="info" id="myAlert">
<strong>Alert with invoker commands</strong><br>
This alert uses invoker commands to toggle its visibility.
</alert-element>

License

Licensed under the The MIT License (MIT)