Modal

A window that appears on top of the main content, often used to focus user attention on specific information, gather input, or display supplemental content. It usually has a clear close option.

Demo

Scripts

Add these before the </body> tag in your site/page settings

GSAP
 <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
Modal component
<script src="https://cdn.jsdelivr.net/npm/socks-ui@{v}/dist/modal.js"></script>

Features

  • Full keyboard navigation
  • Keyboard trap when a modal is open
  • All attributes for screen readers added
  • Closes by clicking a close button or the background overlay

Anatomy

  • Trigger Button(/s)
  • Wrapper
    • Root
      • Title (optional)
      • Close Button (optional)
    • Overlay

Usage

Main Attributes:

s-modal-trigger={modal-wrapper-id} - A button that opens the modal. The value of this attribute should be the ID of the modal wrapper. You can have more than one trigger

s-modal = wrapper - The parent div that wraps the actual modal and an overlay div

s-modal = root - The modal element that contains info

s-modal = overlay - (optional) An overlay that makes background elements less visible. It closes the modal when clicked

s-modal = title -  An element that acts as the title. If you don't want to include this element, you have to set an aria-label attribute (aria-label="Your title") on the root modal element

s-modal = close - A button that closes the modal. You can have more than one close button

Advanced Attributes (optional):

s-modal-manual - Set this if you don't want to have trigger buttons and want to avoid the console error. Your modal should be opened programmatically using the openModal method (see below)

Advanced

Events

modal-open

modal-close

In both events, the accordion being toggled can be accessed through event.detail.

Example usage:

window.addEventListener('modal-open', (event)=> {
    console.log(event.detail)
})
No custom events are exported for this component.

Methods

socks.modals["id"].open() - Open modal with given ID

socks.modals["id"].open() - Close modal with given ID

How to use them:

// this opens the modal that has the ID "some-id"
socks.modals["some-id"].open()

// you could also save them in your own variable to shorten it:
const modals = socks.modals;
modals["some-id"].open()

// if your ID doesn't have dashes, you could also do this:
socks.modals.some_id.open()
No custom methods are exported for this component.

Use Cases

Reset form when modal closes

// listens for closing modals
window.addEventListener('modal-close', (event)=> {
  // shows form
  event.detail.querySelector('form').style.display = 'block';
  // hides success message
  event.detail.querySelector('.w-form-done').style.display = 'none';
})

Close modal after form submission

const delay = 4 // how many seconds to wait
const form = document.querySelector('.your-form') // form selector
const modalID = form.closest('[s-modal="wrapper"]').id // gets modal ID for you
// listen for submissions on that form
form.addEventListener('submit', ()=>{
  setTimeout(()=> {
    socks.modals[modalID].close() // closes the parent modal
  }, delay * 1000)
})
No special use cases added yet
{"type":"@webflow/XscpData","payload":{"nodes":[{"_id":"1258a1b7-d0a3-ab4e-2b5c-84063e7d6303","type":"Block","tag":"div","classes":[],"children":["a2c9bb0d-3db4-45e9-fdc8-802c4d770be6","e887d389-8ab2-323f-90a1-7524c3f09bf1"],"data":{"text":false,"tag":"div"}},{"_id":"a2c9bb0d-3db4-45e9-fdc8-802c4d770be6","type":"DOM","tag":"div","classes":["2b356c50-efa9-4aae-cd62-c610542169bf"],"children":["6551a318-897f-fad8-18f4-66a5c93d10c3"],"data":{"tag":"button","attributes":[{"name":"s-modal-trigger","value":"modal"}]}},{"_id":"6551a318-897f-fad8-18f4-66a5c93d10c3","type":"Block","tag":"div","classes":[],"children":["80cfbef7-08bb-6680-7ce0-503f979ea245"],"data":{"text":true,"tag":"div"}},{"_id":"80cfbef7-08bb-6680-7ce0-503f979ea245","text":true,"v":"Open Modal"},{"_id":"e887d389-8ab2-323f-90a1-7524c3f09bf1","type":"Block","tag":"div","classes":["1b6b5dfd-a6c6-8520-5fd9-0f35988bc745"],"children":["475f4259-1c80-465e-fbf4-46fcc524b51b","b6a836d7-b64b-6217-d51c-4a1da8e40b57"],"data":{"text":false,"tag":"div","devlink":{"runtimeProps":{},"slot":""},"displayName":"","attr":{"id":"modal"},"xattr":[{"name":"s-modal","value":"wrapper"}],"search":{"exclude":false},"visibility":{"conditions":[]}}},{"_id":"475f4259-1c80-465e-fbf4-46fcc524b51b","type":"Block","tag":"div","classes":["0cae4b59-4b34-411a-87ab-2eb23520d007"],"children":[],"data":{"text":false,"tag":"div","devlink":{"runtimeProps":{},"slot":""},"displayName":"","attr":{"id":""},"xattr":[{"name":"s-modal","value":"overlay"}],"search":{"exclude":false},"visibility":{"conditions":[]}}},{"_id":"b6a836d7-b64b-6217-d51c-4a1da8e40b57","type":"Block","tag":"div","classes":["6f97e77d-2de1-2f7a-ccab-c166d98489fb"],"children":["32340c5c-c37e-1d4d-acae-f87b084fd850","40517230-45ab-8e86-934c-675fce0cebf6"],"data":{"text":false,"tag":"div","devlink":{"runtimeProps":{},"slot":""},"displayName":"","attr":{"id":""},"xattr":[{"name":"s-modal","value":"root"}],"search":{"exclude":false},"visibility":{"conditions":[]}}},{"_id":"32340c5c-c37e-1d4d-acae-f87b084fd850","type":"Heading","tag":"h2","classes":["1316170d-1ba2-2ae7-c3f5-cceacf6dd17c"],"children":["6fff1b76-84cb-83c2-a06c-462500f03739"],"data":{"tag":"h2","devlink":{"runtimeProps":{},"slot":""},"displayName":"","attr":{"id":""},"xattr":[{"name":"s-modal","value":"title"}],"search":{"exclude":false},"visibility":{"conditions":[]}}},{"_id":"6fff1b76-84cb-83c2-a06c-462500f03739","text":true,"v":"Modal title"},{"_id":"40517230-45ab-8e86-934c-675fce0cebf6","type":"Block","tag":"div","classes":["c47c2797-eace-029a-eede-38e658fc2872"],"children":["b88b730c-77b2-7ede-8ef3-b18abe7527f5"],"data":{"text":false,"tag":"div","devlink":{"runtimeProps":{},"slot":""},"displayName":"","attr":{"id":""},"xattr":[],"search":{"exclude":false},"visibility":{"conditions":[]}}},{"_id":"b88b730c-77b2-7ede-8ef3-b18abe7527f5","type":"DOM","tag":"div","classes":["2b356c50-efa9-4aae-cd62-c610542169bf","273120d2-8b62-1598-0e94-829668f2fad5"],"children":["04370c3b-693a-4f48-9bf3-fa25564299d2"],"data":{"tag":"button","attributes":[{"name":"s-modal","value":"close"}]}},{"_id":"04370c3b-693a-4f48-9bf3-fa25564299d2","type":"Block","tag":"div","classes":[],"children":["26edc07a-c993-bd4a-1300-08211aa5dd6f"],"data":{"text":true,"tag":"div"}},{"_id":"26edc07a-c993-bd4a-1300-08211aa5dd6f","text":true,"v":"Close modal"}],"styles":[{"_id":"2b356c50-efa9-4aae-cd62-c610542169bf","fake":false,"type":"class","name":"button","namespace":"","comb":"","styleLess":"display: flex; padding-top: 0.75rem; padding-right: 1.5rem; padding-bottom: 0.75rem; padding-left: 1.5rem; justify-content: center; align-items: center; grid-column-gap: 0.5rem; border-top-left-radius: 7.5rem; border-top-right-radius: 7.5rem; border-bottom-left-radius: 7.5rem; border-bottom-right-radius: 7.5rem; background-color: #00ff84; box-shadow: inset 0 10px 10px 0 hsla(0, 0.00%, 100.00%, 0.42), 0 5px 14px 0 hsla(0, 0.00%, 0.00%, 0.50); transition-property: box-shadow, color, background-color; transition-duration: 200ms, 200ms, 200ms; transition-timing-function: ease, ease, ease; color: hsla(0, 0.00%, 11.33%, 1.00); text-align: center; text-decoration: none;","variants":{"main_hover":{"styleLess":"box-shadow: inset 0 11px 9px 0 hsla(0, 0.00%, 100.00%, 0.49), 0 2px 20px 0 hsla(131, 100.00%, 34.00%, 0.70), 0 5px 16px 0 hsla(0, 0.00%, 0.00%, 0.40);"}},"children":["273120d2-8b62-1598-0e94-829668f2fad5","f153d263-c133-61be-10b7-5cb14810c656","2740c8ff-0c72-8134-8eaf-405db05e42a2"],"createdBy":"64f4c4cdbe566b5a0114b6d3","origin":null,"selector":null},{"_id":"1b6b5dfd-a6c6-8520-5fd9-0f35988bc745","fake":false,"type":"class","name":"modal-wrapper","namespace":"","comb":"","styleLess":"position: fixed; left: 0%; top: 0%; right: 0%; bottom: 0%; z-index: 999; display: none; padding-right: 16px; padding-left: 16px; justify-content: center; align-items: center;","variants":{},"children":[],"createdBy":"5de3f22e747d41cf4377aef1","origin":null,"selector":null},{"_id":"0cae4b59-4b34-411a-87ab-2eb23520d007","fake":false,"type":"class","name":"modal-overlay","namespace":"","comb":"","styleLess":"position: absolute; left: 0%; top: 0%; right: 0%; bottom: 0%; z-index: -1; background-color: hsla(0, 0.00%, 11.33%, 1.00); opacity: 0.9;","variants":{},"children":[],"createdBy":"5de3f22e747d41cf4377aef1","origin":null,"selector":null},{"_id":"6f97e77d-2de1-2f7a-ccab-c166d98489fb","fake":false,"type":"class","name":"modal","namespace":"","comb":"","styleLess":"position: relative; z-index: 1; width: 100%; max-width: 44rem; padding-top: 2em; padding-right: 2em; padding-bottom: 2em; padding-left: 2em; border-top-style: solid; border-top-width: 1px; border-top-color: hsla(0, 0.00%, 58.67%, 1.00); border-right-style: solid; border-right-width: 1px; border-right-color: hsla(0, 0.00%, 58.67%, 1.00); border-bottom-style: solid; border-bottom-width: 1px; border-bottom-color: hsla(0, 0.00%, 58.67%, 1.00); border-left-style: solid; border-left-width: 1px; border-left-color: hsla(0, 0.00%, 58.67%, 1.00); border-top-left-radius: 32px; border-top-right-radius: 32px; border-bottom-left-radius: 32px; border-bottom-right-radius: 32px; background-color: hsla(0, 0.00%, 100.00%, 1.00);","variants":{},"children":[],"createdBy":"5de3f22e747d41cf4377aef1","origin":null,"selector":null},{"_id":"1316170d-1ba2-2ae7-c3f5-cceacf6dd17c","fake":false,"type":"class","name":"h4","namespace":"","comb":"","styleLess":"font-size: 2.5rem; line-height: 1.2;","variants":{"medium":{"styleLess":"font-size: 2.25rem;"},"tiny":{"styleLess":"font-size: 1.75rem;"}},"children":[],"createdBy":"64f4c4cdbe566b5a0114b6d3","origin":null,"selector":null},{"_id":"c47c2797-eace-029a-eede-38e658fc2872","fake":false,"type":"class","name":"cta-wrapper","namespace":"","comb":"","styleLess":"display: flex; margin-top: 2rem; flex-wrap: wrap; grid-column-gap: 1rem; grid-row-gap: 1rem;","variants":{},"children":["6f1c3c32-7399-c43a-3e4b-52fb32e7caad"],"createdBy":"64f4c4cdbe566b5a0114b6d3","origin":null,"selector":null},{"_id":"273120d2-8b62-1598-0e94-829668f2fad5","fake":false,"type":"class","name":"cc-outline","namespace":"","comb":"&","styleLess":"align-items: center; border-top-style: solid; border-top-width: 2px; border-top-color: hsla(0, 0.00%, 58.67%, 1.00); border-right-style: solid; border-right-width: 2px; border-right-color: hsla(0, 0.00%, 58.67%, 1.00); border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: hsla(0, 0.00%, 58.67%, 1.00); border-left-style: solid; border-left-width: 2px; border-left-color: hsla(0, 0.00%, 58.67%, 1.00); background-color: transparent; background-image: none; box-shadow: none; transition-property: border-color, box-shadow, color, background-color; transition-duration: 200ms, 200ms, 200ms, 200ms; transition-timing-function: ease, ease, ease, ease; color: hsla(0, 0.00%, 11.33%, 1.00);","variants":{"main_hover":{"styleLess":"border-top-color: #00ff84; border-right-color: #00ff84; border-bottom-color: #00ff84; border-left-color: #00ff84;"}},"children":[],"createdBy":"64f4c4cdbe566b5a0114b6d3","origin":null,"selector":null}],"assets":[],"ix1":[],"ix2":{"interactions":[],"events":[],"actionLists":[]}},"meta":{"droppedLinks":0,"dynBindRemovedCount":0,"dynListBindRemovedCount":0,"paginationRemovedCount":0,"universalBindingsRemovedCount":0,"unlinkedSymbolCount":0}}