I have an overlay modal for authentication but it presents various security issues, especially if a user has some knowledge of CSS, HTML and the Inspect Tools.
Is there a specific way that the HTML behind the modal be obscured or hidden so that the page source does not show the content?
The below snippet is only an example of a modal and not the actual code I am using. My code actually pulls in the wp-auth-login
from Wordpress to the Frontend, but this gives basis to what Is happening. How do I ensure that the user cannot see the content behind a modal, especially not display:none
on the overlay to see the content behind?
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 https://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());
}
});
};
html * {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
*,
*:after,
*:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-size: 100%;
font-family: "PT Sans", sans-serif;
color: #505260;
background-color: #fff;
}
a {
color: #2f889a;
text-decoration: none;
}
img {
max-width: 100%;
}
input,
textarea {
font-family: "PT Sans", sans-serif;
font-size: 16px;
font-size: 1rem;
}
input::-ms-clear,
textarea::-ms-clear {
display: none;
}
header[role=banner] {
position: relative;
height: 50px;
background: #343642;
}
header[role=banner] #cd-logo {
float: left;
margin: 4px 0 0 5%;
-webkit-transform-origin: 0 50%;
-moz-transform-origin: 0 50%;
-ms-transform-origin: 0 50%;
-o-transform-origin: 0 50%;
transform-origin: 0 50%;
-webkit-transform: scale(0.8);
-moz-transform: scale(0.8);
-ms-transform: scale(0.8);
-o-transform: scale(0.8);
transform: scale(0.8);
}
header[role=banner] #cd-logo img {
display: block;
}
header[role=banner]::after {
content: '';
display: table;
clear: both;
}
@media only screen and (min-width: 768px) {
header[role=banner] {
height: 80px;
}
header[role=banner] #cd-logo {
margin: 20px 0 0 5%;
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
.main-nav {
float: right;
width: 80px;
height: 100%;
cursor: pointer;
}
.main-nav a {
display: block;
height: 50px;
line-height: 50px;
text-align: center;
background: #292a34;
border-top: 1px solid #3b3d4b;
color: #FFF;
}
@media only screen and (min-width: 768px) {
.main-nav {
width: auto;
height: auto;
background: none;
cursor: auto;
}
.main-nav a {
display: inline-block;
height: auto;
line-height: normal;
background: transparent;
}
.main-nav a.cd-signin {
padding: .6em 1em;
border: 1px solid rgba(255, 255, 255, 0.6);
border-radius: 50em;
}
}
.cd-user-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(52, 54, 66, 0.9);
z-index: 3;
overflow-y: auto;
cursor: pointer;
visibility: hidden;
opacity: 0;
-webkit-transition: opacity 0.3s 0, visibility 0 0.3s;
-moz-transition: opacity 0.3s 0, visibility 0 0.3s;
transition: opacity 0.3s 0, visibility 0 0.3s;
}
.cd-user-modal.is-visible {
visibility: visible;
opacity: 1;
-webkit-transition: opacity 0.3s 0, visibility 0 0;
-moz-transition: opacity 0.3s 0, visibility 0 0;
transition: opacity 0.3s 0, visibility 0 0;
}
.cd-user-modal.is-visible .cd-user-modal-container {
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
transform: translateY(0);
}
.cd-user-modal-container {
position: relative;
width: 90%;
max-width: 600px;
background: #FFF;
margin: 3em auto 4em;
cursor: auto;
border-radius: 0.25em;
-webkit-transform: translateY(-30px);
-moz-transform: translateY(-30px);
-ms-transform: translateY(-30px);
-o-transform: translateY(-30px);
transform: translateY(-30px);
-webkit-transition-property: -webkit-transform;
-moz-transition-property: -moz-transform;
transition-property: transform;
-webkit-transition-duration: 0.3s;
-moz-transition-duration: 0.3s;
transition-duration: 0.3s;
}
@media only screen and (min-width: 600px) {
.cd-user-modal-container {
margin: 4em auto;
}
.cd-user-modal-container .cd-switcher a {
height: 70px;
line-height: 70px;
}
}
.cd-close-form {
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;
}
@media only screen and (min-width: 1170px) {
.cd-close-form {
display: none;
}
}
#cd-login {
display: none;
}
#cd-login.is-selected {
display: block;
padding: 4em;
text-align: center;
}
<link href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/reset.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<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">
<a class="cd-signin" href="#0">Sign in</a>
</nav>
</header>
<div class="cd-user-modal">
<div class="cd-user-modal-container">
<div id="cd-login">
LOGIN FORM
</div>
<a href="#0" class="cd-close-form">Close</a>
</div>
</div>
</body>