Skip to content

Instantly share code, notes, and snippets.

@bsdfirst
Created October 30, 2025 02:59
Show Gist options
  • Select an option

  • Save bsdfirst/c7ae5d008d51394accbfebba86e66e73 to your computer and use it in GitHub Desktop.

Select an option

Save bsdfirst/c7ae5d008d51394accbfebba86e66e73 to your computer and use it in GitHub Desktop.
Add fade-in support for embedded Tally forms in modal mode
<!--
This is a giant hack to cause an embedded Tally modal form to fade in rather
than just snap into being. This is a workaround, and while it currently
functions correctly, it may not work in all circumstances, or in the future
for that matter. I did look at trying to capture close to fade out as well,
but it got too complicated too quickly and would have been exceedingly
fragile.
I have raised a feature request to add fade in/out support to Tally, so
hopefully this functionality will be added to Tally itself in the future.
The below is just an example pulled from my own use case. You can use this
as a guide to your own use case.
#notadev so YMMV
-->
<script async defer src="https://tally.so/widgets/embed.js"></script>
<script>
function openForm(formID, myHiddenField_value) {
// Wait for Tally to be loaded
if (typeof Tally === 'undefined') {
console.warn('Tally not loaded yet');
return;
}
// Watch for when .tally-overlay is added to DOM (fade immediately)
const observer = new MutationObserver((mutations, obs) => {
const overlay = document.querySelector('.tally-overlay');
if (overlay) {
// Stop observing - we found it
obs.disconnect();
// Small delay to ensure browser registers initial state
setTimeout(() => {
// Fade in the overlay
overlay.classList.add('fade-in');
}, 20);
}
});
// Start observing
observer.observe(document.body, {
childList: true,
subtree: true
});
// Open the popup with custom options
Tally.openPopup(formID, {
layout: 'modal',
width: 500,
hideTitle: true,
alignLeft: false,
autoClose: 5000,
hiddenFields: {
myHiddenField: myHiddenField_value,
},
onOpen: () => {
// Wait for popup to be fully loaded and sized
setTimeout(() => {
const popup = document.querySelector('.tally-popup');
if (popup) {
popup.classList.add('fade-in');
}
}, 100);
},
});
}
</script>
<style>
/* Tally overlay transitions */
.tally-overlay {
opacity: 0 !important;
transition: opacity 0.3s ease-in-out !important;
background-color: rgba(0, 0, 0, 0.8) !important;
}
.tally-overlay.fade-in {
opacity: 1 !important;
}
/* Tally popup transitions */
.tally-popup {
opacity: 0 !important;
transform: scale(0.92) !important;
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out !important;
}
.tally-popup.fade-in {
opacity: 1 !important;
transform: scale(1) !important;
}
</style>
<button onclick="openForm('myformID', 'myHiddenField_value_A')">Click here to show form</button>
<button onclick="openForm('myformID', 'myHiddenField_value_B')">Click here to show form</button>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment