In this stackblitz, I am not able to add animation while closing, I tried it using transform, but it didnt seem to work
HTML
Blocker is used to covering the full screen in a half-transparent mode in mobile devices
const sidebar = document.querySelector('.sidebar');
sidebar.querySelector('.blocker').onclick = hide;
function show() { // swipe right
sidebar.classList.add('visible');
document.body.style.overflow = 'hidden';
}
function hide() { // by blocker click, swipe left, or url change
sidebar.classList.remove('visible');
document.body.style.overflow = '';
}
function toggle() {
sidebar.classList.contains('visible') ? hide() : show();
}
.sidebar {
/* it's a mobile sidebar, blocker and content */
position: fixed;
top: 0;
left: 0;
width: 100vw;
/* to cover the whole screen */
height: 100vh;
padding: 0;
/* to override the default padding */
background: rgba(0, 0, 0, .5);
/* half transparent background */
display: none;
z-index: 99999;
/* to be on top of any other elements */
}
.sidebar.visible {
display: block;
}
/*cover the whole screen and to detect user click on background */
.sidebar .blocker {
position: absolute;
width: 100%;
height: 100%;
}
/* user content */
.sidebar .content {
position: absolute;
top: 0;
left: 0;
background: #FFF;
height: 100%;
width: 250px;
left: -50%;
/* will be animated to left: 0, by animation */
animation: slide 0.5s forwards;
}
#keyframes slide {
100% {
left: 0;
}
}
<div class="sidebar">
<div class="blocker"></div>
<div class="content">
Sidebar Content
</div>
</div>
With the above code, you can have a working sidebar.
Check the working code from stackblitz
https://allenhwkim.medium.com/mobile-friendly-sidebar-in-few-minutes-7817b5c5239f
https://stackblitz.com/edit/medium-sidebar-1-eevvax?file=style.css,index.js
You can't animate between display:block (when .sidebar has .visible applied to it) and display:none (when .visible is removed from .sidebar).
display:none turns off the display of an element so that it has no effect on layout (the document is rendered as though the element did not exist). All descendant elements (i.e. .blocker and .content) also have their display turned off.
The reason you get an animation upon adding .visible is that .sidebar now "exists" and so .sidebar-content also exists and as such animates. As soon as you remove .visible, .sidebar ceases to exist again and so it and its descendants disappear instantaneously.
You are along the right lines using transforms but you need to remove display:none as the method for hiding the sidebar. Something like the below is a good starting point. You may need to change some values to get it looking exactly as you wish. I have added a working codepen to show the result.
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
padding: 0;
background: rgba(0, 0, 0, .5);
z-index: 99999;
transform: translateX(-100%); // new property - will move the element off the left hand side of the screen
transition: transform .5s ease-in-out; // new property - will make the sidebar slide in in a similar manner to your animation
}
.sidebar.visible {
transform: translateX(0); // new property - makes sidebar sit in its natural position (i.e. taking up the whole viewport)
}
.sidebar .blocker {
position: absolute;
width: 100%;
height: 100%;
}
.sidebar .content {
position: absolute;
top: 0;
left: 0;
background: #FFF;
height: 100%;
width: 250px;
}
Related
I would like to make my modal contained in the container (the red area).
When I set position to relative, the modal opens from left to right whereas I want it to open from right to left
And the modal goes after the button when I want it to go over everything in the red area.
#container{ background-color:red; width: 100%; height: 300px }
.modal {
display: block;
position: absolute;
z-index: 99;
right: 0; top: 0;
width: 100%; height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
animation: slide-in 1s linear 1;
}
#keyframes slide-in { 0% { width: 0; } 25% { width: 25%; } 50% { width: 50%; } 75% { width: 75%; } 100% { width: 100%; }
}
.modal-content { background-color: #fefefe; margin: 20px; padding: 20px; border: 1px solid #888;
}
<div id=container>
<button id="open-modal-btn">Open modal</button>
</br>
<div id="my-modal" class="modal">
<div class="modal-content">
<h2>title</h2>
<p>content</p>
</div>
</div>
</div>
UPDATE: Sorry I mis-read your original post. In any case, the technique below is still preferred; just swap values.
To get a from-left slide with your current code as it exists, change right to left in your modal class.
.modal {
/* Change right to left */
/* right: 0; */
left: 0;
}
However your slide-in technique is awkward. You're achieving a slide by growing the width of the modal, so semantically this is a "grow-in". You're lucky that your content is not warping, and that it happens to appear as a "slide-in". A more elegant way to actually slide-in would be to use transform: translate(0,0) on the modal.
Instead I'd do this, roughly:
Codepen link
.modal {
/* ... */
/* Gives motion to changed properties like transform */
transition: all 0.5s ease;
/* Default off-screen left */
transform: translate(-100%,0);
/* Default off-screen right */
/* transform: translate(100%,0); */
}
.modalOpened .modal {
/* Set back to zero (center of viewport) */
transform: translate(0,0);
}
In addition, in your modal open event (the button click) simply toggle a class modalOpened on the app container. No keyframes needed. Just a natural, and actual, slide-in.
Why my class toggle is strict without any transition effect even though I added transition: 0.5s? It doesn't work on my bootstrap website. Whenever I try to test it on custom div on jsfiddle site then it works fine.
https://jsfiddle.net/dawid1798/5goyjwx0/3/
window.addEventListener('scroll', function() {
var header = document.getElementById("navbar");
header.classList.toggle("fixednav", window.scrollY > 100);
});
.fixednav {
transition: 0.5s;
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 9999;
}
When nav loses class .fixednav it also loses the transition property.
Put it on .nav:
.nav {
width: 100%;
height: 250px;
background: red;
transition: 0.5s;
}
Also check if bootstrap is loaded into the project and that you aren't disabling the transition with your css.
I am using Bootstrap 4 on my project, and modified the modal style in order to make it fullscreen like you can see it on this css code:
.modal.show {
display:flex!important;
flex-direction:column;
justify-content:center;
align-content:center;
align-items: flex-start;
}
.modal-body {
padding: 0;
margin: 0;
}
.close {
color: #aaa;
position: absolute;
/* background: blue !important; */
border: 0;
top: 0;
z-index: 99999;
right: 3%;
float: none;
opacity: 1;
font-size: 40px;
font-weight: 400;
}
.modal-backdrop.modal-backdrop-transparent {
background: #ffffff;
}
.modal-backdrop.modal-backdrop-transparent.in {
opacity: .9;
filter: alpha(opacity=90);
}
.modal-backdrop.modal-backdrop-fullscreen {
background: #ffffff;
}
.modal-backdrop.modal-backdrop-fullscreen.in {
opacity: .97;
filter: alpha(opacity=97);
}
.modal-fullscreen {
background: #fff;
min-width: 100%;
margin: 0;
}
#media (min-width: 768px) {
.modal-fullscreen .modal-dialog {
width: 750px;
}
}
#media (min-width: 992px) {
.modal-fullscreen .modal-dialog {
width: 970px;
}
}
#media (min-width: 1200px) {
.modal-fullscreen .modal-dialog {
width: 100%;
}
}
.modal-dialog {
position:fixed;
padding: 0;
max-width: 100%;
margin: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100vh;
overflow:auto;
}
When I tried to scroll down the vertical scrollbar of the browser, it won't ! I can use mouse scroll wheel but not by clicking on it directly !
Are you able to detect the problem ? It's for sure the fixed position but it is needed to make it fullscreen.
Here a jsfiddle to see a live demo of the problem:
https://jsfiddle.net/odbjcpt2/1/
I don't want to use position FLEX instead of FIXED since it won't solve the problem on my project, even if in the example given it will works (modal keep ading padding-right to body ... it is fixed using FIXED).
Thank you
In your JSFiddle, the problem appears to be with the div that contains the Lorem Ipsum text. It has pointer-events: auto; inherited from .modal-content class and if you remove that it ends up with pointer-events: none; inherited from modal-dialog class. If you take both those away, the problem goes away.
EDIT
I believe the root of the issue is that you're setting your .modal-dialog class to have fixed position and overflow auto.
Below is from bootstrap doc
Modals use position: fixed, which can sometimes be a bit particular
about its rendering. Whenever possible, place your modal HTML in a
top-level position to avoid potential interference from other
elements. You’ll likely run into issues when nesting a .modal within
another fixed element.
After playing around, if I edit your CSS in your JSFiddle example and in the .modal-dialog class I just remove position:fixed; and overflow:auto;, the problem goes away.
EDIT AGAIN
I just noticed you actually have .modal-dialog defined in your CSS twice, the first time with flex position and second time with fixed. Sounds like that was maybe a copy/paste mistake. Anyhow, still the same root cause I think, because your .modal-dialog div is fixed and it's inside your .modal div, and bootstrap doc says don't put another fixed inside a .modal
I have an element that has pointer events set to none, this is so hover styles for child elements don't show.
However when this element is clicked on I want to do something with JavaScript. Using an onclick event in JavaScript does not seem to work because pointer-events is set to none.
Is there a way around this so that I can have an element with no pointer events that can still trigger a JavaScript event?
[data-drawer="open"] {
.site-drawer {
transform: translateX(0);
transition: all .2s ease;
}
.site-container {
transform: translateX(-27.5rem);
// Disabling pointer events disables styles hover styles on below elements
// But also disables clicking on container to remove it.
pointer-events: none;
transition: all .2s ease;
&:after {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0,0,0,.75);
content: "";
}
}
}
JavaScript:
this.siteContainer.addEventListener('click', (e) => {
console.log('site container clicked');
if(document.body.hasAttribute('data-drawer')) {
document.body.removeAttribute('data-drawer');
}
});
Cheers
You can use this work around. Set pointer-events: none to the element that has the hover effects, And add a wrapper div to the elements that still needs to be triggered on click.
$(".cant-click-this").on("click", function(ev) {
console.log("You cant trigger the element, and it has no hover effects.");
});
$(".click-me-instead").on("click", function(ev) {
console.log("You can trigger click through the wrapper.");
});
.cant-click-this {
pointer-events: none;
}
.cant-click-this:hover {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="click-me-instead">
<button class="cant-click-this"> Try to click me</button> <br>Hovering is futile.
</div>
As I mentioned in the comments, you can achieve this by adding a non-clickable overlay on top of your content using pseudo-elements and z-index
Essentially you have four layers.
the content of the website (white)
the overlay that covers the content of the website while the modal
is open (grey)
the modal (red)
the layer that covers the modal contents. (transparent)
Result: user can't click inside the modal but can click outside anywhere on layer #2
Rough example:
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
pointer-events: none;
background: rgba(0, 0, 0, .5)
}
.close {
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
display: none;
z-index: 1;
position: fixed;
cursor: default;
}
.modal-content:after {
content: "";
left: 0;
position: absolute;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.modal:target {
opacity: 1;
pointer-events: auto;
}
.modal:target>.close {
display: block;
}
.modal>div {
width: 300px;
text-align: center;
padding: 40px;
z-index: 2;
position: relative;
background: red;
}
.wrap,
.modal {
display: flex;
align-items: center;
justify-content: center
}
<div class="wrap">
<button>You can click me!</button>
<div id="M" class="modal">
<div class="modal-content">
<button>But not me!</button>
</div>
</div>
</div>
I have an image which goes from one side off the screen to other. However, when I open the HTML on a different sized computer/laptop, it does not fit and looks out of place. How do I fix this?
CODE:
body {
text-align: center;
}
div.container {
text-align: left;
width: 710px;
margin: 0 auto;
border: 12px solid black;
border-radius: 10px;
}
div.content {
width: 700px;
min-height: 400px;
background-color: white;
padding: 5px;
}
#-webkit-keyframes mini {
from {
left: 410px;
}
}
.mini {
position: absolute;
top: 280px;
left: 950px;
width: 166px;
height: 70px;
z-index: 10000;
-webkit-animation: mini 3s;
animation: mini 8s;
}
<div class="container">
<div class="content">
<img src="Media/buscartoon.jpg" class="mini" />
</div>
</div>
maybe set initial left and top values
.imganim {
width:100px;
height:60px;
position:absolute;
-webkit-animation:myfirst 5s;
animation:myfirst 5s;
left: 0;
top: 0;
}
Your .content and .container have no position set, so I guess it's defaulting to the next parent element that does have these set.
Pop this on your .content div:
position: relative;
the image is still going to go over the limits because of left: 100% but adding a relative position to the container may well help you get to the next problem.
If you want the image to sit flush with the edge of the container rather than running over, you can also change your left: 100% to:
left: calc(100% - 100px)
...where 100px is the width of the element.
edit: jsfiddle example https://jsfiddle.net/w56r2xnr/
Try the following css classes that i have ammended. I have kept the top at 5px which makes room for the 5px padding within the content div. Also the 50% transformation formal includes the left 100% - (width of the image + right-padding).
You can now adjust the top to make it as you see fit.
CSS changes:
div.content {
width: 700px; min-height: 400px;
background-color: white; padding: 5px;
position: relative;
}
/* Chrome, Safari, Opera */
#-webkit-keyframes myfirst
{
0% {left:0%; top:5px;}
50% {left: calc(100% - 105px);}
100% {left:0%; top:5px;}
}
/* Standard syntax */
#keyframes myfirst
{
0% { left:0%; top:5px;}
50% {left: calc(100% - 105px);}
100% {left:0%; top:5px;}
}
Sample: http://codepen.io/Nasir_T/pen/ZBpjpw
Hope this helps.
[Edit - Code changed in question]
I think in both scenarios you will need to set the content div with position:relative to keep the image contained within it as the image itself is position:absolute. Along with that you need to use percentage values for the left and top in order for the animation and the position to be in the right place regardless of the size of the screen.
For the updated code in question please check the following code sample:
http://codepen.io/Nasir_T/pen/ObRwmO
Just adjust the key frame left percentage according to your need.