javascript dynamically create overlay background - javascript

I have a function that when clicked takes the div container and centers it on screen, enlarged with fixed position and z-index of 2. I would like to dynamically create an element to sit z-index of 1 underneath the div with a black background, partially transparent, that hides the main content. How do I create and place this element into the page and delete it afterwards?

This demo has on overlay that's loaded on window onload event (#overlay).
There's a password input in #overlay (#pass is "off")
#overlay will use classList to change it's class to.off once the password is entered, thereby rendering #overlay non-existent (display: none).
var ov = document.getElementById('overlay');
var ps = document.getElementById('pass');
ps.addEventListener('change', function(e) {
if (pass.value === "off" && ov.classList.contains('on')) {
ov.classList.add('off');
ov.classList.remove('on');
} else {
alert('password is incorrect');
}
}, false);
function init() {
ov.classList.add('on');
}
window.onload = init;
#overlay {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 1;
width: 100%;
height: 100%;
pointer-events: none;
}
.content {
border: 3px solid red;
width: 400px;
height: 200px;
margin: 50px auto;
padding: 10px;
}
p {
font: 600 16px/1.428'Arial' margin: 0 0 15px 10px;
}
#pass {
pointer-events: auto;
width: 100px;
line-height: 20px;
text-align: center;
margin: 25% auto 0;
display: block;
}
.off {
display: none;
}
.on {
display: block;
}
<div id="overlay" class="off">
<input id="pass" name="pass" type="password" placeholder="Enter Password">
</div>
<div class="content">
<p>xxxxxxxxxxxxxxxxxxxxxxxxxx</p>
<p>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
<p>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
</div>

I have a function that when clicked takes the div container and centers it on screen
Since you are doing this you have more control over it, All you have to so it is add this part of html along with this div of yours. (your div and this new div must be wrapped inside a parent div)
HTML
<div class="overlay-parent">
<div class="overlay"></div>
/* your div */
</div>
CSS
.overlay-parent{
width:100%;
height:100%;
overflow:hidden;
}
.overlay{
position:absolute;
top:0;
bottom:0;
width:100%;
background-color: black;
opacity:0.3;
}
This should be the structure when you are centering the div to center of the screen. And appending this structure to the body tag will get you the desired result

Related

Text appear/disappear on top of image with button toggle

In mobile, I'm trying to create a toggle that appears on top of an image, that when tapped on, makes text appear on top of the image too.
I basically want to recreate how The Guardian newspaper handles the little (i) icon in the bottom right corner on mobile.
And on desktop, the the text is there by default under the image and the (i) icon is gone.
So far I've managed to find a similar solution elsewhere online but it's not quite working right as I need it to.
function toggleText() {
var text = document.getElementById("demo");
if (text.style.display === "none") {
text.style.display = "block";
} else {
text.style.display = "none";
}
}
#blog {
width: 100%;
}
#blog figure {
position: relative;
}
#blog figure figcaption {
display: none;
position: absolute;
bottom: 0;
left: 0;
box-sizing: border-box;
width: 100%;
color: black;
text-align: left;
background: rgba(0, 0, 0, 0.5);
}
#blog figure button {
position: absolute;
bottom: 0;
right: 0;
color: black;
border: 5px solid black;
}
<div id="blog">
<figure>
<img src="https://cdn2.hubspot.net/hubfs/4635813/marble-around-the-world.jpg" alt="A photo of a slab of marble for example">
<figcaption id="demo" style='display: none'>A photo of a slab of marble for example</figcaption>
<button type='button' onclick="toggleText()">(i)</button>
</figure>
</div>
Don't use IDs. Your code should be reusable!
Don't use inline JS on* handlers, use Element.addEventListener() instead
Don't use inline style attributes.
Don't use el.style.display === "something" to check for display styles. Use Element.classList.toggle() instead
This straightforward example uses JavaScript to simply toggle a className "is-active" on the button's parent, the figure Element.
Everything else (icon symbol change, caption animation etc...) is handled purely by CSS:
document.querySelectorAll("figure button").forEach(EL_btn => {
EL_btn.addEventListener("click", () => {
EL_btn.closest("figure").classList.toggle("is-active");
});
});
/* QuickReset */ * {margin: 0; box-sizing: border-box;}
img {
max-width: 100%; /* Never extend images more than available */
}
figure {
position: relative;
overflow: hidden; /* overflow hidden to allow figcaption hide bottom */
}
figure img {
display: block; /* prevent "bottom space" caused by inline elements */
}
figure figcaption {
position: absolute;
width: 100%;
bottom: 0;
padding: 1rem;
padding-right: 4rem; /* Prevent text going under the button icon */
color: #fff;
background: rgba(0, 0, 0, 0.5);
transform: translateY(100%); /* Move down, out of view */
transition: transform 0.3s; /* Add some transition animation */
}
figure.is-active figcaption {
transform: translateY(0%); /* Move into view */
}
figure button {
position: absolute;
width: 2rem;
height: 2rem;
bottom: 0.5rem;
right: 0.5rem;
border-radius: 50%;
color: #fff;
background: rgba(0, 0, 0, 0.5);
border: 0;
cursor: pointer;
}
figure button::before {
content: "\2139"; /* i icon */
}
figure.is-active button::before {
content: "\2A09"; /* x icon */
}
<figure>
<img src="https://cdn2.hubspot.net/hubfs/4635813/marble-around-the-world.jpg" alt="A photo of a slab of marble for example">
<figcaption>A photo of a slab of marble for example</figcaption>
<button type="button"></button>
</figure>
The above will work for any number of such elements on your website without the need to add any more CSS or JS.
I see a couple things that could mess this up, one is the fact that there is nothing to make your image adjust to your mobile screen, more-over there is also margin that is there by default, so I suggest these changes to the CSS:
First I'd set box-sizing to border-box and margin to 0, this should be a regular practice by the way.
*{
box-sizing: border-box;
margin: 0;
}
Then select the image and make it adjust to your page as such
#blog figure img{
height: auto;
width:100%;
}
Finally, for some styling you can add some padding to your blog div to make the image slightly smaller on your screen
#blog {
width: 100%;
padding: 35px;
}
This is the Fiddle for it.

Absolutely Positioned elements Affecting Another elements on delete

I have more than one div that is positioned absolute and dynamically created by clicking on a button. Once clicked, they are placed in a container that is positioned relative, and I have a button on each div that when clicking on it, will delete the div, the problem is when deleting the div, it will affect the others positions.
function create() {
var $home = $('<div class="cabine"></div>');
$("#container").append($home);
}
.cabine { /*class that all div's share*/
position: absolute;
top:5%;
left:10%;
width:135px;
height:135px;
float:left;
background: red;
}
#container { /* Where the div's are placed*/
position: relative;
background-image: url(wall.jpg);
background-color: #FFFFFF;
border: 1px solid #000;
width: 100%;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="create()">Create Cabine</button>
<div id="container"></div>
In html you have #container instead of .container.

How to make a page "lights out" except for one element

I'm not really asking for help with my code, I'm more asking, how do you do this?
When you click my div, the screen goes black, but I want my div underneath to still show as normal, but the rest of the area to be blacked out.
function lightsout() {
document.getElementById("lightsout").style.visibility = "visible";
}
<div style="width:100px;height:100px;border:2px solid blue" onclick="lightsout()">Click Me</div>
<div id="lightsout" style="position:fixed;top:0;left:0;width:100%;height:100%;background-color:black;visibility:hidden;">
You can use the box-shadow property to achieve this effect.
Updated the Code
function lightsout() {
document.getElementById("maindiv").classList.toggle("visible");
}
.visible{
box-shadow: 0 0 0 10000px #000;
position: relative;
}
body{
color: red;
}
<div style="width:100px;height:100px;border:2px solid blue; color: #000;" onclick="lightsout()" id="maindiv">Click Me</div>
Other elements on the page will be hidden...
You can simply add z-indexes to your positioning. With giving the black area a lower z-index than your button but a higher z-index than the rest, you will have your effect.
Also it is recommended to not use inline styles, as your code becomes way more maintainable with styles and markup seperate.
function lightsout() {
document.getElementById("lightsout").classList.toggle("visible");
}
.button {
position: relative;
z-index: 10;
width: 100px;
height: 100px;
border: 2px solid blue;
background: white;
}
#lightsout {
position: fixed;
z-index: 5;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: gray;
visibility: hidden;
}
#lightsout.visible {
visibility: visible
}
<div class="button" onclick="lightsout()">Click Me</div>
<div id="lightsout"></div>
Other elements are hidden.
you can use css,
z-index, and add divbox background-color like this :)
function lightsout() {
document.getElementById("lightsout").style.visibility = "visible";
}
#lightsout{
z-index: -1
}
<div style="width:100px;height:100px;border:2px solid blue;background-color:white;" onclick="lightsout()">Click Me</div>
<div id="lightsout" style="position:fixed;top:0;left:0;width:100%;height:100%;background-color:black;visibility:hidden;">http://stackoverflow.com/questions/42688925/how-to-make-a-page-lights-out-except-for-one-element#

How to increase Width within a Div using JQuery - Newby

I'm trying to make it when the users mouse enters the .container the #facial will slide to the left, pause for a second, and then increase it's width to fill the width of it's container.
Right now the #facial slides properly, but when i try to have #facial fill the entire width it pops out of it's container. Also i'd like it to pause for a moment to show the transition slower from when it enters the middle to when it increases it's width.
Here is my code.
$( document ).ready(function() {
$('.container').mouseenter(function(){
// When mouse enters the .container, #facial slides to center of .container.
$('#facial').animate({right: '122px'});
// #facial expands it's width to fit .container.
$('#facial').width(400);
});
});
Here is my Demo
$(document).ready(function() {
$('.container').mouseenter(function() {
// When mouse enters the .container, #facial slides to center of .container.
$('#facial').animate({
right: '122px',
position: 'absolute'
}).delay(500).animate({
right: '0px',
width: '478px'
});
// #facial expands it's width to fit .container.
$('#facial').width(250); // .width(400) causes it to pop-out
});
});
body {
background-color: #d6d6d6;
}
.container {
margin: 200px auto;
background-color: red;
width: 478px;
height: 200px;
}
img {
float: left;
width: 239px;
height: 200px;
}
.image {
position: absolute;
}
#facial {
position: relative;
float: right;
width: 239px;
height: 200px;
background-color: #008aaf;
}
#facial h1,
#facial h2 {
text-align: center;
margin-top: 30px;
color: #FFFFFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="image">
<img src="http://s23.postimg.org/enn2yyh7v/Facial.jpg" alt="Facial - Marketing Material" />
</div>
<div id="facial">
<h1>Facial</h1>
<h2>Marketing Material</h2>
</div>
</div>
Changed to use percentages and to use absolute positioning.
https://jsfiddle.net/sy4pv8z3/
Javascript:
$( document ).ready(function() {
$('.container').mouseenter(function(){
// When mouse enters the .container, #facial slides to center of .container.
$('#facial').animate({right: '25%'})
.delay(500)
.animate({right: 0, width: '100%'});
});
});
CSS:
body {
background-color:#d6d6d6;
}
.container {
position: relative;
margin: 200px auto;
background-color:red;
width:478px;
height:200px;
}
img {
float:left;
width:239px;
height:200px;
}
#facial {
position:absolute;
right: 0;
width:239px;
height:200px;
background-color:#008aaf;
}
#facial h1, #facial h2 {
text-align:center;
margin-top:30px;
color:#FFFFFF;
}
$('#facial').animate({right: '122px'}).delay(1000).animate({width: '400px'});

Elements with fixed position moving when body overflow is hidden

I want to open a modal layer which overtakes the body scroll. To accomplish that, when the layer is shown I'm setting the body overflow to hidden and the overflow to scroll on the modal layer. Visually, one scrollbar replaces the other.
In the background I have a top bar with fixed position and 100% wide. What happens is when the body overflow is set to hidden, the 100% width div (top bar) takes the scrollbar space and its elements move to the right.
How can I prevent those elements from moving?
I tried to calculate (javascript) the width of the scrollbar and when setting the body overflow: hidden, give a margin-right: "scrollbar width" to the top bar. That didn't work.
Also tried a dummy div at the right end of the top bar with overflow set to scroll and force it to display a scroll bar when the layer is opened. The idea was to take the space of the missing scrollbar with another scrollbar, only on the top container. That almost worked but created a 1 or 2px flickering. Not good enough.
jsFiddle here with the basic problem
var body = $('body'),
main = $('.main'),
open_modal = $('.open-modal'),
close_modal = $('.close-modal'),
modal_container = $('.modal-container'),
toggleModal = function() {
body.toggleClass('body-locked');
modal_container.toggleClass('dp-block');
};
open_modal.on('click', toggleModal);
close_modal.on('click', toggleModal);
Basically...
When the modal is opened, set the menu width to it's current width and set a window.onresize event handler which will resize the menu to the body's width.
When the modal is closed, remove the fixed width and the window.onresize handler and return the menu to it's initial state.
In the spirit of less === more I've taken the liberty of simplifying your code as much as I can.
var body = $('body');
var menu = $('#topBarFixed');
function toggleModal() {
menu.css('width', body.hasClass('locked') ? '' : menu.width());
window.onresize = body.hasClass('locked') ? '' : function () {
menu.css('width', body.width());
}
body.toggleClass('locked');
}
body.on('click', '.open-modal, .close-modal', toggleModal);
body {
padding-top: 40px;
height: 1000px;
background: lightblue;
}
body.locked {
height: 100%;
overflow: hidden;
}
.modal-container {
display: none;
overflow-y: scroll;
position: fixed;
top: 0; right: 0;
height: 100%; width: 100%;
background-color: rgba(255, 255, 255, 0.3);
z-index: 400;
}
body.locked .modal-container {
display: block !important;
}
.modal {
height: 600px;
width: 200px;
margin: 50px auto;
background: indianred;
}
#topBarFixed {
width: 100%;
background-color: lightgray;
position: fixed;
top: 0;
left: 0;
text-align:center;
display: inline-block;
z-index: 200;
}
.topBarContent {
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
}
.inner1 {
width:30px;
line-height: 40px;
}
.open-modal {
position: relative;
top: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="topBarFixed">
<div class="topBarContent">
<div id="inner" class="inner1">div</div>
<div id="inner" class="inner1">div</div>
<div id="inner" class="inner1">div</div>
<div id="inner" class="inner1">div</div>
<div id="inner" class="inner1">div</div>
</div>
</div>
<p>Scroll down to open layer</p>
<button class="open-modal">Open layer</button>
<div class="modal-container">
<div class="modal">
<button class="close-modal">Close layer</button>
</div>
</div>
Your problem here is that topBarFixed has a 100% width. If this width was fixed you would not have this problem. The following has been tested on Chrome and Firefox:
Add this line to your toggleModal function's first line:
$(".topBarFixed").width($(".topBarFixed").width());
That will set the width to the actual width (in pixels) of the bar at that point. Then when you close the layer, set it back to 100%.
close_modal.on('click', function() { toggleModal(); $(".topBarFixed").width("100%"); });
The entire code looks like:
var body = $('body'),
main = $('.main'),
open_modal = $('.open-modal'),
close_modal = $('.close-modal'),
modal_container = $('.modal-container'),
toggleModal = function() {
$(".topBarFixed").width($(".topBarFixed").width());
body.toggleClass('body-locked');
modal_container.toggleClass('dp-block');
};
open_modal.on('click', toggleModal);
close_modal.on('click', function() { toggleModal(); $(".topBarFixed").width("100%"); });
And here is the jsFiddle: http://jsfiddle.net/wmk05t0b/5/
Edit
Optionally, you could just come up with a fixed width, and that will do the trick:
.topBarFixed
{
width:715px; /*changed from 100%*/
height: 40px;
background-color: lightgray;
position: fixed;
top: 0;
left: 0;
text-align:center;
display: inline-block;
z-index: 200;
}
Some errors in your code: id is only one. Use classes if you want to apply the same style to more elements.
<div class="topBarContent">
<div class="inner1">div</div>
<div class="inner1">div</div>
<div class="inner1">div</div>
<div class="inner1">div</div>
<div class="inner1">div</div>
</div>
Anyways, that's not what caused your problem. First of all, your body's overflow should be enough: don't add an overflowY to your .modal-container unless you want to prevent the background page from scrolling while modal is open. Second, fix the modal itself, and center it using the centered CSS trick (left:50%, margin-left:-half-of-your-width).
CSS:
.body-locked {
overflow:scroll;
}
.modal-container {
overflow:hidden;
position:fixed;
display: none;
top: 0; right: 0;
height: 100%; width: 100%;
background-color: rgba(255, 255, 255, 0.3);
z-index: 400;
}
.modal {
position: fixed;
height: 600px;
width: 200px;
margin: 50px auto 50px -100px;
background: indianred;
left:50%;
}
/*Reset your body, you never know*/
body {
margin:0;
padding:0
}
Hope it helps.

Categories