Sand Hourglass
A copy-paste watch faces & clocks component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.
Watch Faces & ClocksHTMLCSSany framework
Copy into your project
HTML
<div class="nuda-hg" role="img" aria-label="Hourglass timer">
<div class="nuda-hg__top">
<div class="nuda-hg__sandTop"></div>
</div>
<div class="nuda-hg__neck">
<span class="nuda-hg__stream"></span>
</div>
<div class="nuda-hg__bot">
<div class="nuda-hg__sandBot"></div>
<span class="nuda-hg__grain" style="animation-delay:0s"></span>
<span class="nuda-hg__grain" style="animation-delay:.4s; left:55%"></span>
<span class="nuda-hg__grain" style="animation-delay:.8s; left:45%"></span>
</div>
</div>CSS
/* Sand Hourglass
Top chamber drains while the bottom fills, with falling grains.
Two clip-paths form the triangular hourglass profile. */
.nuda-hg {
--sand: #ffb45e;
--glass: rgba(255, 255, 255, 0.06);
position: relative;
display: inline-block;
width: 80px;
padding: 6px;
}
.nuda-hg__top,
.nuda-hg__bot {
position: relative;
width: 80px;
height: 48px;
background: var(--glass);
border: 1px solid rgba(255, 255, 255, 0.08);
overflow: hidden;
}
.nuda-hg__top {
border-radius: 4px 4px 50% 50% / 4px 4px 30% 30%;
clip-path: polygon(0 0, 100% 0, 55% 100%, 45% 100%);
}
.nuda-hg__bot {
border-radius: 50% 50% 4px 4px / 30% 30% 4px 4px;
clip-path: polygon(45% 0, 55% 0, 100% 100%, 0 100%);
margin-top: -1px;
}
.nuda-hg__sandTop {
position: absolute;
inset: 0;
background: var(--sand);
animation: nuda-hg-drain 6s linear infinite;
}
.nuda-hg__sandBot {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 0;
background: var(--sand);
animation: nuda-hg-fill 6s linear infinite;
}
.nuda-hg__neck {
position: relative;
width: 8px;
height: 6px;
margin: -1px auto;
background: #0c0c10;
border-left: 1px solid rgba(255, 255, 255, 0.08);
border-right: 1px solid rgba(255, 255, 255, 0.08);
}
.nuda-hg__stream {
position: absolute;
left: 50%;
top: 0;
width: 1.5px;
height: 6px;
margin-left: -0.75px;
background: var(--sand);
}
.nuda-hg__grain {
position: absolute;
left: 50%;
top: 0;
width: 2px;
height: 2px;
background: var(--sand);
border-radius: 50%;
animation: nuda-hg-grain 1.4s linear infinite;
}
@keyframes nuda-hg-drain { to { height: 0; } }
@keyframes nuda-hg-fill { to { height: 100%; } }
@keyframes nuda-hg-grain {
0% { top: 0; opacity: 1; }
80% { opacity: 1; }
100% { top: 40px; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.nuda-hg__sandTop,
.nuda-hg__sandBot,
.nuda-hg__grain { animation: none; }
.nuda-hg__sandTop { height: 50%; }
.nuda-hg__sandBot { height: 50%; }
}How to use Sand Hourglass
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.