27 CSS Calendar Designs 22 / 27
Micro-Interactions & Liquid Bubble Date Hover
A plain-looking grid whose magic is the hover.
The code
<div class="cal22">
<div class="cal22__card">
<div class="cal22__head">
<div>
<div class="cal22__title">June <span>2026</span></div>
<div class="cal22__hint">// hover the dates — liquid goo</div>
</div>
<div class="cal22__nav">
<div class="cal22__nav-btn">‹</div>
<div class="cal22__nav-btn">›</div>
</div>
</div>
<div class="cal22__dow">
<div class="cal22__dw">S</div><div class="cal22__dw">M</div><div class="cal22__dw">T</div>
<div class="cal22__dw">W</div><div class="cal22__dw">T</div><div class="cal22__dw">F</div><div class="cal22__dw">S</div>
</div>
<div class="cal22__gridwrap">
<div class="cal22__goo" id="cal22Goo"></div>
<div class="cal22__grid" id="cal22Grid">
<div class="cal22__cell other">25</div><div class="cal22__cell other">26</div><div class="cal22__cell other">27</div>
<div class="cal22__cell other">28</div><div class="cal22__cell other">29</div><div class="cal22__cell other">30</div><div class="cal22__cell other">31</div>
<div class="cal22__cell">1</div>
<div class="cal22__cell">2<span class="ev"></span></div>
<div class="cal22__cell">3</div>
<div class="cal22__cell">4<span class="ev"></span></div>
<div class="cal22__cell">5</div>
<div class="cal22__cell">6</div>
<div class="cal22__cell">7<span class="ev"></span></div>
<div class="cal22__cell today">8</div>
<div class="cal22__cell">9<span class="ev"></span></div>
<div class="cal22__cell">10</div>
<div class="cal22__cell">11<span class="ev"></span></div>
<div class="cal22__cell">12</div>
<div class="cal22__cell">13<span class="ev"></span></div>
<div class="cal22__cell">14</div>
<div class="cal22__cell">15</div>
<div class="cal22__cell">16</div>
<div class="cal22__cell">17<span class="ev"></span></div>
<div class="cal22__cell">18</div>
<div class="cal22__cell">19</div>
<div class="cal22__cell">20<span class="ev"></span></div>
<div class="cal22__cell">21</div>
<div class="cal22__cell">22</div>
<div class="cal22__cell">23</div>
<div class="cal22__cell">24<span class="ev"></span></div>
<div class="cal22__cell">25</div>
<div class="cal22__cell">26</div>
<div class="cal22__cell">27<span class="ev"></span></div>
<div class="cal22__cell">28</div>
<div class="cal22__cell">29</div>
<div class="cal22__cell">30</div>
<div class="cal22__cell other">1</div><div class="cal22__cell other">2</div><div class="cal22__cell other">3</div>
<div class="cal22__cell other">4</div><div class="cal22__cell other">5</div>
</div>
</div>
<div class="cal22__foot">
<div class="cal22__foot-blob"></div>
<div class="cal22__foot-body">
<div class="cal22__foot-title">Sunday, June 8</div>
<div class="cal22__foot-sub">3 events · sprint, launch, review</div>
</div>
</div>
</div>
</div> <div class="cal22">
<div class="cal22__card">
<div class="cal22__head">
<div>
<div class="cal22__title">June <span>2026</span></div>
<div class="cal22__hint">// hover the dates — liquid goo</div>
</div>
<div class="cal22__nav">
<div class="cal22__nav-btn">‹</div>
<div class="cal22__nav-btn">›</div>
</div>
</div>
<div class="cal22__dow">
<div class="cal22__dw">S</div><div class="cal22__dw">M</div><div class="cal22__dw">T</div>
<div class="cal22__dw">W</div><div class="cal22__dw">T</div><div class="cal22__dw">F</div><div class="cal22__dw">S</div>
</div>
<div class="cal22__gridwrap">
<div class="cal22__goo" id="cal22Goo"></div>
<div class="cal22__grid" id="cal22Grid">
<div class="cal22__cell other">25</div><div class="cal22__cell other">26</div><div class="cal22__cell other">27</div>
<div class="cal22__cell other">28</div><div class="cal22__cell other">29</div><div class="cal22__cell other">30</div><div class="cal22__cell other">31</div>
<div class="cal22__cell">1</div>
<div class="cal22__cell">2<span class="ev"></span></div>
<div class="cal22__cell">3</div>
<div class="cal22__cell">4<span class="ev"></span></div>
<div class="cal22__cell">5</div>
<div class="cal22__cell">6</div>
<div class="cal22__cell">7<span class="ev"></span></div>
<div class="cal22__cell today">8</div>
<div class="cal22__cell">9<span class="ev"></span></div>
<div class="cal22__cell">10</div>
<div class="cal22__cell">11<span class="ev"></span></div>
<div class="cal22__cell">12</div>
<div class="cal22__cell">13<span class="ev"></span></div>
<div class="cal22__cell">14</div>
<div class="cal22__cell">15</div>
<div class="cal22__cell">16</div>
<div class="cal22__cell">17<span class="ev"></span></div>
<div class="cal22__cell">18</div>
<div class="cal22__cell">19</div>
<div class="cal22__cell">20<span class="ev"></span></div>
<div class="cal22__cell">21</div>
<div class="cal22__cell">22</div>
<div class="cal22__cell">23</div>
<div class="cal22__cell">24<span class="ev"></span></div>
<div class="cal22__cell">25</div>
<div class="cal22__cell">26</div>
<div class="cal22__cell">27<span class="ev"></span></div>
<div class="cal22__cell">28</div>
<div class="cal22__cell">29</div>
<div class="cal22__cell">30</div>
<div class="cal22__cell other">1</div><div class="cal22__cell other">2</div><div class="cal22__cell other">3</div>
<div class="cal22__cell other">4</div><div class="cal22__cell other">5</div>
</div>
</div>
<div class="cal22__foot">
<div class="cal22__foot-blob"></div>
<div class="cal22__foot-body">
<div class="cal22__foot-title">Sunday, June 8</div>
<div class="cal22__foot-sub">3 events · sprint, launch, review</div>
</div>
</div>
</div>
</div>.cal22, .cal22 *, .cal22 *::before, .cal22 *::after {
box-sizing: border-box; margin: 0; padding: 0;
}
.cal22 ::selection { background: #ff5470; color: #fff; }
.cal22 {
--bg: #0f0e17;
--surface:#16151f;
--text: #fffffe;
--text2: #a7a9be;
--text3: #5a5b70;
--blob: #ff5470;
--blob2: #ff8906;
--accent: #e53170;
--soft: #2e2f3e;
font-family: 'Bricolage Grotesque', sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 40px 20px;
color: var(--text);
}
@keyframes cal22-in {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes cal22-wobble {
0%, 100% { border-radius: 42% 58% 56% 44% / 48% 50% 50% 52%; }
50% { border-radius: 56% 44% 48% 52% / 56% 44% 56% 44%; }
}
.cal22__card {
max-width: 460px;
width: 100%;
background: var(--surface);
border-radius: 28px;
padding: 32px;
box-shadow: 0 30px 70px rgba(0,0,0,0.5);
animation: cal22-in 0.5s ease both;
position: relative;
}
/* ── Header ── */
.cal22__head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 28px;
}
.cal22__title {
font-size: 32px;
font-weight: 800;
letter-spacing: -0.02em;
}
.cal22__title span {
background: linear-gradient(135deg, var(--blob), var(--blob2));
-webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.cal22__hint {
font-family: 'DM Mono', monospace;
font-size: 11px;
color: var(--text3);
margin-top: 3px;
}
.cal22__nav { display: flex; gap: 8px; }
.cal22__nav-btn {
width: 40px; height: 40px;
border-radius: 50%;
background: var(--soft);
border: none;
color: var(--text2);
font-size: 16px;
cursor: pointer;
transition: all 0.2s;
display: flex; align-items: center; justify-content: center;
user-select: none;
}
.cal22__nav-btn:hover { background: var(--blob); color: #fff; }
/* ── DOW ── */
.cal22__dow {
display: grid;
grid-template-columns: repeat(7, 1fr);
margin-bottom: 8px;
}
.cal22__dw {
text-align: center;
font-family: 'DM Mono', monospace;
font-size: 11px;
font-weight: 500;
color: var(--text3);
padding: 4px 0;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GOOEY LIQUID LAYER — the core trick.
A blurred + high-contrast filter on the
blob container fuses overlapping circles
into a single liquid mass (metaball effect).
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.cal22__gridwrap {
position: relative;
}
/* Goo layer sits behind the numbers */
.cal22__goo {
position: absolute;
inset: 0;
filter: blur(8px) contrast(22);
pointer-events: none;
z-index: 1;
mix-blend-mode: screen;
}
/* Each blob is a small circle that grows + wobbles on its cell's hover */
.cal22__blob {
position: absolute;
width: 44px; height: 44px;
border-radius: 50%;
background: var(--blob);
transform: translate(-50%, -50%) scale(0);
transition: transform 0.35s cubic-bezier(0.34,1.56,0.64,1);
will-change: transform;
}
.cal22__grid {
position: relative;
z-index: 2;
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 2px;
}
.cal22__cell {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
font-weight: 600;
color: var(--text);
cursor: pointer;
position: relative;
border-radius: 50%;
transition: color 0.2s;
}
.cal22__cell:hover { color: #fff; }
.cal22__cell.other { color: var(--text3); opacity: 0.4; pointer-events: none; }
/* Today — persistent gradient blob underneath via box-shadow ring */
.cal22__cell.today {
color: #fff;
font-weight: 800;
}
.cal22__cell.today::after {
content: '';
position: absolute;
inset: 6px;
border-radius: 50%;
background: linear-gradient(135deg, var(--blob), var(--blob2));
z-index: -1;
animation: cal22-wobble 4s ease-in-out infinite;
}
.cal22__cell.selected { color: #fff; font-weight: 800; }
.cal22__cell.selected::before {
content: '';
position: absolute;
inset: 5px;
border-radius: 50%;
border: 2px solid var(--blob2);
z-index: -1;
}
/* event dot */
.cal22__cell .ev {
position: absolute;
bottom: 8px;
width: 4px; height: 4px;
border-radius: 50%;
background: var(--blob2);
}
.cal22__cell.today .ev, .cal22__cell:hover .ev { background: #fff; }
/* ── Footer readout ── */
.cal22__foot {
margin-top: 26px;
padding: 16px 18px;
border-radius: 18px;
background: var(--bg);
display: flex;
align-items: center;
gap: 14px;
}
.cal22__foot-blob {
width: 44px; height: 44px;
border-radius: 42% 58% 56% 44% / 48% 50% 50% 52%;
background: linear-gradient(135deg, var(--blob), var(--blob2));
flex-shrink: 0;
animation: cal22-wobble 4s ease-in-out infinite;
}
.cal22__foot-body {}
.cal22__foot-title { font-size: 14px; font-weight: 600; }
.cal22__foot-sub { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text3); margin-top: 2px; }
@media (prefers-reduced-motion: reduce) {
.cal22 * { animation: none !important; }
} .cal22, .cal22 *, .cal22 *::before, .cal22 *::after {
box-sizing: border-box; margin: 0; padding: 0;
}
.cal22 ::selection { background: #ff5470; color: #fff; }
.cal22 {
--bg: #0f0e17;
--surface:#16151f;
--text: #fffffe;
--text2: #a7a9be;
--text3: #5a5b70;
--blob: #ff5470;
--blob2: #ff8906;
--accent: #e53170;
--soft: #2e2f3e;
font-family: 'Bricolage Grotesque', sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 40px 20px;
color: var(--text);
}
@keyframes cal22-in {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes cal22-wobble {
0%, 100% { border-radius: 42% 58% 56% 44% / 48% 50% 50% 52%; }
50% { border-radius: 56% 44% 48% 52% / 56% 44% 56% 44%; }
}
.cal22__card {
max-width: 460px;
width: 100%;
background: var(--surface);
border-radius: 28px;
padding: 32px;
box-shadow: 0 30px 70px rgba(0,0,0,0.5);
animation: cal22-in 0.5s ease both;
position: relative;
}
/* ── Header ── */
.cal22__head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 28px;
}
.cal22__title {
font-size: 32px;
font-weight: 800;
letter-spacing: -0.02em;
}
.cal22__title span {
background: linear-gradient(135deg, var(--blob), var(--blob2));
-webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.cal22__hint {
font-family: 'DM Mono', monospace;
font-size: 11px;
color: var(--text3);
margin-top: 3px;
}
.cal22__nav { display: flex; gap: 8px; }
.cal22__nav-btn {
width: 40px; height: 40px;
border-radius: 50%;
background: var(--soft);
border: none;
color: var(--text2);
font-size: 16px;
cursor: pointer;
transition: all 0.2s;
display: flex; align-items: center; justify-content: center;
user-select: none;
}
.cal22__nav-btn:hover { background: var(--blob); color: #fff; }
/* ── DOW ── */
.cal22__dow {
display: grid;
grid-template-columns: repeat(7, 1fr);
margin-bottom: 8px;
}
.cal22__dw {
text-align: center;
font-family: 'DM Mono', monospace;
font-size: 11px;
font-weight: 500;
color: var(--text3);
padding: 4px 0;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GOOEY LIQUID LAYER — the core trick.
A blurred + high-contrast filter on the
blob container fuses overlapping circles
into a single liquid mass (metaball effect).
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.cal22__gridwrap {
position: relative;
}
/* Goo layer sits behind the numbers */
.cal22__goo {
position: absolute;
inset: 0;
filter: blur(8px) contrast(22);
pointer-events: none;
z-index: 1;
mix-blend-mode: screen;
}
/* Each blob is a small circle that grows + wobbles on its cell's hover */
.cal22__blob {
position: absolute;
width: 44px; height: 44px;
border-radius: 50%;
background: var(--blob);
transform: translate(-50%, -50%) scale(0);
transition: transform 0.35s cubic-bezier(0.34,1.56,0.64,1);
will-change: transform;
}
.cal22__grid {
position: relative;
z-index: 2;
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 2px;
}
.cal22__cell {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
font-weight: 600;
color: var(--text);
cursor: pointer;
position: relative;
border-radius: 50%;
transition: color 0.2s;
}
.cal22__cell:hover { color: #fff; }
.cal22__cell.other { color: var(--text3); opacity: 0.4; pointer-events: none; }
/* Today — persistent gradient blob underneath via box-shadow ring */
.cal22__cell.today {
color: #fff;
font-weight: 800;
}
.cal22__cell.today::after {
content: '';
position: absolute;
inset: 6px;
border-radius: 50%;
background: linear-gradient(135deg, var(--blob), var(--blob2));
z-index: -1;
animation: cal22-wobble 4s ease-in-out infinite;
}
.cal22__cell.selected { color: #fff; font-weight: 800; }
.cal22__cell.selected::before {
content: '';
position: absolute;
inset: 5px;
border-radius: 50%;
border: 2px solid var(--blob2);
z-index: -1;
}
/* event dot */
.cal22__cell .ev {
position: absolute;
bottom: 8px;
width: 4px; height: 4px;
border-radius: 50%;
background: var(--blob2);
}
.cal22__cell.today .ev, .cal22__cell:hover .ev { background: #fff; }
/* ── Footer readout ── */
.cal22__foot {
margin-top: 26px;
padding: 16px 18px;
border-radius: 18px;
background: var(--bg);
display: flex;
align-items: center;
gap: 14px;
}
.cal22__foot-blob {
width: 44px; height: 44px;
border-radius: 42% 58% 56% 44% / 48% 50% 50% 52%;
background: linear-gradient(135deg, var(--blob), var(--blob2));
flex-shrink: 0;
animation: cal22-wobble 4s ease-in-out infinite;
}
.cal22__foot-body {}
.cal22__foot-title { font-size: 14px; font-weight: 600; }
.cal22__foot-sub { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text3); margin-top: 2px; }
@media (prefers-reduced-motion: reduce) {
.cal22 * { animation: none !important; }
}(() => {
const grid = document.getElementById('cal22Grid');
const goo = document.getElementById('cal22Goo');
const cells = grid.querySelectorAll('.cal22__cell:not(.other)');
// create one blob per real cell, track to its position
cells.forEach(cell => {
const blob = document.createElement('div');
blob.className = 'cal22__blob';
goo.appendChild(blob);
function place() {
const gr = grid.getBoundingClientRect();
const cr = cell.getBoundingClientRect();
blob.style.left = (cr.left - gr.left + cr.width/2) + 'px';
blob.style.top = (cr.top - gr.top + cr.height/2) + 'px';
}
cell.addEventListener('mouseenter', () => { place(); blob.style.transform = 'translate(-50%,-50%) scale(1.15)'; });
cell.addEventListener('mouseleave', () => { blob.style.transform = 'translate(-50%,-50%) scale(0)'; });
cell.addEventListener('click', function() {
cells.forEach(c => c.classList.remove('selected'));
this.classList.add('selected');
});
});
})(); (() => {
const grid = document.getElementById('cal22Grid');
const goo = document.getElementById('cal22Goo');
const cells = grid.querySelectorAll('.cal22__cell:not(.other)');
// create one blob per real cell, track to its position
cells.forEach(cell => {
const blob = document.createElement('div');
blob.className = 'cal22__blob';
goo.appendChild(blob);
function place() {
const gr = grid.getBoundingClientRect();
const cr = cell.getBoundingClientRect();
blob.style.left = (cr.left - gr.left + cr.width/2) + 'px';
blob.style.top = (cr.top - gr.top + cr.height/2) + 'px';
}
cell.addEventListener('mouseenter', () => { place(); blob.style.transform = 'translate(-50%,-50%) scale(1.15)'; });
cell.addEventListener('mouseleave', () => { blob.style.transform = 'translate(-50%,-50%) scale(0)'; });
cell.addEventListener('click', function() {
cells.forEach(c => c.classList.remove('selected'));
this.classList.add('selected');
});
});
})();More from 27 CSS Calendar Designs
Interactive 3D Flip Card CalendarInfinite Isometric Dashboard Calendar ViewFluid Split-Screen Hero CalendarBento Grid Style Booking SystemVintage Skeuomorphic / Paper-Torn Tear-off DesignVertical Timeline Slipstream CalendarKinetic Typography Changing CalendarDiagonal Slanted Grid CalendarPure CSS Calendar (No JavaScript)Glassmorphism CSS Calendar WidgetBrutalist CSS Calendar DesignDark Mode CSS Calendar UI
View the full collection →