<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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.