I have an overlay which contains a div and a couple of other elements.
I'm trying to get the div to scale up with a transition upon opening the overlay.
HTML
<div id="item-overlay" class="overlay">
<div id="item-panel" class="overlay-panel">
<div class="overlay-panel-top">
<h1 id="item-panel-title" class="main-panel-txt">Item</h1>
<img class="close" src="images/close.png" alt="" onclick="closeOverlay()">
</div>
</div>
</div>
CSS
.overlay{
display: none;
align-items: center;
justify-content: center;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 2;
}
#item-panel{
width: 0%;
height: 75%;
background: white;
border-radius: 15px;
padding: 25px;
-webkit-transition: width 0.25s ease-in-out;
}
JS
var itmOverlay = document.getElementById("item-overlay");
var itemPanel = document.getElementById("item-panel")
function itemOverlay(){
itmOverlay.style.display = "flex";
itemPanel.style.width = "50%";
}
function closeOverlay(){
itmOverlay.style.display = "none";
itemPanel.style.width = "0%";
}
This doesn't work, the of div just appears at full-size when opening the overlay. However, I can past the code above into the console and the transition will work.
I'm really not sure what's going on here.
I'm unsure why the code above doesn't work, but I managed to get the desired effect by changing the width in a separate function that's called after the overlay is enabled.
function itemOverlay(){
itmOverlay.style.display = "flex";
setTimeout(openOverlayTimer, 10);
}
function openOverlayTimer(){
itemPanel.style.width = "50%";
}
Related
I'm new to the web development world and wanted to know if there is a way to disable background scrolling.
I've tried z-index for the pop-up to display above all the elements, but some background content was getting overlapped with the pop-up.
I'm not much familiar with JS but was not able to get any help.
Below please find my code
body {
height: 200vh;
}
.bg-noscroll {
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
transform: translateY(-60px);
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
width: 30%;
position: relative;
transition: all 5s ease-in-out;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.content {
height: 250px;
}
.popup .content {
overflow-y: scroll;
}
#media screen and (max-width: 700px){
.popup{
width: 70%;
}
<body class="bg-noscroll bg-scroll">
<span><a class="popupBG-Disable" href="#popup">Full Recipe</a></span>
<div id="popup" class="overlay">
<div class="popup">
<h3>Foxtail Millet Porridge:</h3>
<a class="close" href="#">×</a>
<div class="content">
<span>Ingredients:<br>here are some things that you'd use to make this<br> isn't this amazing?<br>Yes, it is!<br>
this is getting loooooong<br>this will take me a while!<br>oh... yes it will<br>we're getting close<br>and we should be there <br>or not...<br>Im losing hope<br>and patience<br>with how long this is taking<br>I could really cry<br>
but we'll get there soon<br>safe and sound<br>free as pie<br>I dont know what I meant by that<br>
this is taking long mannnn<br>
</span>
Thank you for your help!
I have a live codepen with your original code so you can just copy and paste if you wish.
Using Jquery, we can enable and disable overflow using some simple code:
const modal = document.querySelector("#btn");
const body = document.querySelector("body");
const showModal = function (e) {
modal.classList.toggle("hidden");
if (!modal.classList.contains("hidden")) {
body.style.overflow = "hidden";
} else {
body.style.overflow = "hidden";
}
}; // just reversed for re-enabling scroll, as seen in the codepen
Currently, you have to make use of javascript and add or remove the scrollbar-properties or css-class using a hashchange event-listener for example:
window.addEventListener("hashchange", event => {
const newHash = new URL(event.newURL).hash,
el = document.getElementById(newHash.substr(1));
if (el && el.classList && el.classList.contains("overlay")) {
document.body.style.overflow = "hidden";
// or document.body.classList.add("bg-noscroll");
} else {
document.body.style.overflow = "";
// or document.body.classList.remove("bg-noscroll");
}
});
Starting from chromium 101 the support for the :has()-selector has been implemented (experimental flag only) and the current chromium 105 dev channel brings the :has()-selector enabled by default.
With the has()-selector it will be possible using:
body:has(.overlay:target) {
overflow: hidden;
}
Keep also mind, it may take some more time for other browsers to implement the has()-selector. Therefor the best would be to stick with the javascript method for a while.
We open popup window. We want to slide this off the screen. The "Right" and "Top" parts can be made as much as possible. How can we slide out of the screen?
var wind = window.open("https://www.google.com","","width=50,height=50,left=1500%,top=1000%");
While I'm not exactly sure about your particular use case, but by toggling opacity and right/left, you can achieve the "effect" of the div going out of the screen.
function move() {
let element = document.getElementById("box");
element.style.transform = "translate(-400px)";
element.style.right = 0;
element.style.opacity = 0;
}
#box {
width: 300px;
height: 200px;
background: blue;
margin-bottom: 20px;
color: white;
transition: all 0.3s ease;
opacity: 1;
position: absolute;
}
#btn {
margin-top: 300px;
}
<div id="box">Hello</div>
<button id="btn" onclick="move()">Click</button>
I want to have a main page and a side menu whose width is 0 at first. The main page's width is 100% and consists of a button. When clicking on the button, the side menu's width will grow up to 50% and the main page's margin-right will grow up to 50%. I've used CSS transition and some JavaScript code but it doesn't work smoothly. What's your suggestion?
I do not want to use 'px' instead of percentage.
Here is the example:
function openRightSide() {
leftSide.style.marginRight = "50%";
rightSide.style.width = "50%";
}
function closeLeftSide() {
leftSide.style.marginRight = "0";
rightSide.style.width = "0";
}
.main-container {
width: 100%;
height: 100px;
display: flex;
flex-direction: row;
position: relative;
}
.left-side-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 0;
background-color: #7f7f7f;
transition: margin 0.9s;
}
.right-side-container {
width: 0;
height: 100%;
position: fixed;
right: 0;
top: 0;
z-index: 2;
background-color: #f4f4f4;
overflow: hidden;
transition: width 0.9s;
}
<div class="main-container" id="mainContainer">
<div class="left-side-container" id="leftSide">
<button onclick="openRightSide()">Show Right Side</button>
</div>
<div class="right-side-container" id="rightSide">
<span class="close" onclick="closeLeftSide()">×</span>
</div>
</div>
Margin is a heavy operation on a transition better to use transform: translateX(50%) to get a smoother transition.
With a margin transition, the dom needs to check all elements position relative to the one you're animating. Transform changes the element independent of the other elements.
This also applies to the width. Use transform: scale(0).
I'm trying to switch images in a div every few seconds
the current code works, but there are 2 things that I want to change and I need your help for that:
The div resizes to the current image displaying in it, I want it to always use the size of the bigger image
I want to fade between the images instead of just switching
Thanks for reading, I hope you can help me.
This is what I got so far:
var imgIndex = 0;
setInterval(function() {
images[imgIndex].style.display = "none";
imgIndex++;
if (imgIndex >= images.length) {
imgIndex = 0;
}
images[imgIndex].style.display = "block";
}, 5000);
.imageDisplay {
display: inline-block;
width: 100%;
background-Color: white;
color: black;
border-radius: 5%;
margin: 2px;
padding: 1px;
opacity: 0.5;
transition-duration: 0.5s;
}
.imageDisplay:hover {
opacity: 1;
}
.Image {
width: 99%;
height: auto;
margin: 1px;
padding: 1px;
border-radius: 5%;
cursor: pointer;
display: none;
}
<div class="imageDisplay">
<p>Description</p>
<img class="Image"></img>
<img class="Image"></img>
</div>
Firstly you could set the div to be equal to the size of the large image and then use:
object-fit: cover;
object-position:center;
As for switching you could use:
transition: opacity .3s linear;
Read here on how to exactly implement the transitions. My suggestion would be stacking them all up and fading them in one by one every few seconds.
https://www.w3schools.com/css/css3_transitions.asp
http://css3.bradshawenterprises.com/cfimg/
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.