Login page inspired by Google's Material Design - Using clear and intentional animations to interact and entertain the user during typing and login's pending and granted states.
A Pen by Kenneth Aamås on CodePen.
| <div class="tile"> | |
| <div class="tile-header"> | |
| <h2 style="color: white; opacity: .75; font-size: 4rem; display: flex; justify-content: center; align-items: center; height: 100%;">SIGN IN</h2> | |
| </div> | |
| <div class="tile-body"> | |
| <form id="form"> | |
| <label class="form-input"> | |
| <i class="material-icons">person</i> | |
| <input type="text" autofocus="true" required /> | |
| <span class="label">Username</span> | |
| <span class="underline"></span> | |
| </label> | |
| <label class="form-input"> | |
| <i class="material-icons">lock</i> | |
| <input type="password" required /> | |
| <span class="label">Password</span> | |
| <div class="underline"></div> | |
| </label> | |
| <div class="submit-container clearfix" style="margin-top: 2rem;"> | |
| <div id="submit" role="button" type="button" class="btn btn-irenic float-right" tabindex="0"> | |
| <span>SIGN IN</span> | |
| </div> | |
| <div class="login-pending"> | |
| <div class=spinner> | |
| <span class="dot1"></span> | |
| <span class="dot2"></span> | |
| </div> | |
| <div class="login-granted-content"> | |
| <i class="material-icons">done</i> | |
| </div> | |
| </div> | |
| </div> | |
| </form> | |
| </div> | |
| </div> |
Login page inspired by Google's Material Design - Using clear and intentional animations to interact and entertain the user during typing and login's pending and granted states.
A Pen by Kenneth Aamås on CodePen.
| var $btn = document.getElementById("submit"); | |
| var $form = document.getElementById("form") | |
| function signIn() { | |
| if ($form.checkValidity()) { | |
| $btn.classList.add('pending'); | |
| window.setTimeout(function(){ $btn.classList.add('granted'); }, 1500); | |
| } | |
| } | |
| $btn.addEventListener("click", signIn); |
| @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i|Monoton'); | |
| @import url('https://fonts.googleapis.com/icon?family=Material+Icons'); | |
| $colors: ( | |
| irenic: #07beb8, | |
| serene: #3dccc7, | |
| tranquil: #68d8d6, | |
| calm: #9ceaef, | |
| cool: #c4fff9, | |
| ice: #ffffff, | |
| base: #454749 | |
| ); | |
| @function color($key: "calm") { | |
| @return map-get($colors, $key); | |
| } | |
| * { | |
| box-sizing: border-box; | |
| } | |
| html { | |
| font-size: 14px; | |
| } | |
| body { | |
| background: linear-gradient(to bottom, color("tranquil"), color("ice")); | |
| color: color("base"); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-family: | |
| 'Source Sans Pro', | |
| sans-serif; | |
| min-height: 100vh; | |
| } | |
| h1, h2, h3, h4, h5, h6 { | |
| font-family: Monoton, sans-serif; | |
| margin-bottom: .5rem; | |
| } | |
| /** | |
| * Tiles | |
| */ | |
| .tile { | |
| background-color: color("ice"); | |
| border-radius: .1rem; | |
| box-shadow: 0 .75rem 1.5rem rgba(0,0,0,0.2), 0 .25rem .25rem rgba(0,0,0,0.2); | |
| position: relative; | |
| width: 100%; | |
| min-width: 320px; | |
| max-width: 24rem; | |
| overflow: hidden; | |
| .tile-header { | |
| background-image: url('https://res.cloudinary.com/dgmilxzy7/image/upload/c_scale,w_500,o_75,b_rgb:07beb8/v1506735375/CodePen/ViddenPixel.jpg'); | |
| background-position: center; | |
| background-size: cover; | |
| height: 12rem; | |
| } | |
| .tile-body { | |
| padding: 2rem; | |
| } | |
| } | |
| /** | |
| * Forms | |
| */ | |
| .form-input { | |
| $form-margin-bottom: 1rem; | |
| $label-font-size: 1rem; | |
| $label-font-size-focus: .85rem; | |
| $label-icon-spacing: 2.25rem; | |
| $input-padding-top: 1.5rem; | |
| $input-padding-right: 0; | |
| $input-padding-bottom: .5rem; | |
| $input-padding-left: 0; | |
| $input-underline-color: #868e96; | |
| $input-underline-color-focus: color("irenic"); | |
| display: block; | |
| position: relative; | |
| margin-bottom: $form-margin-bottom; | |
| & > .material-icons { | |
| position: absolute; | |
| font-size: 1.5rem; | |
| top: 1.2rem; | |
| & ~ input, & ~ .label, & ~ .underline { | |
| margin-left: $label-icon-spacing; | |
| width: calc(100% - #{$label-icon-spacing}); | |
| } | |
| } | |
| input { | |
| border: none; | |
| box-shadow: none; | |
| padding: { | |
| top: $input-padding-top; | |
| right: $input-padding-right; | |
| bottom: $input-padding-bottom; | |
| left: $input-padding-left; | |
| }; | |
| outline-style: none; | |
| width: 100%; | |
| & ~ .label { | |
| color: $input-underline-color; | |
| font-size: $label-font-size; | |
| margin: 0; | |
| pointer-events: none; | |
| position: absolute; | |
| top: $input-padding-top; | |
| left: $input-padding-left; | |
| transition: top .2s,font .2s; | |
| z-index: 1; | |
| } | |
| & ~ .underline { | |
| background-color: lighten($input-underline-color, 20%); | |
| height: 1px; | |
| width: 100%; | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| } | |
| &:hover, &:focus { | |
| & ~ .underline { | |
| background-color: $input-underline-color-focus; | |
| } | |
| & ~ .label { | |
| color: $input-underline-color-focus; | |
| } | |
| } | |
| &:focus { | |
| & ~ .underline { | |
| height: 2px; | |
| } | |
| } | |
| &:focus, &:valid { | |
| & ~ .label { | |
| top: 0; | |
| font-size: $label-font-size-focus; | |
| } | |
| } | |
| &:-webkit-autofill { | |
| & ~ .label { | |
| top: 0; | |
| font-size: $label-font-size-focus; | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Buttons | |
| */ | |
| @mixin btn-variant($background-color) { | |
| background-color: $background-color; | |
| color: white; | |
| &:hover, &:focus, &:active { | |
| background-color: darken($background-color, 5%); | |
| } | |
| } | |
| .btn { | |
| $btn-padding-x: 1rem; | |
| $btn-padding-y: .5rem; | |
| border-radius: .2rem; | |
| display: inline-block; | |
| padding: { | |
| top: $btn-padding-y; | |
| right: $btn-padding-x; | |
| bottom: $btn-padding-y; | |
| left: $btn-padding-x; | |
| }; | |
| } | |
| .btn, [role="button"], [type="button"] { | |
| -ms-touch-action: manipulation; | |
| touch-action: manipulation; | |
| cursor: pointer; | |
| } | |
| @each $color, $value in $colors { | |
| .btn-#{$color} { | |
| @include btn-variant($value); | |
| } | |
| } | |
| /** | |
| * Utilities | |
| */ | |
| .clearfix:after { | |
| content: ""; | |
| display: table; | |
| clear: both; | |
| } | |
| .float-right { | |
| float: right; | |
| } | |
| /** | |
| * | |
| */ | |
| .submit-container { | |
| position: relative; | |
| #submit { | |
| position: relative; | |
| z-index: 2; | |
| outline: none; | |
| opacity: 1; | |
| transition: transform .1s ease-in, opacity .1s ease-in, border-radius .1s ease-in; | |
| right: -1px; | |
| span { | |
| opacity: 1; | |
| transition: opacity .1s ease-in; | |
| } | |
| &.pending { | |
| transform: scale(0.55, 1.5); | |
| background-color: color("irenic"); | |
| border-radius: 50%; | |
| opacity: 1; | |
| span { | |
| opacity: 0; | |
| } | |
| & ~ .login-pending { | |
| opacity: 1; | |
| transform: scale(1, 1); | |
| z-index: 3; | |
| } | |
| } | |
| &.granted { | |
| & ~ .login-pending { | |
| opacity: 1; | |
| transform: translate(-9rem, -11rem) scale(18, 18); | |
| z-index: 3; | |
| .spinner { | |
| opacity: 0; | |
| } | |
| .login-granted-content { | |
| opacity: 1; | |
| } | |
| } | |
| } | |
| } | |
| .login-pending { | |
| height: 3rem; | |
| width: 3rem; | |
| background-color: color('irenic'); | |
| position: absolute; | |
| border-radius: 50%; | |
| right: 1rem; | |
| bottom: -0.5rem; | |
| opacity: 0; | |
| overflow: hidden; | |
| transform: translate(0, 0) scale(0.5, 0.5); | |
| transition: transform .2s ease-in, scale .2s ease-in; | |
| z-index: 1; | |
| .login-granted-content { | |
| background-image: url(https://res.cloudinary.com/dgmilxzy7/image/upload/c_scale,w_700,o_25,b_rgb:07beb8/v1506735375/CodePen/ViddenPixel.jpg); | |
| background-position: center; | |
| background-size: cover; | |
| color: color("ice"); | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100%; | |
| width: 100%; | |
| opacity: 0; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| transition: opacity .2s ease-in .2s; | |
| text-shadow: 0px 0px 20px color("ice"); | |
| .material-icons { | |
| font-size: 5px; | |
| position: relative; | |
| left: 1.25px; | |
| } | |
| } | |
| } | |
| } | |
| .spinner { | |
| width: 3rem; | |
| height: 3rem; | |
| position: relative; | |
| margin: 0 auto; | |
| .dot1, .dot2 { | |
| width: 100%; | |
| height: 100%; | |
| border-radius: 50%; | |
| background-color: color("tranquil"); | |
| opacity: 0.6; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| -webkit-animation: dot-bounce 2.0s infinite ease-in-out; | |
| animation: dot-bounce 2.0s infinite ease-in-out; | |
| } | |
| .dot2 { | |
| -webkit-animation-delay: -1.0s; | |
| animation-delay: -1.0s; | |
| } | |
| @-webkit-keyframes dot-bounce { | |
| 0%, 100% { -webkit-transform: scale(0.0) } | |
| 50% { -webkit-transform: scale(1.0) } | |
| } | |
| @keyframes dot-bounce { | |
| 0%, 100% { | |
| transform: scale(0.0); | |
| -webkit-transform: scale(0.0); | |
| } 50% { | |
| transform: scale(1.0); | |
| -webkit-transform: scale(1.0); | |
| } | |
| } | |
| } |