
Documentation
Webflow
Code
Setup: External Scripts
External Scripts in Webflow
Make sure to always put the External Scripts before the Javascript step of the resource.
In this video you learn where to put these in your Webflow project? Or how to include a paid GSAP Club plugin in your project?
HTML
Step 1: Copy structure to Webflow
Copy structure to Webflow
In the video below we described how you can copy + paste the structure of this resource to your Webflow project.
Copy to Webflow
Webflow structure is not required for this resource.
Step 1: Add HTML
HTML
<div class="copy-email-wrapper">
<p class="copy-email-eyebrow">Reach out to us:</p>
<button aria-label="Copy email to clipboard" data-copy-button="" data-copy-email="" class="copy-email-button">
<div class="copy-email-icon__wrap">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewbox="0 0 24 24" fill="none">
<path d="M16 2H8V5H16V2Z" stroke="currentColor" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M16 3H17.5L19 4.5V19.5L17.5 21H6.5L5 19.5V4.5L6.5 3H8" stroke="currentColor" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
<div class="copy-email-text__wrap">
<span data-copy-email-element="" class="copy-email-text__el">hello@osmo.supply</span>
<span class="copy-email-text__el">Click to copy email</span>
<span class="copy-email-text__el">Copied to clipboard!</span></div>
</button>
</div>
HTML structure is not required for this resource.
Step 2: Add CSS
CSS
.copy-email-wrapper {
grid-column-gap: 2em;
grid-row-gap: 2em;
flex-flow: column;
justify-content: center;
align-items: center;
display: flex;
}
.copy-email-eyebrow {
opacity: .5;
text-align: center;
margin-bottom: 0;
font-size: 1em;
line-height: 1;
}
.copy-email-button {
grid-column-gap: .75em;
grid-row-gap: .75em;
background-color: #fff;
border-radius: .5em;
justify-content: flex-start;
align-items: center;
padding: .75em 1em .75em .75em;
display: flex;
}
.copy-email-button:focus {
outline-offset: 0px;
border: 1px #000;
outline: 3px #131313;
}
.copy-email-button:focus-visible, .copy-email-button[data-wf-focus-visible] {
outline-offset: 4px;
border-style: none;
outline: 2px solid #fff;
}
.copy-email-text__wrap {
flex-flow: column;
justify-content: flex-start;
align-items: center;
height: 1.2em;
font-size: 2em;
line-height: 1.2;
display: flex;
overflow: hidden;
}
.copy-email-text__el {
white-space: nowrap;
font-size: 1em;
transition: transform .45s cubic-bezier(.65, 0, 0, 1);
}
.copy-email-icon__wrap {
color: #fff;
background-color: #22502e;
border-radius: .375em;
justify-content: center;
align-items: center;
width: 2.5em;
height: 2.5em;
padding: .5em;
transition: background-color .2s;
display: flex;
}
/* Hover styling */
@media (hover: hover) {
.copy-email-button:hover .copy-email-icon__wrap{
background: rgba(34, 80, 46, 0.9);
}
.copy-email-button:hover .copy-email-text__el{
transform: translate(0px, -100%);
}
}
/* Keyboard focus styling */
.copy-email-button:hover .copy-email-icon__wrap{
background: rgba(34, 80, 46, 0.9);
}
.copy-email-button:focus .copy-email-text__el {
transform: translate(0px, -100%);
}
/* 'Copied' state, when a user has clicked the button */
[data-copy-button="copied"] .copy-email-icon__wrap{ background: #0F8E2E !important; }
[data-copy-button="copied"] .copy-email-text__el{ transform: translate(0px, -200%) !important; }
@media screen and (max-width: 991px) {
.section-resource {
font-size: 1em;
}
}
@media screen and (max-width: 479px) {
.copy-email-text__wrap {
font-size: 1em;
}
}
Step 2: Add custom Javascript
Custom Javascript in Webflow
In this video, Ilja gives you some guidance about using JavaScript in Webflow:
Step 2: Add Javascript
Step 3: Add Javascript
Javascript
function initCopyEmail() {
const buttons = document.querySelectorAll('.copy-email-button');
if (!buttons.length) return;
const copyEmail = (button) => {
// Email to copy to clipboard is taking from the button itself, or if that's empty,
// from a text element inside the button
const email =
button.getAttribute('data-copy-email') ||
button.querySelector('[data-copy-email-element]').textContent.trim();
if (email) {
navigator.clipboard.writeText(email).then(() => {
button.setAttribute('data-copy-button', 'copied');
button.setAttribute('aria-label', 'Email copied to clipboard!');
});
}
};
const handleInteraction = (e) => {
if (
e.type === 'click' ||
(e.type === 'keydown' && (e.key === 'Enter' || e.key === ' '))
) {
e.preventDefault();
copyEmail(e.currentTarget);
}
};
buttons.forEach((button) => {
button.addEventListener('click', handleInteraction);
button.addEventListener('keydown', handleInteraction);
button.addEventListener('mouseleave', () => {
// Remove 'active' attribute to reset color and text transform
button.removeAttribute('data-copy-button');
// Remove focus on mouseleave to clear keyboard focus styling
button.blur();
button.setAttribute('aria-label', 'Copy email to clipboard');
});
button.addEventListener('blur', () => {
button.removeAttribute('data-copy-button');
button.setAttribute('aria-label', 'Copy email to clipboard');
});
});
}
document.addEventListener('DOMContentLoaded', () =>{
initCopyEmail();
});
Step 3: Add custom CSS
Step 2: Add custom CSS
Custom CSS in Webflow
Curious about where to put custom CSS in Webflow? Ilja explains it in the below video:
CSS
/* Hover styling */
@media (hover: hover) {
.copy-email-button:hover .copy-email-icon__wrap{
background: rgba(34, 80, 46, 0.9);
}
.copy-email-button:hover .copy-email-text__el{
transform: translate(0px, -100%);
}
}
/* Keyboard focus styling */
.copy-email-button:hover .copy-email-icon__wrap{
background: rgba(34, 80, 46, 0.9);
}
.copy-email-button:focus .copy-email-text__el {
transform: translate(0px, -100%);
}
/* 'Copied' state, when a user has clicked the button */
[data-copy-button="copied"] .copy-email-icon__wrap{ background: #0F8E2E !important; }
[data-copy-button="copied"] .copy-email-text__el{ transform: translate(0px, -200%) !important; }
Documentation
This JavaScript module provides an accessible way for users to copy an email address to their clipboard. The email is either defined as a data-copy-email
attribute on the button or extracted from an inner element marked with data-copy-email-element
.
- Event Handling: Listeners are added for both click and keyboard (Enter or Space) interactions to trigger the copy action.
- Clipboard Interaction: Uses the Clipboard API to copy the email to the user’s clipboard.
- State & Accessibility: Once copied, the button’s state is updated with a data-copy-button="copied" attribute, and its aria-label is set to notify screen readers (“Email copied to clipboard!”). When the mouse leaves the button or it loses focus, the copied state is reset and the default aria-label (“Copy email to clipboard”) is restored.
- Graceful Fallback: If no email is directly provided on the button, the script looks for an inner element containing the email text.