CSS transition not working with classList.add - javascript

Good, I’ve been an hour and I’m going crazy (I’m new)
I have a button that when pressed shows a div . Fixed sidemenu, this occupies 100% high and wide and contains two divs, one that does black background with some transparency and occupies everything and a white side menu.
I want that when you activate the open button or the close button or touch the black background transparently, the background and menu appear or disappear but with a transition and I do not know why it does not work, the menu with a side transition and the menu going from 0 to . 2 of opacity or vice versa when closed
See if anyone can explain why it does not work, thank you very much in advance :)
const sidemenu = document.getElementById('sidemenu')
const sidemenuContent = document.getElementById('sidemenu__content')
const abrirSidemenu = document.getElementById('sidemenu__open')
const cerrarSidemenu = document.getElementById('sidemenu__close')
const sidemenubg = document.getElementById('fondo-modal')
abrirSidemenu.addEventListener('click', () => {
sidemenu.classList.add('show-sidemenu')
sidemenuContent.classList.add('sidemenuContent__animation')
sidemenubg.classList.add('opacity__animation')
})
cerrarSidemenu.addEventListener('click', () => {
sidemenu.classList.remove('show-sidemenu')
sidemenuContent.classList.remove('sidemenuContent__animation')
sidemenubg.classList.remove('opacity__animation')
})
sidemenubg.addEventListener('click', () => {
sidemenu.classList.remove('show-sidemenu')
sidemenuContent.classList.remove('sidemenuContent__animation')
sidemenubg.classList.remove('opacity__animation')
})
.sidemenu {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.fondo-modal {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 5;
background-color: black;
opacity: .0;
transition: .5s;
}
.sidemenu__content {
position: fixed;
top: 0;
left: -350px;
width: 350px;
height: 100%;
background-color: white;
z-index: 10;
padding: 5rem 2rem 0;
overflow-y: auto;
transition: .5s;
}
.show-sidemenu {
display: grid;
}
.sidemenuContent__animation {
left: 0;
}
.opacity__animation {
opacity: .2;
}
<div class="topmenu__left">
<button id="sidemenu__open">OPEN</button>
<div class="sidemenu" id="sidemenu">
<div class="fondo-modal" id="fondo-modal"></div>
<div class="sidemenu__content" id="sidemenu__content">
<button id="sidemenu__close">CLOSE</button>
</div>
</div>

The major issue is that you're trying to transition the display attribute, which cannot be transitioned: https://www.w3schools.com/cssref/pr_class_display.asp So instead, we'll define your display attribute as you like but we'll add the opacity and visibility attributes and make those our goal for transition. We'll also specify a timing operation with linear which you can change at your discretion (see: https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function) and we'll transition everything for the sake of keeping it simple since you don't have any real need for specificity here. Hope that helps, let me know if you have any questions :)
Edit: added a light-blue to the body just so you can see everything happening but you can take that out obviously.
const sidemenu = document.getElementById('sidemenu');
const sidemenuContent = document.getElementById('sidemenu__content');
const abrirSidemenu = document.getElementById('sidemenu__open');
const cerrarSidemenu = document.getElementById('sidemenu__close');
const sidemenubg = document.getElementById('fondo-modal');
abrirSidemenu.addEventListener('click', () => {
sidemenu.classList.add('show-sidemenu');
sidemenuContent.classList.add('sidemenuContent__animation');
sidemenubg.classList.add('opacity__animation');
});
cerrarSidemenu.addEventListener('click', () => {
sidemenu.classList.remove('show-sidemenu');
sidemenuContent.classList.remove('sidemenuContent__animation');
sidemenubg.classList.remove('opacity__animation');
});
sidemenubg.addEventListener('click', () => {
sidemenu.classList.remove('show-sidemenu');
sidemenuContent.classList.remove('sidemenuContent__animation');
sidemenubg.classList.remove('opacity__animation');
});
body {
background-color: lightblue;
}
.sidemenu {
display: grid;
visibility: hidden;
position: fixed;
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100%;
transition: all 0.5s linear;
}
.fondo-modal {
display: block;
position: absolute;
visibility: hidden;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 5;
background-color: black;
opacity: 0;
transition: all 0.5s linear;
}
.sidemenu__content {
display: block;
position: fixed;
visibility: hidden;
top: 0;
left: -350px;
width: 350px;
height: 100%;
background-color: white;
z-index: 10;
padding: 5rem 2rem 0;
overflow-y: auto;
transition: all 0.5s linear;
}
.show-sidemenu {
visibility: visible;
opacity: 1;
left: 0;
transition: all 0.5s linear;
}
.sidemenuContent__animation {
visibility: visible;
left: 0;
transition: all 0.5s linear;
}
.opacity__animation {
visibility: visible;
opacity: 0.2;
transition: all 0.5s linear;
}
<div class="topmenu__left">
<button id="sidemenu__open">OPEN</button>
<div class="sidemenu" id="sidemenu">
<div class="fondo-modal" id="fondo-modal">modal</div>
<div class="sidemenu__content" id="sidemenu__content">
<button id="sidemenu__close">CLOSE</button>
</div>
</div>
</div>

Related

give animation to div when a button click

css Of that Div:-
.PostBox {
position: fixed;
height: 60%;
width: 100%;
background-color: white;
bottom: 0;
border-radius: 10px;
border-top: 5px solid rgb(16, 150, 233);
padding: 20px;
display: inline-table;
animation: SlidUp 3s ease-out backwards;
}
Animaion Of Div
#keyframes SlidUp {
from {
visibility: hidden;
bottom: -60%;
opacity: 0;
}
to {
visibility: visible;
bottom: 0;
opacity: 1;
}
}
I Want to give this Animation Whenever a button is clicked, That Button just turns the visibility of this div to visible or hidden.
in short, I want to give animation when ever a button click or given animation whenever visibility change
You can do this in pure CSS/HTML without JavaScript if that is suitable for your particular use case.
The trick is to use an input of type checkbox. It needs to be before the PostBox and a sibling of PostBox.
Here's a simple example:
.PostBox {
position: fixed;
height: 60%;
width: 100%;
background-color: white;
bottom: 0;
border-radius: 10px;
border-top: 5px solid rgb(16, 150, 233);
padding: 20px;
display: inline-table;
}
input:checked~.PostBox {
animation: SlidUp 3s ease-out backwards;
}
#keyframes SlidUp {
from {
visibility: hidden;
bottom: -60%;
opacity: 0;
}
to {
visibility: visible;
bottom: 0;
opacity: 1;
}
}
<label>Click me </label><input type="checkbox">
<div class="PostBox">I am the div that is going to slide up</div>
Obviously you'll want to refine things a bit - for example do you want the div to be there from the start? But that's a different question.

How can I create scroll effect like Waven Website?

I want to create a scroll effect like Waven Website, using vanilla html, css and javascript, that when you scroll, the whole page goes down, but i don't want to use just CSS like:
section{
scroll-snap-align: start;
}
.container{
scroll-snap-type: y mandatory;
overflow-y: scroll;
}
Because when I use this method, the page scroll a little and after a second scroll the whole section, I want some method when you scroll, the page goes instantly down.
Thank you :)
I think this is what you are looking for, please see snippet below or working codepen .
// original example (without scroll with mouse) :
// https://codepen.io/VeronQ/pen/MVzNOg
function scroll(event) {
event.preventDefault();
// iterate through all inputs
const inputs = document.querySelectorAll('input[name="item"]')
for(var i = 0;i < inputs.length;i++){
if(inputs[i].checked){
//check which input is checked and check next one or previous one according to the event.deltaY (scroll up or down)
if(event.deltaY>0 && i!=inputs.length-1)
inputs[i+1].checked = true
else if(event.deltaY<0 && i!=0)
inputs[i-1].checked = true
break;
}
}
}
// attach scroll function to onwheel event
document.onwheel = scroll;
#import url(https://fonts.googleapis.com/css?family=Carter+One);
input[type=radio] {
display: none;
}
input[type=radio]#section1:checked ~ nav label[for=section1] {
background-color: white;
}
input[type=radio]#section1:checked ~ section:nth-of-type(1) {
z-index: 1;
top: 0;
transition: top 0.5s ease-in-out;
transition-delay: 0s;
}
input[type=radio]#section1:checked ~ .cover {
background-color: #f8b195;
}
input[type=radio]#section2:checked ~ nav label[for=section2] {
background-color: white;
}
input[type=radio]#section2:checked ~ section:nth-of-type(2) {
z-index: 1;
top: 0;
transition: top 0.5s ease-in-out;
transition-delay: 0s;
}
input[type=radio]#section2:checked ~ .cover {
background-color: #c06c85;
}
input[type=radio]#section3:checked ~ nav label[for=section3] {
background-color: white;
}
input[type=radio]#section3:checked ~ section:nth-of-type(3) {
z-index: 1;
top: 0;
transition: top 0.5s ease-in-out;
transition-delay: 0s;
}
input[type=radio]#section3:checked ~ .cover {
background-color: #6c5c7c;
}
input[type=radio]#section4:checked ~ nav label[for=section4] {
background-color: white;
}
input[type=radio]#section4:checked ~ section:nth-of-type(4) {
z-index: 1;
top: 0;
transition: top 0.5s ease-in-out;
transition-delay: 0s;
}
input[type=radio]#section4:checked ~ .cover {
background-color: #345d7e;
}
.nav {
position: fixed;
z-index: 2;
right: 30px;
top: 50%;
transform: translateY(-50%);
}
.nav__item {
width: 12px;
height: 12px;
display: block;
margin: 12px auto;
border: solid 2px white;
border-radius: 50%;
cursor: pointer;
}
.nav__item:hover {
background-color: white;
}
section {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 100%;
right: 0;
left: 0;
transition-delay: 0.5s;
}
section:nth-of-type(1) {
background: #f8b195;
}
section:nth-of-type(2) {
background: #c06c85;
}
section:nth-of-type(3) {
background: #6c5c7c;
}
section:nth-of-type(4) {
background: #345d7e;
}
.cover {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
}
html,
body {
height: 100%;
}
body {
overflow: hidden;
color: white;
font: 100% "Carter One", cursive;
}
h1 {
font-size: 6em;
text-align: center;
}
<!-- Inputs-->
<input type="radio" name="item" checked="checked" id="section1"/>
<input type="radio" name="item" id="section2"/>
<input type="radio" name="item" id="section3"/>
<input type="radio" name="item" id="section4"/>
<!-- Navigation-->
<nav class="nav">
<label class="nav__item" for="section1"></label>
<label class="nav__item" for="section2"></label>
<label class="nav__item" for="section3"></label>
<label class="nav__item" for="section4"></label>
</nav>
<!-- Sections-->
<section>
<h1>One Page</h1>
</section>
<section>
<h1>Pure CSS</h1>
</section>
<section>
<h1>Full Screen</h1>
</section>
<section>
<h1>#Ver_Qn</h1>
</section>
<!-- Fix the white space when scrolling two sections at the time-->
<div class="cover"></div>

How can I create a multi-line splash screen?

I'm trying to create a basic splashscreen for a website but for some reason only 1 line of text is showing up on the splashscreen, and not the remaining text within the <p> tag. Here is a codepen of the problem:
Here is a codepen of the problem.
const splash = document.querySelector('.splash');
document.addEventListener('DOMContentLoaded', (e) => {
setTimeout(() => {
splash.classList.add('display-none');
}, 5000);
})
.splash {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
z-index: 9999;
color: white;
text-align: center;
line-height: 90vh;
}
.splash.display-none {
position: fixed;
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
z-index: 9999;
color: white;
text-align: center;
line-height: 90vh;
transition: 0.5s;
}
#keyframes fadeIn {
to {
opacity: 1;
}
}
.fade-in {
opacity: 0;
animation: fadeIn 1s ease-in forwards;
}
<html>
<head>
<div class="splash">
<p class="fade-in">Hi there! This splashscreen is broken!<br> I can't see this line!<br> I can't see this line either!<br> This line is also missing too!</p>
</div>
<p>hello world</p>
I'm sure it's a relatively simple fix, just a bit stumped on this one.
This is because of the huge amount of line-height that you have given to your <p> tag so each line will occupy 90vh so it will be out of the screen. If you want your text to have appeared in the middle of the element with class splash you can use flexbox to achieve this instead of line-height.
All you have to do is to set the element with splash class display: flex; and then with justify-content and align-items attribute position it to center horizontally and vertically.
So your final code should be something like this:
const splash = document.querySelector('.splash');
document.addEventListener('DOMContentLoaded', (e) => {
setTimeout(() => {
splash.classList.add('display-none');
}, 5000);
})
.splash {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
z-index: 9999;
color: white;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.splash.display-none {
position: fixed;
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
z-index: 9999;
color: white;
text-align: center;
line-height: 90vh;
transition: 0.5s;
}
#keyframes fadeIn {
to {
opacity: 1;
}
}
.fade-in {
opacity: 0;
animation: fadeIn 1s ease-in forwards;
}
<div class="splash">
<p class="fade-in">Hi there! This splashscreen is broken!<br> I can't see this line!<br> I can't see this line either!<br> This line is also missing too!</p>
</div>
<p>hello world</p>
Remove the line for line-height: 90vh; in your .splash css

Animating a Pseudo Class

I'm attempting to achieve a particular effect onclick. I've created an angled or razor-blade style div using a parent div-element, and a pseudo-element :after (see snippet below). What I'm trying to make happen is when the user clicks on the parent element, the skew property I have set up, shifts to a different skewed angle.
My problem is what regardless of whether I call the parent or the pseudo, onclick I cannot get the animation to work. Can anyone point me in the right direction?
$(document).ready(function() {
$('.slantedDiv').click(function() {
$('.slantedDiv .slantedDiv:after').toggleClass('active');
});
});
* {
padding: 0;
margin: 0;
}
.slantedDiv {
position: relative;
width: 100%;
height: 300px;
background-color: yellow;
}
.slantedDiv:after {
position: absolute;
width: 100%;
height: 100%;
content: '';
background: inherit;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform-origin: top left;
transform: skewY(10deg);
transition: all .3s ease-in-out;
}
.active {
transform-origin: top right;
transform: skewY(-10deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slantedDiv"></div>
The issue is to do with the selector in the click handler. Firstly, the element is just .slantedDiv, so repeating the class will not match any elements. You can avoid that issue entirely by just using the this reference in the jQuery object. Secondly, and more importantly, jQuery cannot select pseudo elements so including :after will not find anything.
Instead you need to toggle() the activeclass on the .slantedtDiv directly and then use the :after in your CSS rule based on the presence of the active class, something like this:
$(document).ready(function() {
$('.slantedDiv').click(function() {
$(this).toggleClass('active');
});
});
* {
padding: 0;
margin: 0;
}
.slantedDiv {
position: relative;
width: 100%;
height: 300px;
background-color: yellow;
}
.slantedDiv:after {
position: absolute;
width: 100%;
height: 100%;
content: '';
background: inherit;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform-origin: top left;
transform: skewY(10deg);
transition: all .3s ease-in-out;
}
.slantedDiv.active:after {
transform-origin: top right;
transform: skewY(-10deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slantedDiv"></div>

RotateY transition not working properly

When i hover once, transition is proper, but on second time, transition becomes wierd, as if the perspective: 800px starts working after transition has taken place.
Please also tell how can i set rotation about an edge except center.
I know about transform-origin but nothing such as transform-axis.
I want that when i hover over the , these images should open like a window.
var left=document.getElementById("left");
var right=document.getElementById("right");
function curtain() {
left.style.transform="rotateY(70deg)";
right.style.transform="rotateY(-70deg)";
}
function back() {
left.style.transform="rotateY(0deg)";
right.style.transform="rotateY(0deg)";
}
#animate{
width: 400px;
height: 300px;
margin: auto;
position: relative;
perspective: 800px;
}
img {
width: 100%;
}
#left {
position:absolute;
top: 0;
right: 50%;
padding: 0;
margin: 0;
width: 50%;
transition: transform 0.5s;
}
#right {
position: absolute;
top: 0;
right: 0%;
padding: 0;
margin: 0;
width: 50%;
transition: transform 0.5s;
}
<html>
<head>
<link href="style/style.css" rel="stylesheet">
</head>
<body>
<div id="animate" onmouseover="curtain()" onmouseout="back()">
<div id="left"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Ariyunda.JPG/200px-Ariyunda.JPG"></div>
<div id="right"><img src="http://www.cs.cornell.edu/courses/cs3110/2009sp/hw/ps4/beach_original.png"></div>
</div>
<script src="script/script.js"></script>
</body>
</html>
There seems to be an issue with perspective and the onmouseout. back() (in onmouseout) and curtain() (in onmouseover) are called quite inconsistently. onmouseout is called whenever the mouse moves outside the element (#animate in this case) or its children (the images). The children are animated - they move - and the onmouseout is thereby called multiple times.
I wouldn't recommend onmouseover / onmouseout for this - instead I would use CSS :hover.
That aside, transform-origin defines the center of rotation.
#animate:hover #left {
transform: rotateY(70deg);
}
#animate:hover #right {
transform: rotateY(-70deg);
}
#animate {
width: 400px;
height: 300px;
margin: auto;
position: relative;
perspective: 800px;
}
img {
width: 100%;
}
#left {
position: absolute;
top: 0;
right: 50%;
padding: 0;
margin: 0;
width: 50%;
transition: transform 0.5s;
transform-origin: left;
}
#right {
position: absolute;
top: 0;
right: 0%;
padding: 0;
margin: 0;
width: 50%;
transition: transform 0.5s;
transform-origin: right;
}
<div id = 'animate'>
<div id = 'left'><img src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Ariyunda.JPG/200px-Ariyunda.JPG'></div>
<div id = 'right'><img src = 'http://www.cs.cornell.edu/courses/cs3110/2009sp/hw/ps4/beach_original.png'></div>
</div>
I don't know the origin of the problem, but it works ok if you are using CSS hover instead of JS hover.
And the transform origin is the way to go, it does what your wanted transform-axis would do.
#animate{
width: 400px;
height: 300px;
margin: auto;
position: relative;
perspective: 800px;
}
img {
width: 100%;
}
#left {
position:absolute;
top: 0;
right: 50%;
padding: 0;
margin: 0;
width: 50%;
transition: transform 0.5s;
transform: rotateY(0deg);
transform-origin: left center;
}
#right {
position: absolute;
top: 0;
right: 0%;
padding: 0;
margin: 0;
width: 50%;
transition: transform 0.5s;
transform: rotateY(0deg);
transform-origin: right center;
}
#animate:hover #left {
transform: rotateY(70deg);
}
#animate:hover #right {
transform: rotateY(-70deg);
}
<div id="animate" onmouseover="curtain()" onmouseout="back()">
<div id="left"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Ariyunda.JPG/200px-Ariyunda.JPG"></div>
<div id="right"><img src="http://www.cs.cornell.edu/courses/cs3110/2009sp/hw/ps4/beach_original.png"></div>
</div>

Categories

Resources