<div id="login" class="Login">
<h1 class="Login-heading">Sign in</h1>
<form id="login-form">
<div class="Login-field">
<input id="email" class="Login-input" type="email" required>
<label class="Login-label" for="email">Email</label>
<svg class="Login-field-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="#bbbbbb">
<path d="M12 10.823l8.965-5.563C20.677 5.1 20.352 5 20 5H4c-.352 0-.678.1-.965.26L12 10.823z"/>
<path d="M12.527 12.85c-.16.1-.344.15-.527.15s-.366-.05-.527-.15l-9.47-5.877C2.003 6.983 2 6.99 2 7v9c0 1.1.897 2 2 2h16c1.103 0 2-.9 2-2V7c0-.01-.003-.02-.003-.028l-9.47 5.877z"/>
</g>
</svg>
</div>
<div class="Login-field">
<input id="password" class="Login-input" type="password" required>
<label class="Login-label" for="password">Password</label>
<svg class="Login-field-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="#bbbbbb" d="M17 11V7c0-2.757-2.244-5-5-5-2.758 0-5 2.243-5 5v4c-1.103 0-2 .896-2 2v7c0 1.103.897 2 2 2h10c1.103 0 2-.897 2-2v-7c0-1.104-.897-2-2-2zm-5 7c-.828 0-1.5-.672-1.5-1.5S11.172 15 12 15s1.5.672 1.5 1.5S12.828 18 12 18zm3-7H9V7c0-1.654 1.346-3 3-3s3 1.346 3 3v4z"/>
</svg>
</div>
<div class="Login-forgotPassword">
<a class="Login-forgotPassword-link" href="#">Forgot Password?</a>
</div>
<button class="Login-button" aria-controls="status">Login</button>
</form>
<div class="Login-alert" role="region" id="status" aria-live="assertive"></div>
</div>
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
font-family: "Helvetica Neue", sans-serif;
background: #2e377D;
}
$Login-color-text: #fff;
$Login-color-text-dark: #abb3de;
$Login-color-text-xdark: #777;
$Login-color-primary: #3f51b5;
$Login-color-primary-dark: #324192;
$Login-transition-time: 0.3s;
.Login {
position: relative;
width: 400px;
padding: 1.25rem 4rem 5.5rem;
border-radius: 4px;
color: $Login-color-text;
background: $Login-color-primary;
box-shadow: 0 3px 4px 0px rgba(0,0,0,0.2);
&::before {
position: absolute;
z-index: -1;
opacity: 0;
top: 50%;
left: 50%;
height: 2rem;
width: 2rem;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 14.36"><path fill="#fff" d="M16.28 0L5.36 10.93 1.72 7.28 0 9l5.36 5.36L18 1.72 16.28 0"/></svg>') center center / contain no-repeat;
transition: $Login-transition-time opacity ease $Login-transition-time * 2;
transform: translateX(-50%) translateY(-50%);
content:"";
}
&::after {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background: $Login-color-primary-dark;
transition: $Login-transition-time transform ease;
transform: scaleY(0);
transform-origin: bottom;
}
}
.is-Login-success {
&::before {
z-index: 1;
opacity: 1;
}
&::after {
transform: scaleY(1);
}
}
.Login-heading {
margin-bottom: 0.25rem;
font-size: 1rem;
text-align: center;
}
.Login-field {
position: relative;
display: flex;
flex-direction: column-reverse;
height: 5rem;
}
.Login-field-icon {
position: absolute;
bottom: 0.5rem;
left: 0.5rem;
transition: $Login-transition-time transform ease $Login-transition-time / 2;
transform: scaleY(0);
}
.Login-label {
display: block;
width: 100%;
margin-bottom: 0.5rem;
font-size: 1rem;
transition: 0.3s font-size ease;
cursor: text;
}
.Login-input {
position: relative;
height: 4px;
padding: 0 1rem;
border: none;
border-radius: 4px;
color: $Login-color-text-dark;
font-size: 1.25rem;
transition: 0.3s padding ease;
box-shadow: 0 3px 4px 0px rgba(0,0,0,0.2);
&.is-Login-input-dirty {
padding: 1.25rem 1rem 1.25rem 2.5rem;
color: $Login-color-text-xdark;
~ .Login-label {
margin-bottom: 0.3rem;
font-size: 0.85rem;
color: $Login-color-text-dark;
}
~ .Login-field-icon {
transform: scaleX(1);
}
}
}
.Login-forgotPassword {
margin-top: 0.85rem;
text-align: right;
}
.Login-forgotPassword-link {
color: $Login-color-text;
font-size: 0.85rem;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
.Login-button {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
padding: 1.25rem;
border: none;
color: $Login-color-text;
font-size: 1rem;
font-weight: bold;
background: $Login-color-primary-dark;
}
.Login-alert {
position: absolute;
top: auto;
left: -10000px;
width: 1px;
height: 1px;
overflow: hidden;
}
View Compiled
/**
* Inspired by New Material Text-Fields from Srikant Shetty
* https://dribbble.com/shots/2197140-New-Material-Text-Fields
*/
// Cache elements
const loginElement = document.getElementById('login');
const loginFormElement = document.getElementById('login-form');
const emailInputElement = document.getElementById('email');
const passwordInputElement = document.getElementById('password');
const statusElement = document.getElementById('status');
// Adds a class to the input field so that we know it's "dirty" or
// has been interacted with
function inputEventHandler(event) {
event.target.classList.add('is-Login-input-dirty');
}
// Fires off inputEventHandler when either email or password field
// come in focus
emailInputElement.addEventListener('focus', inputEventHandler);
passwordInputElement.addEventListener('focus', inputEventHandler);
// Handles submitting
loginFormElement.addEventListener('submit', event => {
event.preventDefault();
loginElement.classList.add('is-Login-success');
// Adds aria-hidden="true" attribute to tell the screen reader
// not to allow focus or read anything in the form whilst
// the form is covered and showing the ticket
loginFormElement.setAttribute('aria-hidden', 'true');
// For accessbility purposes, inform the screenreader
// that login is successful
statusElement.innerHTML = "Login success!";
// Reset the form for the purpose of this demo
window.setTimeout(() => {
loginElement.classList.remove('is-Login-success');
loginFormElement.setAttribute('aria-hidden', 'false');
emailInputElement.classList.remove('is-Login-input-dirty');
passwordInputElement.classList.remove('is-Login-input-dirty');
emailInputElement.value = '';
passwordInputElement.value = '';
statusElement.innerHTML = '';
}, 3000);
});
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.