Weekend in Lisbon
Three days of tiles, tarts and trams.
A window with its blinds closed. On hover the slats tilt open one after another, top to bottom, and the sunrise behind them comes through. Each slat rotates on X around its own center.
Also known as: window blinds reveal, rotating slats hover, 3d blinds css.
<div class="hfx-venetian-blinds">
<div class="hfx-venetian-blinds-view">
<strong>Good morning</strong>
<span>6:42 am, clear skies</span>
</div>
<span class="hfx-venetian-blinds-slat" style="--i: 0"></span>
<span class="hfx-venetian-blinds-slat" style="--i: 1"></span>
<span class="hfx-venetian-blinds-slat" style="--i: 2"></span>
<span class="hfx-venetian-blinds-slat" style="--i: 3"></span>
<span class="hfx-venetian-blinds-slat" style="--i: 4"></span>
<span class="hfx-venetian-blinds-slat" style="--i: 5"></span>
<span class="hfx-venetian-blinds-slat" style="--i: 6"></span>
</div>.hfx-venetian-blinds {
--c: var(--hfx-color, #3b82f6);
font-size: var(--hfx-size, 16px);
position: relative;
width: 13em;
height: 8.4em;
overflow: hidden;
border: 0.35em solid color-mix(in srgb, var(--c) 55%, #1f2937);
border-radius: 0.5em;
perspective: 30em;
font-family: system-ui, sans-serif;
}
.hfx-venetian-blinds::after {
content: "";
position: absolute;
top: 0;
right: 1em;
width: 1px;
height: 62%;
background: color-mix(in srgb, var(--c) 50%, #000);
box-shadow: 0 0 0 0.12em color-mix(in srgb, var(--c) 20%, transparent);
}
.hfx-venetian-blinds-view {
position: absolute;
inset: 0;
display: grid;
place-content: center;
gap: 0.2em;
text-align: center;
color: #fff;
background:
radial-gradient(circle at 50% 115%, #fffbeb 0 22%, #fcd34d 30%, transparent 62%),
linear-gradient(color-mix(in srgb, var(--c) 70%, #1e1b4b), color-mix(in srgb, var(--c) 35%, #fb923c));
}
.hfx-venetian-blinds-view strong {
font-size: 1.3em;
text-shadow: 0 0.05em 0.3em color-mix(in srgb, #000 25%, transparent);
}
.hfx-venetian-blinds-view span {
font-size: 0.75em;
opacity: 0.85;
}
.hfx-venetian-blinds-slat {
position: absolute;
left: 0;
right: 0;
top: calc(var(--i) * 100% / 7);
height: calc(100% / 7 + 1px);
background: linear-gradient(color-mix(in srgb, var(--c) 8%, #fff), color-mix(in srgb, var(--c) 30%, #fff));
box-shadow: inset 0 -1px color-mix(in srgb, var(--c) 45%, #fff);
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: calc(var(--i) * 0.04s);
}
.hfx-venetian-blinds:hover .hfx-venetian-blinds-slat {
transform: rotateX(-87deg);
}
@media (prefers-reduced-motion: reduce) {
.hfx-venetian-blinds, .hfx-venetian-blinds *, .hfx-venetian-blinds::before, .hfx-venetian-blinds::after, .hfx-venetian-blinds *::before, .hfx-venetian-blinds *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hfx-color on the element or a parent.
Currently previewing #3b82f6.--hfx-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.