<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. Custom variant
  7. Custom styling
  8. Toast notifications
  9. Creating toasts imperatively
  10. Custom toast stack position
  11. Custom animations
  12. 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 to hide this alert.
Source code
<button type="button">Show Alert</button>

<alert-element variant="info" closable>
  Click the close button to hide this alert.
</alert-element>

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

  alert.addEventListener('alert-show', () => {
    button.setAttribute('disabled', '');
  });

  alert.addEventListener('alert-after-hide', () => {
    button.removeAttribute('disabled');
  });

  button.addEventListener('click', () => {
    alert.show();
  });
</script>

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
<button type="button">Show Alert</button>

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

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

  button.addEventListener('click', () => {
    alert.show();
  });
</script>

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 {
    --alert-custom-variant-color: #ec4899;
  }

  @media (prefers-color-scheme: dark) {
    alert-element {
      --alert-custom-variant-color: #fe94cd;
    }
  }

  alert-element[variant="custom"]::part(base) {
    border-top-color: var(--alert-custom-variant-color);
  }

  alert-element[variant="custom"]::part(icon) {
    color: var(--alert-custom-variant-color);
  }
</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(base) {
    border-width: 1px;
  }

  .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)}`
    });
  }

  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-right"] .alert-toast-stack::part(base) {
    top: 0;
    right: 0;
  }

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

  [data-toast-stack-position="top-left"] .alert-toast-stack::part(base) {
    right: auto;
    left: 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>

<input type="radio" id="top-right" value="top-right" name="name="toast-stack-poisiton" checked>
<label for="top-right">Top right</label>

<input type="radio" id="top-center" value="top-center" name="name="toast-stack-poisiton">
<label for="top-center">Top center</label>

<input type="radio" id="top-left" value="top-left" name="name="toast-stack-poisiton">
<label for="top-left">Top left</label>

<input type="radio" id="bottom-left" value="bottom-left" name="name="toast-stack-poisiton">
<label for="bottom-left">Bottom left</label>

<input type="radio" id="bottom-center" value="bottom-center" name="name="toast-stack-poisiton">
<label for="bottom-center">Bottom center</label>

<input type="radio" id="bottom-right" value="bottom-right" name="name="toast-stack-poisiton">
<label for="bottom-right">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 = `I'm 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
<button type="button">Show Alert</button>

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

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

  alert.customAnimations = {
    show: {
      keyframes: [
        { opacity: 0, transform: 'rotateX(90deg) scale(0.8)' },
        { opacity: 1, transform: 'rotateX(-10deg) scale(1.05)' },
        { opacity: 1, transform: 'rotateX(5deg) scale(0.97)' },
        { opacity: 1, transform: 'rotateX(0deg) scale(1)' }
      ],
      options: {
        duration: 600,
        easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
      }
    },
    hide: {
      keyframes: [
        { opacity: 1, transform: 'scale(1)' },
        { opacity: 0, transform: 'scale(0.8)' }
      ],
      options: {
        duration: 400,
        easing: 'ease-in'
      }
    }
  };

  button.addEventListener('click', () => {
    alert.show();
  });
</script>

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)