A stunning liquid glass sidebar with liquid distortion effects and interactive hover states
<head>
.<!-- Font Awesome Icons; Make sure to add it in the <head> tag -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- SVG Filter for Glass Distortion -->
<svg style="display: none">
<filter id="glass-distortion">
<feTurbulence type="turbulence" baseFrequency="0.008" numOctaves="2" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="77" />
</filter>
</svg>
<div class="glass-sidebar">
<div class="glass-filter"></div>
<div class="glass-overlay"></div>
<div class="glass-specular"></div>
<div class="glass-content">
<div class="sidebar-header">
<h3>Menu</h3>
</div>
<nav class="sidebar-nav">
<a href="#" class="nav-item active">
<i class="fas fa-home"></i>
<span>Home</span>
</a>
<a href="#" class="nav-item">
<i class="fas fa-user"></i>
<span>Profile</span>
</a>
<a href="#" class="nav-item">
<i class="fas fa-cog"></i>
<span>Settings</span>
</a>
<a href="#" class="nav-item">
<i class="fas fa-chart-bar"></i>
<span>Analytics</span>
</a>
<a href="#" class="nav-item">
<i class="fas fa-envelope"></i>
<span>Messages</span>
</a>
</nav>
</div>
</div>
/* Glass Sidebar Container */
.glass-sidebar {
--bg-color: rgba(255, 255, 255, 0.25);
--highlight: rgba(255, 255, 255, 0.75);
--text: #ffffff;
position: relative;
width: 280px;
height: 500px;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.2);
}
.glass-filter,
.glass-overlay,
.glass-specular {
position: absolute;
inset: 0;
border-radius: inherit;
}
.glass-filter {
z-index: 1;
backdrop-filter: blur(4px);
filter: url(#glass-distortion) saturate(120%) brightness(1.15);
}
.glass-overlay {
z-index: 2;
background: var(--bg-color);
}
.glass-specular {
z-index: 3;
box-shadow: inset 1px 1px 1px var(--highlight);
}
.glass-content {
position: relative;
z-index: 4;
color: var(--text);
height: 100%;
display: flex;
flex-direction: column;
}
.sidebar-header {
padding: 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.sidebar-header h3 {
margin: 0;
font-size: 24px;
font-weight: 600;
}
.sidebar-nav {
padding: 20px 0;
flex: 1;
}
.nav-item {
display: flex;
align-items: center;
padding: 12px 20px;
color: var(--text);
text-decoration: none;
transition: background-color 0.3s;
gap: 12px;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.nav-item:hover,
.nav-item.active {
background: rgba(255, 255, 255, 0.1);
}
.nav-item i {
font-size: 18px;
width: 24px;
text-align: center;
}
.nav-item span {
font-size: 16px;
opacity: 0.9;
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
.glass-sidebar {
--bg-color: rgba(0, 0, 0, 0.25);
--highlight: rgba(255, 255, 255, 0.15);
}
}
document.addEventListener('DOMContentLoaded', function() {
// Get all glass elements
const glassElements = document.querySelectorAll('.glass-sidebar');
// Add mousemove effect for each glass element
glassElements.forEach(element => {
element.addEventListener('mousemove', handleMouseMove);
element.addEventListener('mouseleave', handleMouseLeave);
});
// Handle mouse movement over glass elements
function handleMouseMove(e) {
const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// Update filter turbulence based on mouse position
const filter = this.querySelector('filter feDisplacementMap');
if (filter) {
const scaleX = (x / rect.width) * 100;
const scaleY = (y / rect.height) * 100;
filter.setAttribute('scale', Math.min(scaleX, scaleY));
}
// Add highlight effect
const specular = this.querySelector('.glass-specular');
if (specular) {
specular.style.background = `radial-gradient(
circle at ${x}px ${y}px,
rgba(255,255,255,0.15) 0%,
rgba(255,255,255,0.05) 30%,
rgba(255,255,255,0) 60%
)`;
}
}
// Reset effects when mouse leaves
function handleMouseLeave() {
const filter = this.querySelector('filter feDisplacementMap');
if (filter) {
filter.setAttribute('scale', '77');
}
const specular = this.querySelector('.glass-specular');
if (specular) {
specular.style.background = 'none';
}
}
// Add nav item click handler
const navItems = document.querySelectorAll('.nav-item');
navItems.forEach(item => {
item.addEventListener('click', function(e) {
e.preventDefault();
navItems.forEach(navItem => navItem.classList.remove('active'));
this.classList.add('active');
});
});
});