Frosted glass
A translucent pane over slowly moving color.
An iOS style world clock widget: four analog dials, two for day and two for night, on a frosted card over drifting color. Second hands sweep in sync and the other hands turn at true speed.
Also known as: glassmorphism clock css, css analog clock widget, ios world clock widget.
<div class="gls-glass-clock-widget">
<span class="gls-glass-clock-widget-orb gls-glass-clock-widget-orb-a" aria-hidden="true"></span>
<span class="gls-glass-clock-widget-orb gls-glass-clock-widget-orb-b" aria-hidden="true"></span>
<ul class="gls-glass-clock-widget-card" aria-label="World clock">
<li class="gls-glass-clock-widget-city gls-glass-clock-widget-night">
<span class="gls-glass-clock-widget-dial" aria-hidden="true"><i class="gls-glass-clock-widget-hour"></i><i class="gls-glass-clock-widget-min"></i><i class="gls-glass-clock-widget-sec"></i></span>
<b>CUP</b>
<small>-8h</small>
</li>
<li class="gls-glass-clock-widget-city gls-glass-clock-widget-night">
<span class="gls-glass-clock-widget-dial" aria-hidden="true"><i class="gls-glass-clock-widget-hour"></i><i class="gls-glass-clock-widget-min"></i><i class="gls-glass-clock-widget-sec"></i></span>
<b>NYC</b>
<small>-5h</small>
</li>
<li class="gls-glass-clock-widget-city">
<span class="gls-glass-clock-widget-dial" aria-hidden="true"><i class="gls-glass-clock-widget-hour"></i><i class="gls-glass-clock-widget-min"></i><i class="gls-glass-clock-widget-sec"></i></span>
<b>LON</b>
<small>Local</small>
</li>
<li class="gls-glass-clock-widget-city">
<span class="gls-glass-clock-widget-dial" aria-hidden="true"><i class="gls-glass-clock-widget-hour"></i><i class="gls-glass-clock-widget-min"></i><i class="gls-glass-clock-widget-sec"></i></span>
<b>PAR</b>
<small>+1h</small>
</li>
</ul>
</div>.gls-glass-clock-widget {
--c: var(--gls-color, #3b82f6);
font-size: var(--gls-size, 16px);
position: relative;
display: grid;
place-items: center;
width: 22em;
height: 12em;
border-radius: 1.25em;
overflow: hidden;
isolation: isolate;
background: linear-gradient(150deg, color-mix(in srgb, var(--c) 50%, #0f172a), color-mix(in srgb, var(--c) 30%, #312e81));
color: #fff;
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
line-height: 1.3;
}
.gls-glass-clock-widget-orb {
position: absolute;
z-index: -1;
border-radius: 50%;
}
.gls-glass-clock-widget-orb-a {
left: 1.6em;
top: 0.3em;
width: 7em;
height: 7em;
background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #fff), var(--c));
animation: gls-glass-clock-widget-drift-a 9s ease-in-out infinite alternate;
}
.gls-glass-clock-widget-orb-b {
right: 1.8em;
bottom: 0.2em;
width: 6em;
height: 6em;
background: linear-gradient(135deg, #fdba74, #ec4899);
animation: gls-glass-clock-widget-drift-b 10s ease-in-out infinite alternate;
}
.gls-glass-clock-widget-card {
--m: 9;
display: flex;
gap: 0.95em;
margin: 0;
padding: 0.85em 1.05em 0.7em;
border-radius: 1.3em;
list-style: none;
background: color-mix(in srgb, #fff 16%, transparent);
-webkit-backdrop-filter: blur(0.9em) saturate(1.5);
backdrop-filter: blur(0.9em) saturate(1.5);
border: 1px solid color-mix(in srgb, #fff 45%, transparent);
box-shadow: 0 0.5em 1.5em -0.5em rgb(0 0 0 / 0.35), inset 0 1px 0 color-mix(in srgb, #fff 55%, transparent);
}
.gls-glass-clock-widget-city {
display: grid;
justify-items: center;
line-height: 1.25;
}
.gls-glass-clock-widget-city:nth-child(1) { --h: 2; }
.gls-glass-clock-widget-city:nth-child(2) { --h: 5; }
.gls-glass-clock-widget-city:nth-child(3) { --h: 10; }
.gls-glass-clock-widget-city:nth-child(4) { --h: 11; }
.gls-glass-clock-widget-city b { font-size: 0.6em; font-weight: 700; letter-spacing: 0.05em; }
.gls-glass-clock-widget-city small { font-size: 0.5em; font-weight: 600; opacity: 0.75; }
.gls-glass-clock-widget-dial {
position: relative;
width: 3.3em;
height: 3.3em;
margin-bottom: 0.4em;
border-radius: 50%;
background: rgb(255 255 255 / 0.9);
color: #111827;
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.6), 0 0.35em 0.8em -0.35em rgb(0 0 0 / 0.45);
transition: scale 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.gls-glass-clock-widget-night .gls-glass-clock-widget-dial {
background: rgb(15 23 42 / 0.6);
color: #fff;
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.25), inset 0 1px 0 rgb(255 255 255 / 0.3), 0 0.35em 0.8em -0.35em rgb(0 0 0 / 0.5);
}
.gls-glass-clock-widget-city:hover .gls-glass-clock-widget-dial { scale: 1.08; }
/* twelve hour ticks: a conic gradient masked to a ring */
.gls-glass-clock-widget-dial::before {
content: "";
position: absolute;
inset: 0.2em;
border-radius: 50%;
background: repeating-conic-gradient(from -2deg, currentColor 0 4deg, transparent 4deg 30deg);
-webkit-mask: radial-gradient(closest-side, transparent 78%, #000 80%);
mask: radial-gradient(closest-side, transparent 78%, #000 80%);
opacity: 0.55;
}
/* center cap, painted over the hands */
.gls-glass-clock-widget-dial::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
width: 0.26em;
height: 0.26em;
margin: -0.13em 0 0 -0.13em;
border-radius: 50%;
background: #f97316;
}
.gls-glass-clock-widget-hour,
.gls-glass-clock-widget-min,
.gls-glass-clock-widget-sec {
position: absolute;
left: 50%;
bottom: 50%;
border-radius: 99em;
background: currentColor;
transform-origin: 50% 100%;
animation: gls-glass-clock-widget-turn linear infinite;
}
.gls-glass-clock-widget-hour {
width: 0.17em;
height: 0.8em;
margin-left: -0.085em;
transform: rotate(calc(var(--h) * 30deg + var(--m) * 0.5deg));
animation-duration: 43200s;
}
.gls-glass-clock-widget-min {
width: 0.12em;
height: 1.2em;
margin-left: -0.06em;
transform: rotate(calc(var(--m) * 6deg));
animation-duration: 3600s;
}
.gls-glass-clock-widget-sec {
width: 0.07em;
height: 1.55em;
margin: 0 0 -0.3em -0.035em;
background: #f97316;
transform-origin: 50% calc(100% - 0.3em);
transform: rotate(240deg);
animation-duration: 60s;
}
@keyframes gls-glass-clock-widget-turn {
to { rotate: 1turn; }
}
@keyframes gls-glass-clock-widget-drift-a {
to { transform: translate(4em, 1.5em) scale(1.1); }
}
@keyframes gls-glass-clock-widget-drift-b {
to { transform: translate(-4.5em, -1em) scale(0.9); }
}
@media (prefers-reduced-motion: reduce) {
.gls-glass-clock-widget, .gls-glass-clock-widget *, .gls-glass-clock-widget::before, .gls-glass-clock-widget::after, .gls-glass-clock-widget *::before, .gls-glass-clock-widget *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--gls-color on the element or a parent.
Currently previewing #3b82f6.--gls-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.