Skip to content

Modal

The h-modal webcomponent provides a solid foundation for creating lightboxes, dialogs, popups or whatever else. h-modal webcomponent uses the <h-portal> webcomponent to render its content in a different location. Every modal is portaled to a <h-portal-target name="modals"> which is direct children of document body element to avoid z-index issues.

Note: h- stands for headless. This is naming convention used for every webcomponent as they must have a two-part name.

Features:

  • Keyboard support
  • Disables interaction below the Modal
  • Disables scrolling of the page when the Modal is open
  • Manages focus, keeps it within modal until closed
  • Adds appropriate ARIA roles
  • Provides additional webcomponents for faciliate use
  • Provides default styles (which may be customized)

Modals uses slots to render content in the modal. The following slots are available:

  • header
  • body
  • footer

Attributes

Attribute name Type Default Description
opened boolean false decides if modal is opened on render
class string '' class to customize modal look or position
transition string scale transition class name to change how modals open and closes

Note: Hidden attribute should always be part of h-modal component to avoid layout shifts.

DOM events

This webcomponent listens to the following DOM events:

This webcomponent also dispatches the following DOM events:

Basic modal

HTML
<h-modal-opener name="modal">Click me!</h-modal-opener>

<h-modal id="modal" hidden>
    <h-modal-header>
        <header><strong class="h6 font_semibold">Loyalty program</strong></header>

        <h-modal-close class="btn btn_icon">
            <svg class="btn__icon icon icon_l">
                <use xlink:href="/assets/img/icons/symbol-defs.svg#icon-x"></use>
            </svg>
        </h-modal-close>
    </h-modal-header>

    <h-modal-body>
        <p class="size_s">When you buy products covered by the loyalty program, you collect points, which you can then exchange for other products available in the store or receive a permanent discount.</p>
        <p class="size_s">The catalog of products available for points can be found in your customer account.</p>
    </h-modal-body>

    <h-modal-footer>
        <h-modal-close class="modal__btn btn btn_outline">Cancel</h-modal-close>
        <button class="modal__btn btn btn_primary">Create an account and collect points</button>
    </h-modal-footer>
</h-modal>

Inner h-modal components

To facilitate modal creation we provide several components that may be used within modal. They do hide implemenation that is often repetitive. For example h-modal-header markup looks like this:

h-modal-header
<div class="modal__header" slot="header"></div>

So this is the same:

<h-modal hidden opened>
    <div class="modal__header" slot="header"></div>
        Header
    </div>
</h-modal>
<h-modal hidden opened>
    <h-modal-header>
        Header
    </h-modal-header>
</h-modal>

h-modal-opener

The h-modal-opener is a webcomponent that when clicked will open the modal with given name attribute. The h-modal webcomponent with associated id is the actual modal that will open. You may have several h-modal-opener's with same name attribute.

h-modal-header

The h-modal-header is a webcomponent that contains the modal header. By default it is put in header slot in the modal and has modal__header css class.

h-modal-body

The h-modal-body is a webcomponent that contains the modal body (content). By default it is put in body slot in the modal and has modal__body css class.

The h-modal-footer is a webcomponent that contains the modal footer. By default it is put in footer slot in the modal and has modal__footer css class.

h-modal-close

The h-modal-close is a webcomponent that has ability to close modal. It has to be child of modal he wants to close

Opened modal

HTML
<h-modal hidden opened>
    <h-modal-header>
        Simple header
    </h-modal-header>

    <h-modal-body>
        Im opened at start
    </h-modal-body>
</h-modal>

Changing default transition

HTML
<h-modal hidden transition="slide-in">
    <h-modal-header>
        Simple header
    </h-modal-header>

    <h-modal-body>
        Im opened at start
    </h-modal-body>
</h-modal>

Note: Only scale transition is available by default. If you would like to provide own transition you have to write it by yourself:

example of slide-in transition implementation
.modal_show-slide-in-start,
.modal_hide-slide-in-end {
    opacity: 0;
    transform: translate3d(0, -4rem, 0);
}

.modal_show-slide-in-end,
.modal_hide-slide-in-start {
    opacity: 1;
    transform: translate3d(0, 0, 0);
}

Default transition

HTML
<h-modal hidden>
    <h-modal-header>
        Simple header
    </h-modal-header>

    <h-modal-body>
        Im opened at start
    </h-modal-body>
</h-modal>
scale transition implementation
.modal_show-scale-start,
.modal_hide-scale-end {
    opacity: 0;
    transform: scale(1.05);
}

.modal_show-scale-end,
.modal_hide-scale-start {
    opacity: 1;
    transform: scale(1);
}

API

As webcomponent is basically custom HTML element. You can get reference to it and use API that it provides. h-modal has two public methods:

open(): void

Opens modal

const modal = document.querySelector('h-modal#my-modal');
open();

close(): void

Closes modal

const modal = document.querySelector('h-modal#my-modal');
close();

Customization

Custom slots

h-modal is fully customizable. You can provide own HTML elements or webcomponents to change how the modal looks.

HTML
<h-modal-opener name="modal">Click me!</h-modal-opener>

<h-modal id="modal" hidden>
    <div slot="header">
        My own header
    </div>

    <div slot="body">
        My own super body
    </div>

    <div slot="footer">
        My own super footer
    </div>
</h-modal>

Adding classes

If you wish to add classes to your modal elements simply add them to the webcomponents and they will propagate to the opened modal. It works with custom slots as well:

HTML
<h-modal-opener name="modal">Click me!</h-modal-opener>

<h-modal id="modal" class="my-custom-modal-container" hidden>
    <h-modal-header class="modal-custom-header">
        Simple header
    </h-modal-header>

    <h-modal-body class="modal-custom-body">
        Simple body
    </h-modal-body>

    <div slot="footer" class="modal-custom-footer">
        My own super footer
        <h-modal-close class="modal__btn btn btn_outline">Cancel</h-modal-close>
    </div>
</h-modal>

Webcomponents reference