Why does an element's width change after animation ends? - javascript

I'm learning jQuery, testing its functionality, and have some problem with an example I made.
https://codepen.io/MaxVelichkin/pen/pBJeZy
/*remove animate2 class and assign animate1 class to target*/
$(function() {
$('#trigger').on('click', function() {
$('#target').removeClass('animate2');
$('#target').addClass('animate1');
});
});
/*remove animate1 class and assign animate2 class to target*/
$(function() {
$('#trigger2').on('click', function() {
$('#target').removeClass('animate1');
$('#target').addClass('animate2');
});
});
/*just a container around*/
#container {
margin: 10px;
width: 350px;
height: 350px;
border: solid green 1px;
}
/*green button*/
#trigger {
width: 50px;
height: 50px;
border-radius: 100%;
background-color: green;
margin: 20px auto;
}
/*red button*/
#trigger2 {
width: 50px;
height: 50px;
border-radius: 100%;
background-color: red;
margin: 20px auto;
}
/*Target div which will be changing*/
#target {
width: 100px;
height: 100px;
border: solid blue 1px;
margin: 10px auto;
}
/*Keyframes for green button*/
#keyframes myfirst {
0% {
background: white;
width: 100px;
height: 100px;
border-radius: 0%;
}
100% {
background: blue;
width: 150px;
border-radius: 100%;
}
}
/*Keyframes for red button*/
#keyframes mysecond {
0% {
background: blue;
width: 150px;
border-radius: 100%;
}
100% {
background: white;
width: 100px;
height: 100px;
border-radius: 0%;
}
}
/*cusstom class to be assigned by green button*/
.animate1 {
-webkit-animation: myfirst 3s;
animation: myfirst 3s;
height: 100px;
background: blue;
width: 150px;
border-radius: 100%;
margin: 10px auto;
}
/*cusstom class to be assigned by red button*/
.animate2 {
-webkit-animation: mysecond 3s;
animation: mysecond 3s;
height: 100px;
width: 150px;
border: solid red 1px;
border-radius: 0%;
margin: 10px auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="trigger"></div>
<div id="trigger2"></div>
<div id="target"></div>
</div>
There are:
2 buttons, green and red.
2 sets of keyframes.
2 custom classes which start the animation of corresponding keyframes and applies the styles from the last keyframe.
target div, which style I want to change on button click.
When I click on the button, it assigns a class to the target div and removes the class, assigned by another button.
Question 1: Why the width of the target div is changing back to 100px after the green button animation ends (why it doesn't remain 150px)?
Question 2: Do I do everything right or there is a better jQuery approach?

Your #target is taking precedence since it is a id selector. This has a width of 100px. Your class animate1 is getting overwritten, so that's why you aren't seeing 150px.

you can code like this animation: myfirst 3s forwords;

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.

Make hovered tooltip disappear when clicking button

I am trying to create a tooltip for whatever that needs it on my website, e.g. a button, text, etc. So far I have something like this:
https://jsfiddle.net/f06q3cLg/
.content {
display: grid;
width: 100vw;
height: 100vh;
place-content: center;
}
.content .parent {
border: 1px red solid;
padding: 10px;
position: relative;
}
.content .parent:hover .tooltip-wrapper {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:hover:before {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:active .tooltip-wrapper {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:active:before {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
left: 50%;
transform: translateX(-50%);
opacity: 0;
}
.content .parent .tooltip-wrapper {
position: absolute;
display: grid;
left: 0;
width: 300px;
height: 100%;
opacity: 0;
pointer-events: none;
}
.content .parent .tooltip-wrapper.bottom {
top: calc(100% + 8px);
}
.content .parent .tooltip-wrapper .tooltip {
max-width: 300px;
width: fit-content;
padding: 8px;
position: absolute;
display: inline-block;
background: blue;
border-radius: 5px;
padding: 8px;
color: white;
font-size: 11px;
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
line-height: 1.3;
text-align: left;
}
/* Keyframes */
#keyframes fadeInTooltip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOutTooltip {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="content">
<div class="parent">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip</span>
</div>
</div>
</div>
As such, it works somewhat fine. My issue is that I would like the tooltip to disappear when I click the button. Now it vanishes, and then comes back with a 0.4s delay as the hover effect actually has. Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.
I'm not sure if this is even achievable with pure CSS, but any JS would also do.
The problem is that :active is only applied as long as the mouse is down.
mdn: :active:
The :active CSS pseudo-class represents an element (such as a button) that is being activated by the user. When using a mouse, "activation" typically starts when the user presses down the primary mouse button.
What you could do (if you want to stay CSS only) is to use tabindex="0" on the <div class="parent"> and :focus instead of :active. But you need to verify that using tabindex="0" here won't hurt usability.
Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.
That won't work with :focus either. I'm pretty sure that this behavior can only be achieved with JS. If it is possible with CSS only it likely would be a pretty hacky solution.
But from the perspective of a user, this seems to be counterintuitive that the tooltip won't appear after clicked.
A JavaScript solution that does what you want could look like this.
It is a simplified version of the tooltip to only show the relevant parts.
Every element having a tooltip has an attribute data-has-tooltip.
// event delegation for all mouse down event:
// this ensures that the code also works for elements that have been added to the DOM after that script was executed.
document.addEventListener('mousedown', (evt) => {
// check if the mousedown happened in an element with a tooltip
const element = evt.target.closest('[data-has-tooltip]');
if (element) {
// if the user already clicked on the element ignore the click
if (!element.classList.contains('active')) {
// add the active class to the element so that hover won't show the toolip
element.classList.add('active');
function removeActiveOnLeave() {
// remove the active class
element.classList.remove('active');
// remove the mouseleave event listener again
element.removeEventListener('mouseleave', removeActiveOnLeave)
}
// add an event listener for mouseleave to remove the active class
element.addEventListener('mouseleave', removeActiveOnLeave)
}
}
});
.parent {
display: inline-block;
border: 1px solid red;
padding: 0.5rem;
margin: 0.5rem;
}
.tooltip-wrapper {
display: none;
}
.parent:hover .tooltip-wrapper {
display: block;
}
.parent.active:hover .tooltip-wrapper {
display: none;
}
<div class="content">
<div class="parent" data-has-tooltip>
Hover me A
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip A </span>
</div>
</div>
</div>
<div class="content">
<div class="parent" data-has-tooltip>
Hover me B
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip B</span>
</div>
</div>
</div>
HTML
<div class="content">
<div class="parent" onClick="myFunction()">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip" id="tooltip">This is mytooltip</span>
</div>
</div>
</div>
Javascript
function myFunction(){
var tooltip=document.getElementById("tooltip");
if (tooltip.style.display=="none") {
document.getElementById("tooltip").style.display="block";
} else {
document.getElementById("tooltip").style.display="none";
}
}
Manipulating 'display' property.
const parent = document.querySelector('.parent');
const toolTip = document.querySelector('.tooltip');
parent.addEventListener('click', () => {
if(toolTip.style.display !== 'none') {
toolTip.style.display = 'none';
}else {
toolTip.style.display = 'grid';
}
});
A solution using jQuery 3.4.1:
$(".parent").click(function () {
$(".tooltip-wrapper").css("display", "none");
});
The only downfall with that solution is once you click and re-hover in the same session, the SCSS :hover doesn't work properly.
No need to stress, just add the following if you want that functionality:
$(".parent").hover(function () {
$(".tooltip-wrapper").css("display", "block");
});
Try it out in the attached snippet:
$(".parent").click(function () {
$(".tooltip-wrapper").css("display", "none");
});
$(".parent").hover(function () {
$(".tooltip-wrapper").css("display", "block");
});
.content {
display: grid;
width: 100vw;
height: 100vh;
place-content: center;
}
.content .parent {
border: 1px red solid;
padding: 10px;
position: relative;
}
.content .parent:hover .tooltip-wrapper {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:hover:before {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:active .tooltip-wrapper {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:active:before {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
left: 50%;
transform: translateX(-50%);
opacity: 0;
}
.content .parent .tooltip-wrapper {
position: absolute;
display: grid;
left: 0;
width: 300px;
height: 100%;
opacity: 0;
pointer-events: none;
}
.content .parent .tooltip-wrapper.bottom {
top: calc(100% + 8px);
}
.content .parent .tooltip-wrapper .tooltip {
max-width: 300px;
width: fit-content;
padding: 8px;
position: absolute;
display: inline-block;
background: blue;
border-radius: 5px;
padding: 8px;
color: white;
font-size: 11px;
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
line-height: 1.3;
text-align: left;
}
/* Keyframes */
#keyframes fadeInTooltip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOutTooltip {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="content">
<div class="parent">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip</span>
</div>
</div>
</div>
OR, you can see it working in this Fiddle. with your initial
SCSS.
You can uncomment the second function to see the hover working again after clicking.

Make a shape and animate it in JavaScript or CSS

I want to create a L shape with lines (div element). I also want to animate it. The problem is that when I try to rotate it (using transform rotate), the whole line gets rotated. How do I get it done? Can anyone help? Below is the code snippet. How do I make it a L.
.line {
width: 100px;
background: #ff0000;
animation: animate-line 2s;
height: 2px;
}
#keyframes animate-line {
0% {
width: 50px;
}
100% {
width: 300px;
}
}
<div class="line"></div>
Simply without using JS or an SVG image you can animate the elements width and height and use borders
.line {
position: absolute;
width: 0px;
height: 0px;
background: transprent;
border-top: 2px solid red;
border-right: 2px solid red;
animation: animate-line 2s linear forwards;
}
#keyframes animate-line {
0% {
width: 50px;
height: 0px;
}
50% {
width: 300px;
height: 0px;
}
100% {
width: 300px;
height: 300px;
}
}
<div class="line"></div>
If that isn't what you wanted please provide an image with an example.

My css animation doesnt work when i run js function classList.add

I made a div with some class and height 0px and on clicking something, I run classList.add to add the class where height is 150px (popup). When the function adds the class, div is supposed to make an animation from height: 0px to height: 150px.
Can someone tell me why this isn't working?
function issPopup() {
var ist = document.getElementById("ist");
iss.classList.toggle("istopen");
}
#keyframes isani1 {
from {
height: 0px;
}
to {
height: 130px;
}
}
#-webkit-keyframes isani1 {
from {
height: 0px;
}
to {
height: 130px;
}
}
.inputsubmittextdiv.istopen {
width: 100%;
height: auto;
min-height: 130px;
float: left;
-webkit-animation: isani1 1s;
animation: isani1 1s;
}
.inputsubmittextdiv {
width: 100%;
height: 0px;
min-height: 0px;
float: left;
overflow: hidden;
}
<div id="ist" class="inputsubmittextdiv">
</div>
You can simply do something like the following:
function addClass(elem) {
elem.classList.add('istopen');
}
//here are you are basically telling your onCLick event to add the .istopen class whenever "something" is clicked.
//you can do the same when you hover over something etc.
.istopen {
width: 100%;
height: auto;
min-height: 130px;
float: left;
-webkit-animation: isani1 1s;
animation: isani1 1s;
background: red;
}
<div id="ist" onclick="addClass(this)"> Something
</div>

How to Show Div Partially and on click show it full

I want a css option for this
currently i am using this css classes
.a{
top:-102px;
height: 140px !important;
}
.b{
top:0px;
height: 240px !important;
}
but this is opening the div from top to bottom and i want it to open from bottom to top
can Anyone please help its very important
thanks in advance
You need to wrap your div in another div
Give the parent div position:relative
Give the child div position:absolute
Anchor the child div using bottom:0
Demo 1 uses minimal JavaScript:
classList.toggle()
Demo 2 uses only CSS:
<label> and <input type='checkbox'> needed for "trigger"
Demo 1 (Plain JavaScript)
var x = document.querySelector('.x');
x.addEventListener('click', function(e) {
this.classList.toggle('b');
});
.y {
position: relative;
height: 240px;
width: 50px;
background: brown;
}
.x {
position: absolute;
height: 140px;
width: 50px;
background: red;
bottom: 0;
transition: height .5s ease;
}
.b {
height: 240px;
transition: height .5s ease;
}
<div class='y'>
<div class='x'>Click the Red</div>
</div>
Demo 2 (Pure CSS)
.y {
position: relative;
height: 240px;
width: 50px;
background: brown;
}
.x {
position: absolute;
height: 140px;
width: 50px;
background: red;
bottom: 0;
transition: height .5s ease;
}
#chx {
display: none
}
#chx:checked+.y .x {
height: 240px;
transition: height .5s ease;
}
<input id='chx' type='checkbox'>
<div class='y'>
<label for='chx'>
<div class='x'>Click on the Red</div>
</label>
</div>
why don't you try something like this?
.b{
top:0px;
height: 240px !important;
display:hidden;
}
and with jquery
$('.a').click(function(){
$('.b').show('fast');
})
You can put one div inside the main div. And give it overflow: hidden;
HTML
<div class='main_div'>
<div class='overlay_div'>
</div>
</div>
CSS
.main_div{
height: 240px;
}
.overlay_div{
height: 140px;
overflow: hidden;
}
Javascript
$('.overlay_div').click(function(){
$('.overlay_div').css({'overflow': 'visible'});
});
Please check below solution. I hope this will help you.
$('.a').click(function(){
$(this).toggleClass('b');
})
.a{
position:absolute;
top:100px;
height: 50px !important;
border:1px solid red;
transition-property: all;
transition-duration: .5s;
}
.b{
top:0px;
height: 150px !important;
border:1px solid red;
transition-property: all;
transition-duration: .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a">Hello World!</div>
You can't handle click with CSS. you must add JavaScript for this.
I have made a sample code for hover
Here it's
<div class="wrapper">
<div class="face">Face</div>
<div class="back">Back</div>
</div>
And styling
.wrapper {
border: 1px solid red;
height: 100px;
width: 100px;
overflow: hidden;
}
.wrapper:hover .face {
margin-top: -100%;
}
.face, .back {
height: 100%;
transition: margin ease 0.2s;
}
.face {
background-color: yellow;
}
.back {
background-color: orange;
}
Here's the a CodePen for you:
https://codepen.io/AbuMuslim/pen/GvEwYz
You can use JS as following:
document
.querySelector('.wrapper')
.addEventListener('click', function() {
this.classList.toggle('active');
});
And instead of using hover selector, we change to .active, as following:
.wrapper.active .face {
margin-top: -100%;
}
Here's a CodePen for that: https://codepen.io/AbuMuslim/pen/QMgJVw

Categories

Resources