<div class="locker" data-locker="css-cheat-sheet">
<!-- The content you want to lock goes in here -->
<div class="locker-content">
<h3>The Complete CSS Cheat Sheet (PDF)</h3>
<p>Every selector, property, and shorthand on two printable pages. Keep it next to your keyboard and stop googling flexbox.</p>
<a class="download-button" href="css-cheat-sheet.pdf" download>Download the PDF</a>
</div>
<!-- The overlay visitors see while the content is locked -->
<div class="locker-overlay">
<svg class="locker-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12,17C10.89,17 10,16.1 10,15C10,13.89 10.89,13 12,13A2,2 0 0,1 14,15A2,2 0 0,1 12,17M18,20V10H6V20H18M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10C4,8.89 4.89,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"/></svg>
<p class="locker-title">This content is locked</p>
<p class="locker-hint">Share this page on any network below to unlock the download instantly.</p>
<!-- Icons: Font Awesome Free 6 (fontawesome.com) - CC BY 4.0 -->
<div class="locker-share">
<a href="#" data-share="x" aria-label="Share on X">
<svg viewBox="0 0 512 512" aria-hidden="true"><path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"/></svg>
</a>
<a href="#" data-share="facebook" aria-label="Share on Facebook">
<svg viewBox="0 0 320 512" aria-hidden="true"><path d="M80 299.3V512H196V299.3h86.5l18-97.8H196V166.9c0-51.7 20.3-71.5 72.7-71.5c16.3 0 29.4 .4 37 1.2V7.9C291.4 4 256.4 0 236.2 0C129.3 0 80 50.5 80 159.4v42.1H14v97.8H80z"/></svg>
</a>
<a href="#" data-share="linkedin" aria-label="Share on LinkedIn">
<svg viewBox="0 0 448 512" aria-hidden="true"><path d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"/></svg>
</a>
<a href="#" data-share="pinterest" aria-label="Share on Pinterest">
<svg viewBox="0 0 384 512" aria-hidden="true"><path d="M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"/></svg>
</a>
<a href="#" data-share="reddit" aria-label="Share on Reddit">
<svg viewBox="0 0 512 512" aria-hidden="true"><path d="M373 138.6c-25.2 0-46.3-17.5-51.9-41l0 0c-30.6 4.3-54.2 30.7-54.2 62.4l0 .2c47.4 1.8 90.6 15.1 124.9 36.3c12.6-9.7 28.4-15.5 45.5-15.5c41.3 0 74.7 33.4 74.7 74.7c0 29.8-17.4 55.5-42.7 67.5c-2.4 86.8-97 156.6-213.2 156.6S45.5 410.1 43 323.4C17.6 311.5 0 285.7 0 255.7c0-41.3 33.4-74.7 74.7-74.7c17.2 0 33 5.8 45.7 15.6c34-21.1 76.8-34.4 123.7-36.4l0-.3c0-44.3 33.7-80.9 76.8-85.5C325.8 50.2 347.2 32 373 32c29.4 0 53.3 23.9 53.3 53.3s-23.9 53.3-53.3 53.3zM157.5 255.3c-20.9 0-38.9 20.8-40.2 47.9s17.1 38.1 38 38.1s36.6-9.8 37.8-36.9s-14.7-49.1-35.7-49.1zM395 303.1c-1.2-27.1-19.2-47.9-40.2-47.9s-36.9 22-35.7 49.1c1.2 27.1 16.9 36.9 37.8 36.9s39.3-11 38-38.1zm-60.1 70.8c1.5-3.6-1-7.7-4.9-8.1c-23-2.3-47.9-3.6-73.8-3.6s-50.8 1.3-73.8 3.6c-3.9 .4-6.4 4.5-4.9 8.1c12.9 30.8 43.3 52.4 78.7 52.4s65.8-21.6 78.7-52.4z"/></svg>
</a>
<a href="#" data-share="whatsapp" aria-label="Share on WhatsApp">
<svg viewBox="0 0 448 512" aria-hidden="true"><path d="M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"/></svg>
</a>
</div>
</div>
</div>/* Demo page styling */
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
background-color: #f1f5f9;
}
.locker-content h3 {
margin: 0 0 10px;
font-size: 22px;
color: #0f172a;
}
.locker-content p {
margin: 0 0 20px;
font-size: 15px;
line-height: 1.6;
color: #475569;
}
.download-button {
display: inline-block;
padding: 12px 22px;
font-weight: 700;
text-decoration: none;
color: #fff;
background-color: #3e7bd6;
border-radius: 8px;
}
.download-button:hover {
background-color: #3069c2;
}
/* The content locker component */
/* Every knob you might want to tweak lives in one place */
.locker {
--locker-radius: 12px;
--locker-blur: 8px;
--locker-speed: .4s;
--locker-accent: #3e7bd6;
--locker-overlay: linear-gradient(160deg, rgba(30, 41, 59, .92), rgba(15, 23, 42, .96));
--locker-button: 44px;
position: relative;
max-width: 520px;
border-radius: var(--locker-radius);
overflow: hidden;
box-shadow: 0 4px 24px rgba(15, 23, 42, .12);
}
/* The content being locked; the blur fades away smoothly on unlock */
.locker-content {
padding: 30px;
background-color: #fff;
transition: filter var(--locker-speed) ease;
}
/* Blur the content and block clicks and text selection while it is locked */
.locker:not(.unlocked) .locker-content {
filter: blur(var(--locker-blur));
pointer-events: none;
user-select: none;
}
/* The dark overlay that sits on top of the locked content */
.locker-overlay {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
padding: 20px;
text-align: center;
color: #fff;
background: var(--locker-overlay);
transition: opacity var(--locker-speed) ease, visibility var(--locker-speed);
}
/* Fade the overlay away once the locker is unlocked */
.locker.unlocked .locker-overlay {
opacity: 0;
visibility: hidden;
}
.locker-icon {
width: 34px;
height: 34px;
fill: #94a3b8;
}
.locker-title {
margin: 4px 0 0;
font-size: 20px;
font-weight: 700;
}
.locker-hint {
margin: 0 0 10px;
font-size: 14px;
line-height: 1.5;
color: #cbd5e1;
}
/* The row of round share buttons; each button reads its own --brand color */
.locker-share {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
.locker-share a {
display: flex;
align-items: center;
justify-content: center;
width: var(--locker-button);
height: var(--locker-button);
border-radius: 50%;
background-color: var(--brand);
transition: transform .15s ease;
}
.locker-share a:hover,
.locker-share a:focus-visible {
transform: scale(1.12);
}
.locker-share svg {
width: 18px;
height: 18px;
fill: #fff;
}
/* The official brand color for each network */
[data-share=x] { --brand: #000000; }
[data-share=facebook] { --brand: #0866ff; }
[data-share=linkedin] { --brand: #0a66c2; }
[data-share=pinterest] { --brand: #e60023; }
[data-share=reddit] { --brand: #ff4500; }
[data-share=whatsapp] { --brand: #25d366; }
/* The email form used by the email signup variant */
.locker-form {
display: flex;
gap: 8px;
width: 100%;
max-width: 340px;
}
.locker-form input {
flex: 1;
min-width: 0;
padding: 10px 14px;
font-size: 14px;
color: #fff;
background-color: #1e293b;
border: 1px solid #475569;
border-radius: 6px;
}
.locker-form input::placeholder {
color: #94a3b8;
}
.locker-form button {
padding: 10px 18px;
font-size: 14px;
font-weight: 700;
color: #fff;
background-color: var(--locker-accent);
border: 0;
border-radius: 6px;
cursor: pointer;
}
.locker-form button:hover {
filter: brightness(.9);
}
/* Keep things calm for visitors who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
.locker-content, .locker-overlay, .locker-share a {
transition: none;
}
}
// The share dialog URL for every supported network; {url} becomes the page's address
const networks = {
x: 'https://x.com/intent/post?url={url}',
facebook: 'https://www.facebook.com/sharer/sharer.php?u={url}',
linkedin: 'https://www.linkedin.com/sharing/share-offsite/?url={url}',
pinterest: 'https://pinterest.com/pin/create/button/?url={url}',
reddit: 'https://www.reddit.com/submit?url={url}',
whatsapp: 'https://wa.me/?text={url}'
};
// Read or save an unlock flag; storage can be blocked in private or embedded pages
const remember = (key, value) => {
try { return value ? localStorage.setItem(key, value) : localStorage.getItem(key); } catch (e) { return null; }
};
// Reveal the content and remember the unlock so it stays open on return visits
const unlock = locker => {
locker.classList.add('unlocked');
locker.querySelector('.locker-content').inert = false;
remember('locker_' + locker.dataset.locker, 'unlocked');
};
// Set up every locker on the page
document.querySelectorAll('.locker').forEach(locker => {
// Keep clicks and keyboard focus out of the content while it is locked
locker.querySelector('.locker-content').inert = true;
// Unlocked on a previous visit? Reveal it immediately and skip the rest
if (remember('locker_' + locker.dataset.locker)) return unlock(locker);
// Unlock by sharing: one click handler per share button
locker.querySelectorAll('[data-share]').forEach(button => button.addEventListener('click', event => {
event.preventDefault();
// Build the share link for the clicked network with this page's URL filled in
const url = networks[button.dataset.share].replace('{url}', encodeURIComponent(location.href));
// Open the network's share dialog in a small centered popup window
const popup = window.open(url, 'share', 'popup,width=600,height=600,left=' + (screen.width - 600) / 2 + ',top=' + (screen.height - 600) / 2);
// Popup blocked? Fall back to a new tab and unlock after a short delay
if (!popup) { window.open(url, '_blank'); setTimeout(() => unlock(locker), 5000); return; }
// Watch the popup; once it closes, the share is done and we can unlock
const watcher = setInterval(() => {
if (popup.closed) { clearInterval(watcher); unlock(locker); }
}, 500);
}));
// Unlock by email: used by the email signup variant if the form exists
const form = locker.querySelector('.locker-form');
if (form) form.addEventListener('submit', event => {
event.preventDefault();
// Send the address to your newsletter system here, then reveal the content
unlock(locker);
});
});
Nothing to show yetType HTML, CSS or JavaScript and your page appears here.
Click any element to find its code Esc
Check this code before you run it
It came from a shared link. It runs with fewer permissions, so it cannot open pop-ups, submit forms or start downloads.
0.00s / 0.00s
Nothing has animated yet. Hover, click or type in the preview and each CSS animation, transition or
element.animate() call shows up here as it plays.