Skip to content

Instantly share code, notes, and snippets.

@saikatharryc
Created December 18, 2016 05:57
Show Gist options
  • Save saikatharryc/af7e3cbc4dabd8e37b5cb16aede8ac00 to your computer and use it in GitHub Desktop.
Save saikatharryc/af7e3cbc4dabd8e37b5cb16aede8ac00 to your computer and use it in GitHub Desktop.
Responsive Login/Signup Modal Window
<body>
<header role="banner">
<div id="cd-logo"><a href="#0"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-logo_1.svg" alt="Logo"></a></div>
<nav class="main-nav">
<ul>
<!-- inser more links here -->
<li><a class="cd-signin" href="#0">Sign in</a></li>
<li><a class="cd-signup" href="#0">Sign up</a></li>
</ul>
</nav>
</header>
<div class="cd-user-modal"> <!-- this is the entire modal form, including the background -->
<div class="cd-user-modal-container"> <!-- this is the container wrapper -->
<ul class="cd-switcher">
<li><a href="#0">Sign in</a></li>
<li><a href="#0">New account</a></li>
</ul>
<div id="cd-login"> <!-- log in form -->
<form class="cd-form">
<p class="fieldset">
<label class="image-replace cd-email" for="signin-email">E-mail</label>
<input class="full-width has-padding has-border" id="signin-email" type="email" placeholder="E-mail">
<span class="cd-error-message">Error message here!</span>
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signin-password">Password</label>
<input class="full-width has-padding has-border" id="signin-password" type="text" placeholder="Password">
<a href="#0" class="hide-password">Hide</a>
<span class="cd-error-message">Error message here!</span>
</p>
<p class="fieldset">
<input type="checkbox" id="remember-me" checked>
<label for="remember-me">Remember me</label>
</p>
<p class="fieldset">
<input class="full-width" type="submit" value="Login">
</p>
</form>
<p class="cd-form-bottom-message"><a href="#0">Forgot your password?</a></p>
<!-- <a href="#0" class="cd-close-form">Close</a> -->
</div> <!-- cd-login -->
<div id="cd-signup"> <!-- sign up form -->
<form class="cd-form">
<p class="fieldset">
<label class="image-replace cd-username" for="signup-username">Username</label>
<input class="full-width has-padding has-border" id="signup-username" type="text" placeholder="Username">
<span class="cd-error-message">Error message here!</span>
</p>
<p class="fieldset">
<label class="image-replace cd-email" for="signup-email">E-mail</label>
<input class="full-width has-padding has-border" id="signup-email" type="email" placeholder="E-mail">
<span class="cd-error-message">Error message here!</span>
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signup-password">Password</label>
<input class="full-width has-padding has-border" id="signup-password" type="text" placeholder="Password">
<a href="#0" class="hide-password">Hide</a>
<span class="cd-error-message">Error message here!</span>
</p>
<p class="fieldset">
<input type="checkbox" id="accept-terms">
<label for="accept-terms">I agree to the <a href="#0">Terms</a></label>
</p>
<p class="fieldset">
<input class="full-width has-padding" type="submit" value="Create account">
</p>
</form>
<!-- <a href="#0" class="cd-close-form">Close</a> -->
</div> <!-- cd-signup -->
<div id="cd-reset-password"> <!-- reset password form -->
<p class="cd-form-message">Lost your password? Please enter your email address. You will receive a link to create a new password.</p>
<form class="cd-form">
<p class="fieldset">
<label class="image-replace cd-email" for="reset-email">E-mail</label>
<input class="full-width has-padding has-border" id="reset-email" type="email" placeholder="E-mail">
<span class="cd-error-message">Error message here!</span>
</p>
<p class="fieldset">
<input class="full-width has-padding" type="submit" value="Reset password">
</p>
</form>
<p class="cd-form-bottom-message"><a href="#0">Back to log-in</a></p>
</div> <!-- cd-reset-password -->
<a href="#0" class="cd-close-form">Close</a>
</div> <!-- cd-user-modal-container -->
</div> <!-- cd-user-modal -->
</body>
jQuery(document).ready(function($){
var $form_modal = $('.cd-user-modal'),
$form_login = $form_modal.find('#cd-login'),
$form_signup = $form_modal.find('#cd-signup'),
$form_forgot_password = $form_modal.find('#cd-reset-password'),
$form_modal_tab = $('.cd-switcher'),
$tab_login = $form_modal_tab.children('li').eq(0).children('a'),
$tab_signup = $form_modal_tab.children('li').eq(1).children('a'),
$forgot_password_link = $form_login.find('.cd-form-bottom-message a'),
$back_to_login_link = $form_forgot_password.find('.cd-form-bottom-message a'),
$main_nav = $('.main-nav');
//open modal
$main_nav.on('click', function(event){
if( $(event.target).is($main_nav) ) {
// on mobile open the submenu
$(this).children('ul').toggleClass('is-visible');
} else {
// on mobile close submenu
$main_nav.children('ul').removeClass('is-visible');
//show modal layer
$form_modal.addClass('is-visible');
//show the selected form
( $(event.target).is('.cd-signup') ) ? signup_selected() : login_selected();
}
});
//close modal
$('.cd-user-modal').on('click', function(event){
if( $(event.target).is($form_modal) || $(event.target).is('.cd-close-form') ) {
$form_modal.removeClass('is-visible');
}
});
//close modal when clicking the esc keyboard button
$(document).keyup(function(event){
if(event.which=='27'){
$form_modal.removeClass('is-visible');
}
});
//switch from a tab to another
$form_modal_tab.on('click', function(event) {
event.preventDefault();
( $(event.target).is( $tab_login ) ) ? login_selected() : signup_selected();
});
//hide or show password
$('.hide-password').on('click', function(){
var $this= $(this),
$password_field = $this.prev('input');
( 'password' == $password_field.attr('type') ) ? $password_field.attr('type', 'text') : $password_field.attr('type', 'password');
( 'Hide' == $this.text() ) ? $this.text('Show') : $this.text('Hide');
//focus and move cursor to the end of input field
$password_field.putCursorAtEnd();
});
//show forgot-password form
$forgot_password_link.on('click', function(event){
event.preventDefault();
forgot_password_selected();
});
//back to login from the forgot-password form
$back_to_login_link.on('click', function(event){
event.preventDefault();
login_selected();
});
function login_selected(){
$form_login.addClass('is-selected');
$form_signup.removeClass('is-selected');
$form_forgot_password.removeClass('is-selected');
$tab_login.addClass('selected');
$tab_signup.removeClass('selected');
}
function signup_selected(){
$form_login.removeClass('is-selected');
$form_signup.addClass('is-selected');
$form_forgot_password.removeClass('is-selected');
$tab_login.removeClass('selected');
$tab_signup.addClass('selected');
}
function forgot_password_selected(){
$form_login.removeClass('is-selected');
$form_signup.removeClass('is-selected');
$form_forgot_password.addClass('is-selected');
}
//REMOVE THIS - it's just to show error messages
$form_login.find('input[type="submit"]').on('click', function(event){
event.preventDefault();
$form_login.find('input[type="email"]').toggleClass('has-error').next('span').toggleClass('is-visible');
});
$form_signup.find('input[type="submit"]').on('click', function(event){
event.preventDefault();
$form_signup.find('input[type="email"]').toggleClass('has-error').next('span').toggleClass('is-visible');
});
//IE9 placeholder fallback
//credits http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html
if(!Modernizr.input.placeholder){
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.val(input.attr('placeholder'));
}
}).blur();
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
}
});
//credits http://css-tricks.com/snippets/jquery/move-cursor-to-end-of-textarea-or-input/
jQuery.fn.putCursorAtEnd = function() {
return this.each(function() {
// If this function exists...
if (this.setSelectionRange) {
// ... then use it (Doesn't work in IE)
// Double the length because Opera is inconsistent about whether a carriage return is one character or two. Sigh.
var len = $(this).val().length * 2;
this.setSelectionRange(len, len);
} else {
// ... otherwise replace the contents with itself
// (Doesn't work in Google Chrome)
$(this).val($(this).val());
}
});
};
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
@import "bourbon";
// variables - colors
$main-text: #505260; // main text
$background: #fff; // body background color
$color-1: #343642; // blue-dark
$color-2: #2f889a; // blue-light
$color-3: #d2d8d8; // grey
$red: #d76666; // error messages
// variables - fonts
$primary-font: 'PT Sans', sans-serif;
// variables - z-index
$header-zindex: 2;
$modal-zindex: 3;
// variables - header
$header-height-S: 50px;
$header-height-M: 80px;
// mixins - rem fallback - credits: http://zerosixthree.se/
@function calculateRem($size) {
$remSize: $size / 16px;
@return $remSize * 1rem;
}
@mixin font-size($size) {
font-size: $size;
font-size: calculateRem($size);
}
// mixins - center vertically and/or horizontally an absolute positioned element
@mixin center($xy:xy) {
@if $xy == xy {
left: 50%;
top: 50%;
bottom: auto;
right: auto;
@include transform(translateX(-50%) translateY(-50%));
}
@else if $xy == x {
left: 50%;
right: auto;
@include transform(translateX(-50%));
}
@else if $xy == y {
top: 50%;
bottom: auto;
@include transform(translateY(-50%));
}
}
// mixins - border radius
@mixin border-radius($radius:.25em) {
border-radius: $radius;
}
// layout - breakpoints
$S: 600px;
$M: 768px;
$L: 1170px;
// layout - media queries
@mixin MQ($canvas) {
@if $canvas == S {
@media only screen and (min-width: $S) { @content; }
}
@else if $canvas == M {
@media only screen and (min-width: $M) { @content; }
}
@else if $canvas == L {
@media only screen and (min-width: $L) { @content; }
}
}
// layout - super light grid - it works with the .cd-container class
@mixin column($percentage, $float-direction:left) {
width: 100% * $percentage;
float: $float-direction;
}
/* --------------------------------
Primary style
-------------------------------- */
html * {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
*, *:after, *:before {
@include box-sizing(border-box);
}
body {
font: {
size: 100%;
family: $primary-font;
}
color: $main-text;
background-color: $background;
}
a {
color: $color-2;
text-decoration: none;
}
img {
max-width: 100%;
}
input, textarea {
font-family: $primary-font;
@include font-size(16px);
&::-ms-clear {
display: none;
}
}
/* --------------------------------
Main components
-------------------------------- */
header[role=banner] {
position: relative;
height: $header-height-S;
background: $color-1;
#cd-logo {
float: left;
margin: 4px 0 0 5%;
/* reduce logo size on mobile and make sure it is left aligned with the transform-origin property */
@include transform-origin(0 50%);
@include transform(scale(.8));
img {
display: block;
}
}
&::after { /* clearfix */
content: '';
display: table;
clear: both;
}
@include MQ(M) {
height: $header-height-M;
#cd-logo {
margin: 20px 0 0 5%;
@include transform(scale(1));
}
}
}
.main-nav {
float: right;
margin-right: 5%;
width: 44px;
height: 100%;
background: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-icon-menu.svg') no-repeat center center;
cursor: pointer;
ul {
position: absolute;
top: 0;
left: 0;
width: 100%;
@include transform(translateY(-100%));
&.is-visible {
@include transform(translateY($header-height-S));
}
}
a {
display: block;
height: $header-height-S;
line-height: $header-height-S;
padding-left: 5%;
background: darken($color-1, 5%);
border-top: 1px solid lighten($color-1, 3%);
color: #FFF;
}
@include MQ(M) {
width: auto;
height: auto;
background: none;
cursor: auto;
ul {
position: static;
width: auto;
@include transform(translateY(0));
line-height: $header-height-M;
&.is-visible {
@include transform(translateY(0));
}
}
li {
display: inline-block;
margin-left: 1em;
&:nth-last-child(2) {
margin-left: 2em;
}
}
a {
display: inline-block;
height: auto;
line-height: normal;
background: transparent;
&.cd-signin, &.cd-signup {
padding: .6em 1em;
border: 1px solid rgba(#FFF, .6);
border-radius: 50em;
}
&.cd-signup {
background: $color-2;
border: none;
}
}
}
}
/* --------------------------------
xsigin/signup popup
-------------------------------- */
.cd-user-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba($color-1, .9);
z-index: $modal-zindex;
overflow-y: auto;
cursor: pointer;
visibility: hidden;
opacity: 0;
@include transition(opacity .3s 0, visibility 0 .3s);
&.is-visible {
visibility: visible;
opacity: 1;
@include transition(opacity .3s 0, visibility 0 0);
.cd-user-modal-container {
@include transform(translateY(0));
}
}
}
.cd-user-modal-container {
position: relative;
width: 90%;
max-width: 600px;
background: #FFF;
margin: 3em auto 4em;
cursor: auto;
@include border-radius;
@include transform(translateY(-30px));
@include transition-property (transform);
@include transition-duration(.3s);
.cd-switcher {
@include clearfix;
li {
@include column(.5);
text-align: center;
&:first-child a {
border-radius: .25em 0 0 0;
}
&:last-child a {
border-radius: 0 .25em 0 0;
}
}
a {
display: block;
width: 100%;
height: 50px;
line-height: 50px;
background: $color-3;
color: darken($color-3, 30%);
&.selected {
background: #FFF;
color: $main-text;
}
}
}
@include MQ(S) {
margin: 4em auto;
.cd-switcher a {
height: 70px;
line-height: 70px;
}
}
}
.cd-form {
padding: 1.4em;
.fieldset {
position: relative;
margin: 1.4em 0;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
label {
@include font-size(14px);
&.image-replace {
/* replace text with an icon */
display: inline-block;
position: absolute;
left: 15px;
@include center(y);
height: 20px;
width: 20px;
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
color: transparent;
text-shadow: none;
background-repeat: no-repeat;
background-position: 50% 0;
}
&.cd-username {
background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-icon-username.svg');
}
&.cd-email {
background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-icon-email.svg');
}
&.cd-password {
background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-icon-password.svg');
}
}
input {
margin: 0;
padding: 0;
@include border-radius;
&.full-width {
width: 100%;
}
&.has-padding {
padding: 12px 20px 12px 50px;
}
&.has-border {
border: 1px solid $color-3;
@include appearance(none);
&:focus {
border-color: $color-1;
box-shadow: 0 0 5px rgba($color-1, .1);
outline: none;
}
}
&.has-error {
border: 1px solid $red;
}
&[type=password] {
/* space left for the HIDE button */
padding-right: 65px;
}
&[type=submit] {
padding: 16px 0;
cursor: pointer;
background: $color-2;
color: #FFF;
font-weight: bold;
border: none;
@include appearance(none);
.no-touch &:hover, .no-touch &:focus {
background: lighten($color-2, 5%);
outline: none;
}
}
}
.hide-password {
display: inline-block;
position: absolute;
right: 0;
top: 0;
padding: 6px 15px;
border-left: 1px solid $color-3;
@include center(y);
@include font-size(14px);
color: $color-1;
}
.cd-error-message {
display: inline-block;
position: absolute;
left: -5px;
bottom: -35px;
background: rgba($red, .9);
padding: .8em;
z-index: 2;
color: #FFF;
@include font-size(13px);
@include border-radius;
/* prevent click and touch events */
pointer-events: none;
visibility: hidden;
opacity: 0;
@include transition(opacity .2s 0, visibility 0 .2s);
&::after {
/* triangle */
content: '';
position: absolute;
left: 22px;
bottom: 100%;
@include triangle(16px, rgba($red, .9), up);
}
&.is-visible {
opacity: 1;
visibility: visible;
@include transition(opacity .2s 0, visibility 0 0);
}
}
@include MQ(S) {
padding: 2em;
.fieldset {
margin: 2em 0;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
input.has-padding {
padding: 16px 20px 16px 50px;
}
input[type=submit] {
padding: 16px 0;
}
}
}
.cd-form-message {
padding: 1.4em 1.4em 0;
@include font-size(14px);
line-height: 1.4;
text-align: center;
@include MQ(S) {
padding: 2em 2em 0;
}
}
.cd-form-bottom-message {
position: absolute;
width: 100%;
left: 0;
bottom: -30px;
text-align: center;
@include font-size(14px);
a {
color: #FFF;
text-decoration: underline;
}
}
.cd-close-form {
/* form X button on top right */
display: block;
position: absolute;
width: 40px;
height: 40px;
right: 0;
top: -40px;
background: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-icon-close.svg') no-repeat center center;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
@include MQ(L) {
display: none;
}
}
#cd-login, #cd-signup, #cd-reset-password {
display: none;
}
#cd-login.is-selected, #cd-signup.is-selected, #cd-reset-password.is-selected {
display: block;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment