Skip to content

Popup & drawer

<button id="contact-btn">Get in touch</button>
<script src="https://forms.justinjongstra.nl/formbuilder/asset/embed.js"
data-fb-form="YOUR-FORM-ID"
data-fb-mode="popup"
data-fb-trigger="click"
data-fb-trigger-selector="#contact-btn" async></script>

Same renderer, same config, one attribute different. It slides in from the side instead of opening in the middle:

<button id="contact-btn">Get in touch</button>
<script src="https://forms.justinjongstra.nl/formbuilder/asset/embed.js"
data-fb-form="YOUR-FORM-ID"
data-fb-mode="drawer"
data-fb-position="right"
data-fb-trigger="click"
data-fb-trigger-selector="#contact-btn" async></script>

Which to use is a layout decision rather than a functional one: a drawer leaves more of the page visible, which suits a form that supports what somebody is already reading. A popup takes the focus, which suits one that is the point of the visit.

Config sits on the script tag rather than a container because these modes have no container: there is nothing on the page to hang it off until the overlay opens.

Attribute Values
data-fb-mode popup, drawer, button
data-fb-trigger click, load, delay, scroll, exit
data-fb-delay milliseconds, for delay
data-fb-scroll percent of the page, for scroll
data-fb-once session, forever, never
data-fb-position right, left, for drawer
data-fb-animation slide, scale, rise, fade, none
data-fb-animation-duration any CSS duration, e.g. 400ms
data-fb-animation-easing any CSS easing, e.g. ease-out

The overlay’s chrome renders in its own shadow root on a body-level element, so your page’s CSS cannot break the modal, while the form itself stays in light DOM and inherits your fonts.

A drawer slides in from its edge and a popup scales up; both take 260ms. Set data-fb-animation to pick a different one, and the two timing attributes to change how it feels.

<script src="https://forms.justinjongstra.nl/formbuilder/asset/embed.js"
data-fb-form="YOUR-FORM-ID"
data-fb-mode="drawer"
data-fb-animation="slide"
data-fb-animation-duration="420ms"
data-fb-animation-easing="cubic-bezier(.16,1,.3,1)" async></script>

You can also do it in CSS, which is the better option when the motion should match the rest of your site rather than be configured per embed. The overlay’s outer element carries data-formbuilder-overlay, and custom properties set on it inherit through the shadow boundary:

[data-formbuilder-overlay] {
--fb-anim-duration: 420ms;
--fb-anim-easing: cubic-bezier(.16, 1, .3, 1);
--fb-backdrop: rgba(10, 20, 40, 0.6);
}
/* Only the drawer, only on wide screens. */
[data-formbuilder-overlay='drawer'] {
--fb-anim-distance: 60%;
}
Property Default What it does
--fb-anim-duration 260ms Enter and exit timing
--fb-anim-easing cubic-bezier(.22,.61,.36,1) Enter and exit curve
--fb-anim-distance 100% drawer, 20px rise How far the panel travels
--fb-anim-scale .94 Starting scale, for scale
--fb-backdrop rgba(15,15,20,.45) Backdrop colour
--fb-panel-bg #fff Panel background
--fb-radius / --fb-pad 14px / 28px Panel shape

An attribute wins over your CSS, so leave the attribute off when you want the stylesheet to be in charge.

The form’s definition is fetched while the page is idle, not when somebody clicks, so by the time the panel opens the form is already in it. On a cold click over a slow connection you get a loading placeholder instead, and if the form genuinely cannot be reached you get a message and a Try again button. Never an empty panel.