A stunning liquid glass form with seamless login/register transitions and interactive effects
<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-form">
<div class="glass-filter"></div>
<div class="glass-overlay"></div>
<div class="glass-specular"></div>
<div class="glass-content">
<div class="form-container login active">
<h3>Login</h3>
<form>
<div class="form-group">
<i class="fas fa-envelope"></i>
<input type="email" placeholder="Email" required>
</div>
<div class="form-group">
<i class="fas fa-lock"></i>
<input type="password" placeholder="Password" required>
</div>
<button type="submit">Sign In</button>
</form>
<p class="form-switch">Don't have an account? <a href="#" class="switch-to-register">Register</a></p>
</div>
<div class="form-container register">
<h3>Register</h3>
<form>
<div class="form-group">
<i class="fas fa-user"></i>
<input type="text" placeholder="Username" required>
</div>
<div class="form-group">
<i class="fas fa-envelope"></i>
<input type="email" placeholder="Email" required>
</div>
<div class="form-group">
<i class="fas fa-lock"></i>
<input type="password" placeholder="Password" required>
</div>
<div class="form-group">
<i class="fas fa-lock"></i>
<input type="password" placeholder="Confirm Password" required>
</div>
<button type="submit">Sign Up</button>
</form>
<p class="form-switch">Already have an account? <a href="#" class="switch-to-login">Login</a></p>
</div>
</div>
</div>
.glass-form {
--bg-color: rgba(255, 255, 255, 0.25);
--highlight: rgba(255, 255, 255, 0.75);
--text: #ffffff;
--input-bg: rgba(255, 255, 255, 0.1);
--input-border: rgba(255, 255, 255, 0.2);
--input-focus: rgba(255, 255, 255, 0.3);
position: relative;
width: 400px;
min-height: 450px;
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;
padding: 30px;
color: var(--text);
height: 100%;
}
.form-container {
display: none;
opacity: 0;
transform: translateX(20px);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.form-container.active {
display: block;
opacity: 1;
transform: translateX(0);
}
.form-container h3 {
margin: 0 0 20px 0;
font-size: 28px;
font-weight: 600;
text-align: center;
}
.form-group {
position: relative;
margin-bottom: 20px;
}
.form-group i {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: var(--text);
opacity: 0.8;
}
.form-group input {
width: 100%;
padding: 12px 15px 12px 45px;
background: var(--input-bg);
border: 1px solid var(--input-border);
border-radius: 10px;
color: var(--text);
font-size: 16px;
transition: border-color 0.3s ease, background 0.3s ease;
}
.form-group input:focus {
outline: none;
background: var(--input-focus);
border-color: var(--highlight);
}
.form-group input::placeholder {
color: rgba(255, 255, 255, 0.6);
}
button[type="submit"] {
width: 100%;
padding: 12px;
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 10px;
color: var(--text);
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 10px;
}
button[type="submit"]:hover {
background: rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.4);
}
.form-switch {
text-align: center;
margin-top: 20px;
font-size: 14px;
opacity: 0.8;
}
.form-switch a {
color: var(--text);
text-decoration: none;
font-weight: 600;
opacity: 1;
}
.form-switch a:hover {
text-decoration: underline;
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
.glass-form {
--bg-color: rgba(0, 0, 0, 0.25);
--highlight: rgba(255, 255, 255, 0.15);
--input-bg: rgba(0, 0, 0, 0.2);
--input-border: rgba(255, 255, 255, 0.1);
--input-focus: rgba(0, 0, 0, 0.3);
}
}
document.addEventListener('DOMContentLoaded', function() {
// Get all glass form elements
const glassElements = document.querySelectorAll('.glass-form');
const switchToRegister = document.querySelector('.switch-to-register');
const switchToLogin = document.querySelector('.switch-to-login');
const loginForm = document.querySelector('.form-container.login');
const registerForm = document.querySelector('.form-container.register');
// Add mousemove effect for each glass element
glassElements.forEach(element => {
element.addEventListener('mousemove', handleMouseMove);
element.addEventListener('mouseleave', handleMouseLeave);
});
// Form switch event listeners
if (switchToRegister && switchToLogin && loginForm && registerForm) {
switchToRegister.addEventListener('click', (e) => {
e.preventDefault();
loginForm.style.opacity = '0';
loginForm.style.transform = 'translateX(-20px)';
setTimeout(() => {
loginForm.classList.remove('active');
registerForm.classList.add('active');
setTimeout(() => {
registerForm.style.opacity = '1';
registerForm.style.transform = 'translateX(0)';
}, 50);
}, 300);
});
switchToLogin.addEventListener('click', (e) => {
e.preventDefault();
registerForm.style.opacity = '0';
registerForm.style.transform = 'translateX(-20px)';
setTimeout(() => {
registerForm.classList.remove('active');
loginForm.classList.add('active');
setTimeout(() => {
loginForm.style.opacity = '1';
loginForm.style.transform = 'translateX(0)';
}, 50);
}, 300);
});
}
// 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;
// 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 = document.querySelector('#glass-distortion feDisplacementMap');
if (filter) {
filter.setAttribute('scale', '77');
}
const specular = this.querySelector('.glass-specular');
if (specular) {
specular.style.background = 'none';
}
}
// Form validation and submission handling
const forms = document.querySelectorAll('.glass-form form');
forms.forEach(form => {
const inputs = form.querySelectorAll('input');
// Add input validation styles
inputs.forEach(input => {
input.addEventListener('invalid', function() {
this.classList.add('error');
});
input.addEventListener('input', function() {
if (this.validity.valid) {
this.classList.remove('error');
}
});
});
// Handle form submission
form.addEventListener('submit', (e) => {
e.preventDefault();
// Get form data
const formData = new FormData(form);
const data = Object.fromEntries(formData.entries());
// Simple validation for password match in register form
if (form.closest('.register')) {
const password = data.password;
const confirmPassword = data['confirm-password'];
if (password !== confirmPassword) {
alert('Passwords do not match!');
return;
}
}
// Here you would typically send the data to your server
console.log('Form submitted:', data);
// Show success state
const submitBtn = form.querySelector('button[type="submit"]');
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Success!';
submitBtn.classList.add('success');
setTimeout(() => {
submitBtn.textContent = originalText;
submitBtn.classList.remove('success');
form.reset();
}, 2000);
});
});
// Initialize code blocks for the snippet preview
initializeCodeBlocks();
});
// Function to initialize code blocks
function initializeCodeBlocks() {
const htmlCode = document.getElementById('html-code');
const cssCode = document.getElementById('css-code');
const jsCode = document.getElementById('js-code');
// Add copy functionality to code blocks
document.querySelectorAll('.copy-button').forEach(button => {
button.addEventListener('click', () => {
const targetId = button.getAttribute('data-target');
const codeBlock = document.getElementById(targetId);
if (codeBlock) {
navigator.clipboard.writeText(codeBlock.textContent).then(() => {
button.innerHTML = ' Copied!';
setTimeout(() => {
button.innerHTML = ' Copy';
}, 2000);
});
}
});
});
}