Terms Scroll Gate
A copy-paste cookie & consent component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.
Cookie & ConsentHTMLCSSany framework
Terms of Service
By continuing you agree to our data handling practices, including the cookie categories described in this policy and how usage data may be aggregated to improve the product over time.
Scroll to the bottom to continue
Copy into your project
HTML
<div class="nuda-ck2-scroll-gate" role="region" aria-label="Terms acceptance">
<p class="nuda-ck2-scroll-gate__title">Terms of Service</p>
<div class="nuda-ck2-scroll-gate__box">
<p class="nuda-ck2-scroll-gate__text">
By continuing you agree to our data handling practices, including the cookie
categories described in this policy and how usage data may be aggregated to
improve the product over time.
</p>
<div class="nuda-ck2-scroll-gate__fade" aria-hidden="true"></div>
</div>
<div class="nuda-ck2-scroll-gate__agree">
<input type="checkbox" id="ck2-scroll-gate-agree" class="nuda-ck2-scroll-gate__checkbox" disabled>
<label for="ck2-scroll-gate-agree" class="nuda-ck2-scroll-gate__label">
I have read and agree to the Terms of Service
</label>
</div>
<p class="nuda-ck2-scroll-gate__hint" aria-live="polite">Scroll to the bottom to continue</p>
<button type="button" class="nuda-ck2-scroll-gate__submit" disabled>Continue</button>
</div>CSS
.nuda-ck2-scroll-gate {
width: 290px;
box-sizing: border-box;
background: #141414;
border: 1px solid rgba(255,255,255,.1);
border-radius: 16px;
padding: 1rem 1.1rem;
box-shadow: 0 20px 50px rgba(0,0,0,.55);
animation: _nuda-ck2scrollgateIn .45s cubic-bezier(.16,1,.3,1) both;
}
.nuda-ck2-scroll-gate__title {
color: #fafafa;
font-size: .82rem;
font-weight: 700;
margin: 0 0 .55rem;
}
.nuda-ck2-scroll-gate__box {
position: relative;
max-height: 64px;
overflow: hidden;
border: 1px solid rgba(255,255,255,.08);
border-radius: 10px;
padding: .55rem .65rem;
background: rgba(255,255,255,.03);
}
.nuda-ck2-scroll-gate__text {
color: #777;
font-size: .68rem;
line-height: 1.5;
margin: 0;
}
.nuda-ck2-scroll-gate__fade {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 28px;
background: linear-gradient(to bottom,rgba(20,20,20,0),#141414 90%);
pointer-events: none;
}
.nuda-ck2-scroll-gate__agree {
display: flex;
align-items: flex-start;
gap: .5rem;
margin: .75rem 0 .3rem;
}
.nuda-ck2-scroll-gate__checkbox {
width: 18px;
height: 18px;
min-width: 18px;
margin-top: 1px;
accent-color: #e4ff54;
cursor: not-allowed;
}
.nuda-ck2-scroll-gate__checkbox:focus-visible {
outline: 2px solid #e4ff54;
outline-offset: 2px;
}
.nuda-ck2-scroll-gate__label {
color: #cfcfcf;
font-size: .7rem;
line-height: 1.4;
}
.nuda-ck2-scroll-gate__hint {
color: #555;
font-size: .63rem;
margin: 0 0 .7rem;
}
.nuda-ck2-scroll-gate__submit {
width: 100%;
min-height: 40px;
border-radius: 9px;
border: 1px solid rgba(255,255,255,.12);
background: rgba(255,255,255,.06);
color: #555;
font-size: .75rem;
font-weight: 700;
cursor: not-allowed;
}
@keyframes _nuda-ck2scrollgateIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: none;
}
}
@media (prefers-reduced-motion:reduce) {
.nuda-ck2-scroll-gate {
animation: none !important;
}
}
How to use Terms Scroll Gate
Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.
Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.