My Side navbar doesn't collapse after page reload - javascript

I have a side navbar using HTML, SCSS and js. When I click reload, it goes to uncollapse state.
HTML
<nav class="nav" id="myNav">
<button class="nav__toggle" id="toggle-btn">
<span class="hamburger"></span>
</button>
<ul>
<li class="brand">
<a href="">
<img src="/images/logo.png" class="img-fluid" alt="NC Designs logo">
</a>
</li>
<li>My creatives</li>
<li>About me</li>
<li>My Portfolio</li>
<li>Clients</li>
<li>Testimonials</li>
<li>Contact me</li>
</ul>
</nav>
SCSS
.nav {
position: absolute;
text-align: center;
right: 0;
width: 260px;
height: 100vh;
background: var(--clr-light);
box-shadow: 0 0 3em #00000026;
transform: translateX(100%);
transition: transform 300ms cubic-bezier(0.5, 0, 0.5, 1);
ul {
list-style: none;
margin: 0;
padding: 0;
.li:nth-child(0){
margin-bottom: 1rem!important;
}
li {
margin-bottom: 2em;
display: flex;
a {
text-decoration: none;
color: var(--clr-dark);
padding: .5em;
flex: 1;
&:hover {
text-decoration: underline;
color: var(--clr-primary);
}
}
}
}
}
.brand{
margin-top: 2em;
}
.brand img{
height:100px
}
.nav__toggle {
position: absolute;
top: 2em;
left: 0;
transform: translateX(-100%);
background: var(--clr-light);
padding: 1em 0.5em;
border: 0;
border-radius: 0.25em 0 0 0.25em;
cursor: pointer;
transition: left 600ms ease-in-out, padding 500ms,
transform 3500ms ease-in-out, opacity 200ms linear;
&:focus {
outline: 0;
box-shadow: 0 0 0 1px rgba(238, 99, 82, 0.5);
}
}
.hamburger {
display: block;
position: relative;
&::before,
&::after {
content: "";
position: absolute;
left: 0;
}
&::before {
bottom: 6px;
}
&::after {
top: 6px;
}
}
.hamburger,
.hamburger::before,
.hamburger::after {
width: 2em;
height: 3px;
background: var(--clr-dark);
transition: transform 350ms ease-in-out, opacity 200ms linear;
}
/* Navigation open styles */
.nav-open {
.nav {
-webkit-transform: translateX(0);
transform: translateX(0);
}
/* Change this stuff below */
.hamburger {
-webkit-transform: rotate(45deg) scale(0.7);
transform: rotate(45deg) scale(0.7);
&::before {
opacity: 0;
}
&::after {
transform: rotate(90deg) translate(-6px) scale(1);
}
}
.nav__toggle {
position: absolute;
top: 2em;
left: 98%;
transform: translateX(-100%);
background: var(--clr-light);
padding: 1em 0.1em;
border: 0;
border-radius: 50%;
box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
margin-bottom: 50px;
&:focus {
outline: 0;
border-radius: 50%;
box-shadow: 0 0 0 1px rgba(238, 99, 82, 0.25), 0 0 0.5em rgba(0, 0, 0, 0.25);
}
&:hover {
outline: 0;
border-radius: 50%;
box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.55);
}
}
}
JS
<script>
const navToggle = document.querySelector('.nav__toggle');
const navFocus = document.querySelector('nav ul li a');
navToggle.addEventListener('click', () => {
document.body.classList.toggle('nav-open');
});
/*
Allow the toggle to work if the tab key is used to access menu...
I'm not sure if this is the best way or if it works all the time.
I tried experimenting with keyup and the keycode but this seemed simple.
*/
navFocus.addEventListener('focus', () => {
document.body.classList.toggle('nav-open');
});
</script>
repo link
Note: when I click the refresh second time, the navbar opens (uncollapsed), that should not happen (should remain collapsed even if I reload from the uncollapsed state (open navbar state). What should I do?

This behavior is expected if you were to reload the page. However, if you wanted to override this, you need a way to save the state between page refreshes. I think you should take a look at the sessionStorage API:
https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
A couple of things to point you in the right direction:
When you load the page, you should access the state of the sidebar. I think opened or closed would be enough to remember the state of the sidebar. Something like:
const navBarKey = "navBarState"; // using variable to prevent typos
const navBarState = sessionStorage.getItem(navBarKey);
const open = "open"; // using variable to prevent typos
const navOpen = 'nav-open'; // using variable to prevent css class typos
if(navBarState === open){
// this code will run when first started. If not, you may need to add some window.onload logic.
// if the saved state is open, add 'nav-open'
body.classList.add(navOpen);
}
const navToggle = document.querySelector('.nav__toggle');
navToggle.addEventListener('click', () => {
if(body.classList.contains(navOpen)) {
// if already open, remove 'nav-open' and remove 'navBarState' from sessionStorage
body.classList.remove(navOpen);
sessionStorage.removeItem(navBarKey)
} else {
// if not open, add 'mav-open' and add 'navBarState' to sessionStorage
body.classList.add(navOpen);
sessionStorage.setItem(navBarKey, open)
}
});
sessionStorage will persist only while the window/tab is open, and will clear if you exit the browser.
localStorage, however, will persist even after the brower is closed. So, if you wanted to persist after restarting the browser, you should instead use localStorage.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
I hope this is enough for you to get started! There are of course, different ways to handle this/refactoring opportunities, but for the given code you have at hand, this should suffice.

The problem was with absolute positioning.
nav loses its absolute position after reload. After changing nav's position to fixed, it worked. No Javascript changed were required.
.nav {
position: fixed;
}
Thank you!

Related

Remove # from anchor in url

I created a button on my website with this code:
// set a short timeout before taking action
// so as to allow hash to be set
setTimeout(() => {
// uses HTML5 history API to manipulate the location bar
history.replaceState('', document.title, window.location.origin + window.location.pathname + window.location.search);
}, 500); // 5 millisecond timeout in this case
#media screen and (max-device-width: 1020px) {
button {
font-size: 15px!important;
animation: glow 1s ease-in-out infinite alternate;
transition-delay: 0.6s;
}
#-webkit-keyframes glow {
from {
box-shadow: 0 0 10px #00f498, 0 0 15px #00f498, 0 0 25px #00bcaa, 0 0 50px #00f498;
}
to {
box-shadow: 0 0 10px #00f498, 0 0 25px #00bcaa, 0 0 50px #00f498, 0 0 55px #00f498;
}
}
}
div {
margin: auto;
text-align: center;
padding: 60px;
}
button {
position: relative;
padding: 1em 2em;
outline: none;
border: 1px solid #303030;
background: #000000;
color: #00F498;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 25px;
overflow: hidden;
transition: 0.2s;
border-radius: 20px;
cursor: pointer;
font-family: "Rubik";
font-weight: 900;
}
button:hover {
box-shadow: 0 0 10px #00F498, 0 0 25px #00BCAA, 0 0 50px #00F498;
transition-delay: 0.6s;
}
button span {
position: absolute;
}
button span:nth-child(1) {
top: 0;
left: -100%;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, #00F498);
}
button:hover span:nth-child(1) {
left: 100%;
transition: 0.7s;
}
button span:nth-child(3) {
bottom: 0;
right: -100%;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, #00F498);
}
button:hover span:nth-child(3) {
right: 100%;
transition: 0.7s;
transition-delay: 0.35s;
}
button span:nth-child(2) {
top: -100%;
right: 0;
width: 2px;
height: 100%;
background: linear-gradient(180deg, transparent, #00F498);
}
button:hover span:nth-child(2) {
top: 100%;
transition: 0.7s;
transition-delay: 0.17s;
}
button span:nth-child(4) {
bottom: -100%;
left: 0;
width: 2px;
height: 100%;
background: linear-gradient(360deg, transparent, #00F498);
}
button:hover span:nth-child(4) {
bottom: 100%;
transition: 0.7s;
transition-delay: 0.52s;
}
button:active {
background: #00F498;
background: linear-gradient(to top right, #00F498, #00BCAA);
color: #fff;
box-shadow: 0 0 8px #00F498, 0 0 8px #00BCAA, 0 0 8px #00F498;
transition: 0.1s;
}
button:active span:nth-child(1) span:nth-child(2) span:nth-child(2) span:nth-child(2) {
transition: none;
transition-delay: none;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Rubik">
<a href="#mercadoaudiovisual" target="_top">
<div>
<button id="comeceagora">
<span></span>
<span></span>
<span></span>
<span></span> Comece Agora!
</button>
</div>
</a>
I would like to remove the hash from the url anchor, but I have tried several ways and none have worked.
The last code I tried was this one:
<!-- F’in sweet Webflow Hacks -->
<script>
// set a short timeout before taking action
// so as to allow hash to be set
setTimeout(()=>{
// uses HTML5 history API to manipulate the location bar
history.replaceState('', document.title, window.location.origin + window.location.pathname + window.location.search);
}, 5); // 5 millisecond timeout in this case
</script>
The site was built in a site builder called Zyro, I have the possibility to use Javascript, html and css and I have access to the <head>, but I believe the scripts don't work because I don't have direct access to the <body> of the site.
The button has been added to an embed code element.
The website link is this: https://bldgprod.com.br/
UPDATE:
I don't know if I formulated my question correctly, but I want the click on the button not to change the page url, because if a person wants to share the link with someone else, the link will be "contaminated".
First off, you HTML structure is wrong.
You can't put div inside a tag, because div is a block level element, while a is an inline level element.
Block level elements can hold both other block level elements as well inline level elements inside of them, while inline level elements can only hold other inline level elements inside of them.
Other then that, what is the reason you want to remove # from href tag in your a tag ? :)

Enable hover for touch/click on mobile

Everything works the way it should on desktop view but the DIV which shows on hover in desktop doesn't show in mobile view. I want to show that DIV on touch/click in mobile/tablet.
As per some suggestions, I tried with :active after :hover too but that doesn't work.
I don't mind JS or jQuery answers too.
DEMO: https://jsfiddle.net/ovg6xzhu/
HTML:
<div class="hoverEffect hoverEffect-first">
<img src="https://via.placeholder.com/150" />
<div class="mask">
<h2>Web Services!</h2>
<p>We are going to build another sets of css hover image effects with CSS3 animations.<br />View All</p>
</div>
</div>
CSS:
.hoverEffect {
width: 100%;
float: left;
overflow: hidden;
position: relative;
text-align: center;
cursor: default;
border-radius: 2px;
margin-bottom: 30px;
}
.hoverEffect .mask {
width: 100%;
position: absolute;
overflow: hidden;
top: 0;
left: 0
}
.hoverEffect img {
display: block;
position: relative
}
.hoverEffect h2 {
text-transform: uppercase;
color: #fff;
text-align: center;
position: relative;
padding: 10px;
margin: 20px 0 0 0
}
.hoverEffect p {
position: relative;
color: #fff;
padding: 0px 20px 20px;
text-align: center
}
.hoverEffect-first img {
transition: all 0.2s linear;
width:100%;
height:auto;
}
.hoverEffect-first .mask {
opacity: 0;
background-color: rgba(61, 90, 128, 0.95);
transition: all 0.4s ease-in-out;
width: 100%;
height: 100%;
}
.hoverEffect-first h2 {
margin: 10px 40px;
transform: translateY(-100px);
opacity: 0;
transition: all 0.2s ease-in-out;
}
.hoverEffect-first p {
transform: translateY(100px);
opacity: 0;
transition: all 0.2s linear;
}
.hoverEffect-first:hover img, .hoverEffect-first:active img {
transform: scale(1.1);
}
.hoverEffect-first:hover .mask, .hoverEffect-first:active .mask {
opacity: 1;
}
.hoverEffect-first:hover h2,
.hoverEffect-first:hover p,
.hoverEffect-first:active h2,
.hoverEffect-first:active p {
opacity: 1;
transform: translateY(0px);
}
.hoverEffect-first:hover p, .hoverEffect-first:active p {
transition-delay: 0.1s;
}
.hoverEffect-first:hover a.info, .hoverEffect-first:active a.info {
transition-delay: 0.2s;
}
Your code is working. Always make sure to clear your browser cache. A quick trick to do this on mobile would be to add " /?random " at the end of your url to get a fresh load. Make sure to change " random " to anything you wish per refresh so it keeps sending you a fresh load. That said I would also have to agree with ehab's answer, it's not very intuitive to show/hide your content upon hovering on mobile. Add visual indicators like a button or let the animation take place naturally when it enters the viewport.
You dont need js for this purpose: css should be enough, and active should do the job, The code you posted is working fine - maybe u had a cache problem. That being said its not the best experience for mobile users, you should not emulate hover effects on mobile, users wont expect they need to click ( and then they are expected to click on another element to make the effect go away).

How can I add different event handlers for outer and inner elements?

I am working on a project for an upcoming exhibition and need your help with some of the script. I used jQuery to implement a transition on click for the images and it works really well.
Now I want to implement some kind of lightbox gallery which enlarges the images on a second click on a specific image. Afterwards, when clicked anywhere but the enlarged image the lightbox gallery should close. All I know it that I need another onClick event in jQuery... but honestly I am pretty lost!
I hope someone can help me here.
This is the code I use right now:
jQuery(document).ready(function($){
$('ul.cards').on('click', function(){
$(this).toggleClass('transition');
});
});
ul.cards{
width: 1500px; margin: 0 auto 20px;
height: 450px;
list-style-type: none;
position: relative;
padding: 50px 0;
cursor: pointer;
li.title{ margin: 0 0 20px;
h2{ font-weight: 700; }
}
li.card{
background: #FFF; overflow: hidden;
height: 300px; width: 250px;
border-radius: 7.5px;
position: absolute; left: 0px;
box-shadow: 1px 2px 2px 0 #aaa;
transition: all 0.4s cubic-bezier(.63,.15,.03,1.12);
img{
max-width: 100%; height: auto;
}
div.content{
padding: 5px 10px;
h1{
}
p{
}
}
&.card-1{
z-index: 10; transform: rotateZ(-2deg);
}
&.card-2{
z-index: 9; transform: rotateZ(-7deg);
transition-delay: 0.05s;
}
&.card-3{
z-index: 8; transform: rotateZ(5deg);
transition-delay: 0.1s;
}
}
&.transition{
li.card{
transform: rotateZ(0deg);
&.card-1{
left: 560px;
}
&.card-2{
left: 280px;
}
&.card-3{
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="cards">
<li class="title">
<h2>Foncemagne, Étienne Lauréault</h2>
</li>
<li class="card card-1"><img src="https://digi.bib.uni-mannheim.de/fileadmin/digi/51044668X/max/51044668X_0001.jpg" />
</li>
<li class="card card-2"><img src="https://digi.bib.uni-mannheim.de/fileadmin/digi/510448682/max/510448682_0001.jpg" />
</li>
<li class="card card-3"><img src="https://digi.bib.uni-mannheim.de/fileadmin/digi/510449158/max/510449158_0001.jpg" />
</li>
</ul>
im not sure enough, but I just tried, maybe the meaning is more or less like this.
I change ul.card to double click, so that the image can also be clicked.
if you use second way maybe there will be less coding no need to use function if ($ ('li.card'). css ('transform', 'scale (1)')) on javascript,
but I can't use second way, maybe because it's css on element
.li there is have a transform property.
jQuery(document).ready(function($){
$('ul.cards').on('dblclick', function(){
$(this).toggleClass('transition');
$('li.card').css("transform","");
/* $('li.card').removeClass('transformation'); -- second way*/
$('li.card').off('click'); //delete the event listener click from li.card, so that when the collapsed cant be clicked
if ($('ul.cards').hasClass('transition')){
$('li.card').on('click', function(){
/* $(this).toggleClass('transformation');
-- second way */
if ($('li.card').css('transform','scale(1)'))
{
$(this).css('transform','scale(1.5)');
} else {
$(this).css('transform','scale(1)');
}
});
}
});
});
$(document).mouseup(function (e) { // when clicked anywhere the image close/back to default scale
if ($('ul.cards').hasClass('transition')){
if ($(e.target).closest('li.card').length
=== 0) {
$('li.card').css('transform','scale(1)');
}
}
});
ul.cards{
width: 1500px; margin: 0 auto 20px;
height: 450px;
list-style-type: none;
position: relative;
padding: 50px 0;
cursor: pointer;
li.title{ margin: 0 0 20px;
h2{ font-weight: 700; }
}
li.card{
background: #FFF; overflow: hidden;
height: 300px; width: 250px;
border-radius: 7.5px;
position: absolute; left: 0px;
box-shadow: 1px 2px 2px 0 #aaa;
transition: all 0.4s cubic-bezier(.63,.15,.03,1.12);
img{
max-width: 100%; height: auto;
}
div.content{
padding: 5px 10px;
h1{
}
p{
}
}
/* &.transformation {
transform: scale(1.5);
} -- second way */
&.card-1{
z-index: 10; transform: rotateZ(-2deg);
}
&.card-2{
z-index: 9; transform: rotateZ(-7deg);
transition-delay: 0.05s;
}
&.card-3{
z-index: 8; transform: rotateZ(5deg);
transition-delay: 0.1s;
}
}
&.transition{
li.card{
transform: rotateZ(0deg);
&.card-1{
left: 560px;
}
&.card-2{
left: 280px;
}
&.card-3{
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="cards" id="cardsParent">
<li class="title">
<h2>Foncemagne, Étienne Lauréault</h2>
</li>
<li id="card-1" class="card card-1"><img src="https://digi.bib.uni-mannheim.de/fileadmin/digi/51044668X/max/51044668X_0001.jpg" />
</li>
<li class="card card-2"><img src="https://digi.bib.uni-mannheim.de/fileadmin/digi/510448682/max/510448682_0001.jpg" />
</li>
<li class="card card-3"><img src="https://digi.bib.uni-mannheim.de/fileadmin/digi/510449158/max/510449158_0001.jpg" />
</li>
</ul>
<div style="height:100px;background-color:grey;color:white;text-align:center;">
click here or anywhere for close/change to default image
</div>
u can see in this link
https://jsfiddle.net/Lzp74drj/2/
I hope this is useful.

Slideout.js menu isnt smooth

I have been trying to get slideout.js to work properly for my site.
The issue is that when the menu is opened, the text appears before the fully opens and when the menu is closed, the text disappears after the menu is closed.
I have looked at the CSS and made sure that there are backgrounds to the menu and heights are correctly set.
Demo (view as mobile) - http://stefan.admark.co.uk/gates/index.php
JS:
window.onload = function() {
var slideout = new Slideout({
'panel': document.getElementById('main'),
'menu': document.getElementById('menu'),
'side': 'right',
'padding': 256,
'tolerance': 70
});
document.querySelector('.js-slideout-toggle').addEventListener('click', function() {
slideout.toggle();
});
};
CSS:
.slideout-menu {
position: fixed;
top: 80px;
bottom: 0;
width: 256px;
/* min-height: 100vh; */
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 999;
display: none;
padding-left:20px;
}
.slideout-menu-left {
left: 0;
}
.slideout-menu-right {
right: 0;
}
.slideout-panel {
position: relative;
z-index: 1;
will-change: transform;
background-color: #ffffff; /* A background-color is required */
min-height: 100%;
-webkit-box-shadow: 6px 0px 5px 0px rgba(0,0,0,0.1);
-moz-box-shadow: 6px 0px 5px 0px rgba(0,0,0,0.1);
box-shadow: 6px 0px 5px 0px rgba(0,0,0,0.1);
}
.slideout-open,
.slideout-open body,
.slideout-open .slideout-panel {
overflow: hidden;
}
.slideout-open .slideout-menu {
display: block;
}
#media screen and (min-width: 1000px) {
.slideout-panel {
/* margin-left: 256px; */
}
.slideout-menu {
display: none;
}
}
.panel:before {
content: '';
display: block;
background-color: rgba(0,0,0,0);
transition: background-color 0.5s ease-in-out;
}
.panel-open:before {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background-color: rgba(0,0,0,.5);
z-index: 99;
}
It looks like your <nav> element on your page doesn't have any transition CSS on it.
For instance, your <main> element has the following transition applied to it:
transition: -webkit-transform 300ms ease 0s; transform: translateX(-256px)
Whatever javascript you have triggering the transition for your <main> element, if applied to <nav> should cause the text and everything inside <nav> to transition properly as well.

Obscure HTML content behind modal

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">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/148866/cd-logo_1.svg" alt="Logo">
</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>
Close
</div>
</div>
</body>
At the end of the day, if you have code running on a client machine, security is out of the window. You can play games to make it more difficult for the user to discover, but let's first agree that perfect security given your implied constraints is not possible.
Within you're implied constraints, however, I can offer a couple of suggestions. When the authentication modal is visible/demanding attention, you might:
visibly blur the underlay; this just makes it look some degree of secure.
actually replace the underlayed DOM with some version of gibberish; the key point being that to be "safe from prying eyes", you need to actually remove anything that might be pried. You can either wholesale remove the sensitive bits, or you can scramble it. Your choice for your context.
If you want to keep the data around, for uber-fast redisplay after the user successfully authenticates, consider locking the necessary content inside of a private/inaccessible variable. Note that this still isn't secure to a determined user, but it raises the bar quite a bit. For total and complete security, you will have to actually and totally remove all sensitive information from the client machine and force them to recollect data once authenticated.

Categories