Modals
Dialogs are streamlined, but flexible, dialog prompts with the minimum required functionality.
Modal Base
<div class="sui-modal"> <div role="dialog" id="modal-unique-id" class="sui-modal-content" aria-modal="true" aria-labelledby="modal-title-unique-id" aria-describedby="modal-description-unique-id" > ... add here modal content ... </div> </div>
data
attributes to the element that's going to trigger the action (to open or to close the modal).
<!-- OPEN MODAL. You can only use these attributes on an element that's placed "outside" modal. 1. (required) data-modal-open="unique-id" This attribute will open the modal you assign. 2. data-modal-open-focus="focused-element-id" This attribute will focus element you assign that's placed inside modal when open function fires. !! When not used, modal will find the first focusable element in the markup to focus it. 3. data-modal-close-focus="focused-element-id" This attribute will focus element you assign that's placed outside modal when close function fires. !! When not used, modal will find focus-back button you clicked to open modal on first place. 4. data-modal-mask="true" This attribute will allow overlay mask to fire close function when clicking on it. !! When not used, overlay mask will do nothing. 5. data-esc-close true|false Default: true Handles whether the ESC key closes the modal. If 'true', pressing the ESC key closes the modal. If 'false', pressing the ESC key does nothing. 6. data-modal-animated true|false Default: true Handles whether the modal is animated. If 'true', modal will be animated. If 'false', modal will not be animated. --> <button data-modal-open="unique-id" data-modal-open-focus="focused-element-id" data-modal-close-focus="focused-element-id" data-modal-mask="true" data-esc-close="true" data-modal-animated="true" > Open Modal </button> <!-- CLOSE MODAL. You can use this attribute on an element that's placed "inside" modal. --> <button data-modal-close="" > Close Modal </button>
( function( $ ) { /** * OPEN MODAL. * * @desc Trigger this function when performing a click action on * an element that's placed outside modal. * * @param modalId * The ID of the element serving as the modal container. * * @param focusAfterClosed * This is a required and important paramether. You can use the following * values: * - this, when you click on a button or any element to open the modal it * will find this same element to focus it when modal closes. * - unique-id, when you want to focus an element outside modal when * it closes. * * @param focusWhenOpen (optional) * Use `element-unique-id` that's inside modal for screenreader to * focus it when modal opens. You can set it to `undefined` if you * don't want/need this function and modal will automatically find * the first focusable element. * * @param hasOverlayMask (optional) * When is set to `true` modal overlay mask can be clicked and will * fire close modal function. * * @param isCloseOnEsc (optional) * boolean * Default: true * Handles whether the ESC key closes the modal. * If 'true', pressing the ESC key closes the modal. * If 'false', pressing the ESC key does nothing. * * @param isAnimated * Default: true * Optional boolean parameter that when it's set to "true", it will enable animation in dialog box. * * SUI.openModal( modalId, focusAfterClosed, focusWhenOpen, hasOverlayMask, isCloseOnEsc, isAnimated ); */ $( 'button' ).on( 'click', function() { const modalId = 'modal-unique-id', focusAfterClosed = this, focusWhenOpen = undefined, hasOverlayMask = false, isCloseOnEsc = true, isAnimated = true ; SUI.openModal( modalId, focusAfterClosed, focusWhenOpen, hasOverlayMask, isCloseOnEsc, isAnimated ); }); /** * CLOSE MODAL. * * @desc Hides the current top modal and sets focus on the element * specified for "focusAfterClosed" on open function. * * SUI.closeModal( closeButton ); */ $( 'button' ).on( 'click', function() { SUI.closeModal(); }); }( jQuery ) );
Modal Sizes
Modals come in 4 different sizes:
By default modals assign 100% width to its content. You can get this by using sui-modal
class only.
<div class="sui-modal"> ... </div>
Extra large modals assign 980px max-width to its content. You can get this by using sui-modal sui-modal-xl
classes together.
<div class="sui-modal sui-modal-xl"> ... </div>
Large modals assign 600px max-width to its content. You can get this by using sui-modal sui-modal-lg
classes together.
<div class="sui-modal sui-modal-lg"> ... </div>
Large modals assign 500px max-width to its content. You can get this by using sui-modal sui-modal-md
classes toegether.
<div class="sui-modal sui-modal-md"> ... </div>
Large modals assign 400px max-width to its content. You can get this by using sui-modal sui-modal-sm
classes toegether.
<div class="sui-modal sui-modal-sm"> ... </div>
Replace Modal
This action will allow you to replace the current opened modal with a new one.
These actions can be added directly on markup asdata
attributes to the element that's going to trigger the action (to open or to close the modal).
<!-- REPLACE MODAL. You can only use these attributes on an element that's placed "inside" currently opened modal. 1. (required) data-modal-replace="unique-id" This attribute will close current opened modal and open instead the new modal you assigned. 2. (required) data-modal-close-focus="unique-id" This attribute will help modal re-assign focusable element, that's lost after we replaced modal, when close function fires. 3. data-modal-open-focus="unique-id" This attribute will focus element you assign that's placed inside modal when open function fires. !! When not used, modal will find the first focusable element in the markup to focus on it. 4. data-modal-replace-mask="true" This attribute will allow new modal to have an overlay mask that fires close function when clicking on it. !! When not used, overlay mask will do nothing. 5. data-esc-close true|false Default: true Handles whether the ESC key closes the modal. If 'true', pressing the ESC key closes the modal. If 'false', pressing the ESC key does nothing. 6. data-modal-animated true|false Default: true Handles whether the modal is animated. If 'true', modal will be animated. If 'false', modal will not be animated. --> <button data-modal-replace="unique-id" data-modal-open-focus="element-unique-id" data-modal-close-focus="element-unique-id" data-modal-replace-mask="true" data-esc-close="true" data-modal-animated="true" > </button>
/** * REPLACE MODAL * * @desc Hides the current modal and replaces it with another. * * @param newModalId * ID of the modal that will replace the currently open top modal. * * @param newFocusAfterClosed * Optional ID or DOM node specifying where to place focus when the new modal closes. * If not specified, focus will be placed on the element specified by the modal being replaced. * * @param newFocusFirst * Optional ID or DOM node specifying where to place focus in the new modal when it opens. * If not specified, the first focusable element will receive focus. * * @param hasOverlayMask * Optional boolean parameter that when is set to "true" will enable a clickable overlay * mask to the new opened modal. This mask will fire close modal function when you click it. * * @param isCloseOnEsc (optional) * boolean * Default: true * Handles whether the ESC key closes the modal. * If 'true', pressing the ESC key closes the modal. * If 'false', pressing the ESC key does nothing. * * @param isAnimated * Default: true * Optional boolean parameter that when it's set to "true", it will enable animation in dialog box. * * SUI.replaceModal( newModalId, newFocusAfterClosed, newFocusFirst, hasOverlayMask, isCloseOnEsc, isAnimated ); */ ( function( $ ) { $( 'button' ).on( 'click', function() { const newModalId = 'modal-unique-id', newFocusAfterClosed = 'element-unique-id', newFocusFirst = 'element-unique-id', hasOverlayMask = true, isCloseOnEsc = true, isAnimated = true, ; SUI.replaceModal( newModalId, newFocusAfterClosed, newFocusFirst, hasOverlayMask, isCloseOnEsc, isAnimated ); }); }( jQuery ) );
Slide Modal
Some modals have more than one step, and even when you can use Replace Modal to show different content, another approach could be using Slide Modal where you going to use 1 modal with 2 or more sliders inside and each with the content you want to show. You will also have to option to animate the slide with fade-in transitions from left or right depending the case or if you want to use it.
<div class="sui-modal sui-modal-md"> <div role="dialog" id="unique-id" class="sui-modal-content" aria-live="polite" aria-modal="true" aria-labelledby="" > <div id="slide-unique-id" class="sui-modal-slide sui-active sui-loaded" data-modal-size="md" ></div> <!-- NOTE: Notice the attribute "data-modal-size", it is important when you have slides of different sizes. Also, make sure modal size when opening has the same value of the first slide. --> <div id="slide-unique-id" class="sui-modal-slide" data-modal-size="sm" ></div> </div> </div>
<!-- ACTION: Slide Content You can only use these attributes on an element that's placed "inside" currently opened modal. 1. "data-modal-slide" attribute will open the slide you assign. 2. "data-modal-slide-focus" attribute will focus element you assign that's placed inside modal on modal open action. 3. "data-modal-slide-intro" attribute will set from where the slide will animate. If not chosen the slide intro animation will be fade in. --> <button data-modal-slide="unique-id" data-modal-slide-focus="element-unique-id" data-modal-slide-intro="next" > </button>
( function( $ ) { /** * SLIDE-IN NEW CONTENT. * * @desc Uses the same dialog to display different content that will slide to show. * * @param newSlideId * ID of the slide that will replace the currently active slide content. * * @param newSlideFocus * Optional ID or DOM node specifying where to place focus in the new slide when it shows. * If not specified, the first focusable element will receive focus. * * @param newSlideEntrance * Determine if slide entrance animation comes from left or right of the screen. * You can use: next, back, left or right. * If not specified, the slide entrance animation will be "fade in". * * SUI.slideModal( newSlideId, newSlideFocus, newSlideEntrance ); */ $( 'button' ).on( 'click', function( e ) { const newSlideId = 'slide-unique-id', newSlideFocus = 'element-unique-id', newSlideEntrance = 'next' ; SUI.slideModal( newSlideId, newSlideFocus, newSlideEntrance ); }); }( jQuery ) );
Modal Elements
Modals have 2 basic elements: content wrapper, skip button and step dots.
Content Wrapper
This element holds the main content and is important for the modal to work correctly.
This is the most important element for a modal and without it nothing will work correctly. The sui-box
element, but it can also hold an skip modal button that is usually placed after sui-box
element.
Sample markup
<div class="sui-modal"> <div role="dialog" id="modal-unique-id" class="sui-modal-content" aria-modal="true" aria-labelledby="title-unique-id" aria-describedby="desc-unique-id" > <!-- NOTE: You can place skip button, slider modal wrapper or "sui-box" with any of its element. --> </div> </div>
Skip Button
Optional element for users to skip into next step, next modal or close everything. It looks like a link but with gray font color.
This element is placed before content wrapper closing tag, right after sui-box
closes, but you can also have it inside of sui-box
if that's what you need.
Code below represents only the markup needed for the element to show up correctly styled, but if you want this element to close or change modal, or maybe switch slide you have to add proper data attribute or assign to it the desired JS function.
Sample markup
<!-- Skip Button (using "button" tag) --> <button role="button" class="sui-modal-skip">Skip this</button> <!-- Skip Button (using "a" tag) --> <a href="#" role="button" class="sui-modal-skip">Skip this</a>
Inside modal content wrapper you will have to use sui-box
div to wrap content in a white box. This element is basic when placed outside modal, but inside each part (header, body and footer) allow further customization to easily get a pixel perfect result when compared with the design.
Box Header
Box Header - Variations |
Box Header - VariationsSpacingYou can overwrite Box Header default padding (spacing) with
Content AlignmentHave in mind that Box Header uses flexbox by default to align elements in a single row. You can overwrite default content alignment with
Flatten ElementBy default Box Header comes with bottom border to mark a separation with elements placed after this. Remove border and bottom padding using |
Box Header - Title |
Box Header - TitleBy default this element has
|
Box Header - Logo |
Box Header - LogoThis element is used to highlight a service logo for brands, for example: when setting up HubSpot integration in Forminator. SR Hidden This markup will hide box header logo element from screenreader. Use this markup when image provided does not contain relevant information for users, but if that's not the case then is better to use SR Accessible markup. <figure class="sui-box-logo" aria-hidden="true"> <img src="./path/to/image.png" srcset="./path/to/image.png 1x, ./path/to/image@2x.png 2x" /> </figure> SR Accessible This markup will allow box header logo element to be accessible by screenreader providing a brief description of the image that you will place on <figure class="sui-box-logo"> <img src="./path/to/image.png" srcset="./path/to/image.png 1x, ./path/to/image@2x.png 2x" alt="Image brief description" /> <figcaption>Image detailed (extended) description.</figcaption> </figure> |
Box Header - Banner |
Box Header - BannerThis element is used to place a banner (image) that occupies full width of the modal, for example: Beehive on board design. SR Hidden This markup will hide box header banner element from screenreader. Use this markup when image provided does not contain relevant information for users, but if that's not the case then is better to use SR Accessible markup. <figure class="sui-box-banner" aria-hidden="true"> <img src="./path/to/image.png" srcset="./path/to/image.png 1x, ./path/to/image@2x.png 2x" /> </figure> SR Accessible This markup will allow box header banner element to be accessible by screenreader providing a brief description of the image that you will place on <figure class="sui-box-banner"> <img src="./path/to/image.png" srcset="./path/to/image.png 1x, ./path/to/image@2x.png 2x" alt="Image brief description" /> <figcaption>Image detailed (extended) description.</figcaption> </figure> |
Box Header - Steps |
Box Header - StepsThis element is used to show users where they are and how many steps are missing before they finish setting up something. For example, Forminator uses this element when users create a new quiz. This element works with two classes: sui-box-steps and sui-{size} where {size} defines the width and height of the dots and can be Also, if you want to place Steps element on top center of the modal (as it shows on the sample above) you can use Informative Steps This markup will be hidden from screenreader and regular users won't be able to interact with it either. It's just to show in which step user is at the moment. <div class="sui-box-steps sui-md sui-steps-float" aria-hidden="true"> <span class="sui-current">First step (current).</span> <span>Second step.</span> <span>Third step.</span> </div> Interactive Steps These are clickable steps that users can interact with. For example, you can use Replace Modal attributes or functions to open a new modal when clicking on second step button. <div class="sui-box-steps sui-md sui-steps-float"> <button class="sui-current" disabled>First step (current).</button> <button>Go to second step.</button> <button>Go to third step.</button> </div> |
Box Header - Buttons |
Box Header - ButtonsWhen you need to add a button for any action just check on SUI Buttons section. In addition to that have in mind: #1 Float Buttons: There are times you will have to place an button on top right or left of the modal, for those cases just include
#2 Icons Size: By default icons are set to 12px, but there are times you gonna need to use a bigger icon. For those cases in the icon element include
|
Box Body
Box Body - Variations |
Box Body - VariationsSpacingYou can overwrite Box Body default padding (spacing) with
Content AlignmentBy default Box Body aligns content to left but you can overwrite how content will align with
|
Box Footer
Box Footer - Variations |
Box Footer - VariationsSpacingYou can overwrite Box Footer default padding (spacing) with
Content AlignmentHave in mind that Box Footer uses flexbox by default to align elements in a single row. You can overwrite default content alignment with
Flatten ElementBy default Box Header comes with bottom border to mark a separation with elements placed after this. Remove border and bottom padding using |
Box Footer - Steps |
Box Footer - StepsThis element is used to show users where they are and how many steps are missing before they finish setting up something. For example, Hustle uses this element for welcoming new users. This element works with two classes: sui-box-steps and sui-{size} where {size} defines the width and height of the dots and can be Informative Steps This markup will be hidden from screenreader and regular users won't be able to interact with it either. It's just to show in which step user is at the moment. <div class="sui-box-steps sui-sm" aria-hidden="true"> <span class="sui-current">First step (current).</span> <span>Second step.</span> <span>Third step.</span> </div> Interactive Steps These are clickable steps that users can interact with. For example, you can use Replace Modal attributes or functions to open a new modal when clicking on second step button. <div class="sui-box-steps sui-sm"> <button class="sui-current" disabled>First step (current).</button> <button>Go to second step.</button> <button>Go to third step.</button> </div> |
Accessibility
Here's a list of some rules to follow when creating correct markup for modals to allow screenreader users navigate easily through our content:
1. Modals must be properly labelled.
You must use aria-labelledby="unique-id"
or aria-label="Some text"
but always have your modals properly labelled. In addition to this you can use aria-describedby="unique-id"
in case you have a longer text with more information.
2. Changing content.
You must use aria-live="polite"
attribute for sui-modal-content
when there are changes on the modal content while users are interacting with it. For example: forms showing errors, lazy load content, etc.
In case you lazy load content make sure to alert users there's some content being loaded.
4. Close button as first element.
This element should always be placed at the beginning of the content. For example, on Hustle Create Module modal you will have to place inside sui-box-header
4 elements in the following order: floated to right close button, floated steps element (hidden for screenreader), large title and description.
Modal Samples
1. HubSpot Integration
This sample was grabbed from Forminator project. When clicking on button we allow users to create contact and ticket for proper HubSpot integration.
Create Contact
Let's start with choosing the HubSpot list and matching up your form fields with the default HubSpot contact fields to make sure we’re sending data to the right place.
HubSpot Fields | Forminator Fields |
---|---|
Email Address | |
First Name | |
Last Name | |
Job Title |
Create Ticket
In addition to adding a new contact to your HubSpot account, you can also create a HubSpot ticket for each form submission.
2. Hummingbird On Board
This sample was grabbed from Hummingbird project. The modal should close when performance test finishes or when user clicks on skip button.
Get Started
Welcome to Hummingbird, the hottest Performance plugin for WordPress! We recommend running a quick performance test before you start tweaking things. Alternatively you can skip this step if you'd prefer start customizing.
This is only a performance test. Once you know what to fix you can get started in the next steps.
Hummingbird is running a test to measure your website performance.
3. Create Hustle Module.
This sample was grabbed from Hustle project. The modal slides between two contents changing modal size.
Choose Content Type
Let's start by choosing an appropriate content type based on your goal.
Create Popup
Let's give your new popup a name. What would you like to name it?
4. Import Hustle Pop-up.
This sample was grabbed from Hustle project. This is a simple small-size modal.
Import Pop-up
Choose the popup configuration file and hit import to import your popup.
5. Dismiss Notice.
This sample was grabbed from Hustle project. This is a simple small-size modal.
Dismiss Migrate Data Notice
Are you sure you wish to dismiss this notice? Make sure you've already migrated data of your existing modules, and you don't need to migrate data anymore.
6. Beehive On Board.
This sample was grabbed from Beehive project. This modal uses "replace" and "slide" functions to perform different actions.
Welcome to Beehive Pro
Andy, welcome to the hottest Google Analytics plugin for WordPress. Let's get started by connecting your Google Analytics account so that we can feed your analytics data. If you only want to enable tracking without reports, you can paste your analytics code via the link below.
Easily connect with Google and paste the access code below. Please note, we only retrieve analytics information and no personally identifiable data.
We recommend to set up API project, as it results in smoother experience for site admins. You can check the documentation on how to set up API project here.
Set up your account
We have successfully connected your Google account. The next step is to choose your Analytics Profile to get data feeding.
Add Tracking Code
Paste your Google Analytics tracking ID in the field below to enable analytics tracking. You can get your ID here.
Finishing Setup...
Please wait a few moments while we set up your account. Note that data can take up to 24 hours to display.
7. Modal without animation
This sample was to show a modal without open/close animation.
Create Contact
Let's start with choosing the HubSpot list and matching up your form fields with the default HubSpot contact fields to make sure we’re sending data to the right place.
HubSpot Fields | Forminator Fields |
---|---|
Email Address | |
First Name | |
Last Name | |
Job Title |
Create Ticket
In addition to adding a new contact to your HubSpot account, you can also create a HubSpot ticket for each form submission.