A neumorphism login form built with pure HTML and CSS that uses soft shadows and subtle highlights to create a smooth, embossed interface style. It enhances depth perception and modern soft UI aesthetics in authentication layouts.
Usage
Use this component when interfaces require soft UI authentication styling, such as SaaS login pages, creative dashboards, modern web apps, or experimental UI layouts emphasizing minimal depth contrast.
Implementation
The effect is implemented using dual box shadow techniques combined with soft background tones, creating raised and recessed surfaces typical of neumorphism design. Responsive styling ensures consistent appearance across devices.
HTML
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neumorphism Login Form</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="login-container">
<div class="login-card">
<div class="login-header">
<div class="neu-icon">
<div class="icon-inner">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</svg>
</div>
</div>
<h2>Welcome back</h2>
<p>Please sign in to continue</p>
</div>
<form class="login-form" id="loginForm" novalidate>
<div class="form-group">
<div class="input-group neu-input">
<input type="email" id="email" name="email" required autocomplete="email" placeholder=" ">
<label for="email">Email address</label>
<div class="input-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
<polyline points="22,6 12,13 2,6"/>
</svg>
</div>
</div>
<span class="error-message" id="emailError"></span>
</div>
<div class="form-group">
<div class="input-group neu-input password-group">
<input type="password" id="password" name="password" required autocomplete="current-password" placeholder=" ">
<label for="password">Password</label>
<div class="input-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
<path d="M7 11V7a5 5 0 0110 0v4"/>
</svg>
</div>
<button type="button" class="password-toggle neu-toggle" id="passwordToggle" aria-label="Toggle password visibility">
<svg class="eye-open" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
<circle cx="12" cy="12" r="3"/>
</svg>
<svg class="eye-closed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
<line x1="1" y1="1" x2="23" y2="23"/>
</svg>
</button>
</div>
<span class="error-message" id="passwordError"></span>
</div>
<div class="form-options">
<div class="remember-wrapper">
<input type="checkbox" id="remember" name="remember">
<label for="remember" class="checkbox-label">
<div class="neu-checkbox">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
<polyline points="20 6 9 17 4 12"/>
</svg>
</div>
Remember me
</label>
</div>
<a href="#" class="forgot-link">Forgot password?</a>
</div>
<button type="submit" class="neu-button login-btn">
<span class="btn-text">Sign In</span>
<div class="btn-loader">
<div class="neu-spinner"></div>
</div>
</button>
</form>
<div class="divider">
<div class="divider-line"></div>
<span>or continue with</span>
<div class="divider-line"></div>
</div>
<div class="social-login">
<button type="button" class="social-btn neu-social">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
</svg>
</button>
<button type="button" class="social-btn neu-social">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
</svg>
</button>
<button type="button" class="social-btn neu-social">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
</svg>
</button>
</div>
<div class="signup-link">
<p>Don't have an account? <a href="#">Sign up</a></p>
</div>
<div class="success-message" id="successMessage">
<div class="success-icon neu-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
<polyline points="20 6 9 17 4 12"/>
</svg>
</div>
<h3>Success!</h3>
<p>Redirecting to your dashboard...</p>
</div>
</div>
</div>
<script src="../../shared/js/form-utils.js"></script>
<script src="script.js"></script>
</body>CSS
{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #e0e5ec;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
line-height: 1.6;
}
.login-container {
width: 100%;
max-width: 420px;
}
.login-card {
background: #e0e5ec;
border-radius: 30px;
padding: 50px 40px;
box-shadow:
20px 20px 60px #bec3cf,
-20px -20px 60px #ffffff;
position: relative;
transition: all 0.3s ease;
}
.login-card:hover {
transform: translateY(-5px);
}
.login-header {
text-align: center;
margin-bottom: 40px;
}
.neu-icon {
width: 80px;
height: 80px;
margin: 0 auto 24px;
background: #e0e5ec;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow:
8px 8px 20px #bec3cf,
-8px -8px 20px #ffffff,
inset 0 0 0 #bec3cf,
inset 0 0 0 #ffffff;
transition: all 0.3s ease;
}
.neu-icon:hover {
box-shadow:
4px 4px 10px #bec3cf,
-4px -4px 10px #ffffff,
inset 4px 4px 10px #bec3cf,
inset -4px -4px 10px #ffffff;
}
.icon-inner {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #6c7293;
}
.icon-inner svg {
width: 100%;
height: 100%;
}
.login-header h2 {
color: #3d4468;
font-size: 2rem;
font-weight: 600;
margin-bottom: 8px;
}
.login-header p {
color: #9499b7;
font-size: 15px;
font-weight: 400;
}
.form-group {
margin-bottom: 28px;
position: relative;
}
.neu-input {
position: relative;
background: #e0e5ec;
border-radius: 15px;
box-shadow:
inset 8px 8px 16px #bec3cf,
inset -8px -8px 16px #ffffff;
transition: all 0.3s ease;
}
.neu-input:focus-within {
box-shadow:
inset 4px 4px 8px #bec3cf,
inset -4px -4px 8px #ffffff;
}
.neu-input input {
width: 100%;
background: transparent;
border: none;
padding: 20px 24px;
padding-left: 55px;
color: #3d4468;
font-size: 16px;
font-weight: 500;
outline: none;
transition: all 0.3s ease;
}
.neu-input input::placeholder {
color: transparent;
}
.neu-input label {
position: absolute;
left: 55px;
top: 50%;
transform: translateY(-50%);
color: #9499b7;
font-size: 16px;
font-weight: 400;
pointer-events: none;
transition: all 0.3s ease;
}
.neu-input input:focus + label,
.neu-input input:not(:placeholder-shown) + label {
top: 8px;
font-size: 12px;
color: #6c7293;
transform: translateY(0);
}
.input-icon {
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
color: #9499b7;
transition: all 0.3s ease;
}
.input-icon svg {
width: 100%;
height: 100%;
}
.neu-input:focus-within .input-icon {
color: #6c7293;
}
.password-group {
padding-right: 50px;
}
.neu-toggle {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
background: #e0e5ec;
border: none;
width: 35px;
height: 35px;
border-radius: 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #9499b7;
box-shadow:
4px 4px 10px #bec3cf,
-4px -4px 10px #ffffff;
transition: all 0.3s ease;
}
.neu-toggle:hover {
color: #6c7293;
}
.neu-toggle:active {
box-shadow:
inset 2px 2px 5px #bec3cf,
inset -2px -2px 5px #ffffff;
}
.neu-toggle svg {
width: 18px;
height: 18px;
}
.eye-closed {
display: none;
}
.neu-toggle.show-password .eye-open {
display: none;
}
.neu-toggle.show-password .eye-closed {
display: block;
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 35px;
flex-wrap: wrap;
gap: 16px;
}
.remember-wrapper {
display: flex;
align-items: center;
cursor: pointer;
}
.remember-wrapper input[type="checkbox"] {
display: none;
}
.checkbox-label {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
user-select: none;
color: #6c7293;
font-size: 14px;
font-weight: 500;
}
.neu-checkbox {
width: 22px;
height: 22px;
background: #e0e5ec;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
box-shadow:
3px 3px 8px #bec3cf,
-3px -3px 8px #ffffff;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.remember-wrapper input[type="checkbox"]:checked + .checkbox-label .neu-checkbox {
box-shadow:
inset 2px 2px 5px #bec3cf,
inset -2px -2px 5px #ffffff;
}
.neu-checkbox svg {
width: 14px;
height: 14px;
color: #00c896;
opacity: 0;
transform: scale(0);
transition: all 0.3s ease;
}
.remember-wrapper input[type="checkbox"]:checked + .checkbox-label .neu-checkbox svg {
opacity: 1;
transform: scale(1);
}
.forgot-link {
color: #6c7293;
text-decoration: none;
font-size: 14px;
font-weight: 500;
transition: color 0.3s ease;
}
.forgot-link:hover {
color: #3d4468;
}
.neu-button {
width: 100%;
background: #e0e5ec;
border: none;
border-radius: 15px;
padding: 18px 32px;
color: #3d4468;
font-size: 16px;
font-weight: 600;
cursor: pointer;
position: relative;
margin-bottom: 30px;
box-shadow:
8px 8px 20px #bec3cf,
-8px -8px 20px #ffffff;
transition: all 0.3s ease;
overflow: hidden;
}
.neu-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
.neu-button:hover {
transform: translateY(-2px);
box-shadow:
12px 12px 30px #bec3cf,
-12px -12px 30px #ffffff;
}
.neu-button:hover::before {
left: 100%;
}
.neu-button:active {
transform: translateY(0);
box-shadow:
inset 4px 4px 10px #bec3cf,
inset -4px -4px 10px #ffffff;
}
.btn-text {
position: relative;
z-index: 1;
transition: opacity 0.3s ease;
}
.btn-loader {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
transition: opacity 0.3s ease;
}
.neu-spinner {
width: 20px;
height: 20px;
border: 3px solid #bec3cf;
border-top: 3px solid #6c7293;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.neu-button.loading .btn-text {
opacity: 0;
}
.neu-button.loading .btn-loader {
opacity: 1;
}
.divider {
display: flex;
align-items: center;
margin: 30px 0;
gap: 16px;
}
.divider-line {
flex: 1;
height: 2px;
background: linear-gradient(90deg, transparent, #bec3cf, transparent);
}
.divider span {
color: #9499b7;
font-size: 13px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
}
.social-login {
display: flex;
justify-content: center;
gap: 16px;
margin-bottom: 30px;
}
.neu-social {
width: 50px;
height: 50px;
background: #e0e5ec;
border: none;
border-radius: 15px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #6c7293;
box-shadow:
6px 6px 15px #bec3cf,
-6px -6px 15px #ffffff;
transition: all 0.3s ease;
}
.neu-social:hover {
transform: translateY(-2px);
box-shadow:
8px 8px 20px #bec3cf,
-8px -8px 20px #ffffff;
}
.neu-social:active {
transform: translateY(0);
box-shadow:
inset 3px 3px 8px #bec3cf,
inset -3px -3px 8px #ffffff;
}
.neu-social svg {
width: 22px;
height: 22px;
}
.signup-link {
text-align: center;
}
.signup-link p {
color: #9499b7;
font-size: 14px;
}
.signup-link a {
color: #6c7293;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
}
.signup-link a:hover {
color: #3d4468;
}
.error-message {
color: #ff3b5c;
font-size: 12px;
font-weight: 500;
margin-top: 8px;
margin-left: 20px;
opacity: 0;
transform: translateY(-10px);
transition: all 0.3s ease;
}
.error-message.show {
opacity: 1;
transform: translateY(0);
}
.form-group.error .neu-input {
box-shadow:
inset 8px 8px 16px #ffb8c4,
inset -8px -8px 16px #ffffff,
0 0 0 2px #ff3b5c;
}
.success-message {
display: none;
text-align: center;
padding: 40px 20px;
opacity: 0;
transform: translateY(20px);
transition: all 0.5s ease;
}
.success-message.show {
display: block;
opacity: 1;
transform: translateY(0);
}
.success-message .neu-icon {
background: #e0e5ec;
color: #00c896;
margin-bottom: 20px;
}
.success-message h3 {
color: #3d4468;
font-size: 1.5rem;
margin-bottom: 8px;
}
.success-message p {
color: #9499b7;
font-size: 14px;
}
@media (max-width: 480px) {
body {
padding: 16px;
}
.login-card {
padding: 35px 25px;
border-radius: 20px;
}
.login-header h2 {
font-size: 1.75rem;
}
.neu-input input {
padding: 18px 20px;
padding-left: 50px;
}
.neu-input label {
left: 50px;
}
.form-options {
flex-direction: column;
align-items: flex-start;
gap: 16px;
}
}Notes
- Built with pure HTML and CSS
- No JavaScript required
- Uses soft shadow neumorphism styling
- Enhances subtle depth and tactile UI appearance
- Fully responsive across breakpoints
- Suitable for dashboards and login pages
- Easy to customize shadow softness and background tone
Preview styles shown. Production customization recommended.
Browse More UI Components
Explore hundreds of reusable HTML & CSS UI components built for modern web projects.
Discover buttons, cards, loaders, animations, layouts, and more all with live previews and clean, copy-paste code.
