Use transition with hover without it reverting to previous state - html

I have a div 'box' which rotates 90 degrees when the user hovers it.
When the user moves the mouse away the box counter rotates back to its original position.
I would like to prevent this.
I.E: When the user hover over the box it rotates and stays that way, even when he removes the mouse from the box.
Please look at for the basic setup:
.box {
height: 150px;
width: 150px;
background-color: blue;
transition: 1s all;
}
.box:hover {
transform: rotate(90deg);
}
<div class="box">
Hover me!
</div>
JSFIDDLE
What should I change in order to make it act as I want?

One way you can achieve this using animation
Like this
.box {
height: 150px;
width: 150px;
background-color: grey;
transition: 1s all;
animation: rotate .4s forwards paused;
}
.box:hover {
animation-play-state: running;
}
#keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(90deg);
}
}
<div class="box">
Hover me!
</div>
Or
You can use js. Like this
$(document).ready(function() {
$(".box").mouseover(function(e) {
$(this).css("transform","rotate(90deg)");
});
});
.box {
height: 150px;
width: 150px;
background-color: grey;
transition: 1s all;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
Hover me!
</div>

Related

keyframe animation not playing after clicking link

I have a full screen drop down menu that goes up and down the screen when the user interacts with the menu button. I didn't like that the full screen menu animates when the page loads so I set the opacity of the menu to 0 so that you wouldn't see the animation when the page loads. I created an onclick event that sets the opacity to 1 when the user clicks on the menu. that solved the issue of seeing the animation when the user loads the index page. here's the code for how I did it:
HTML
<div class="menu">
<input type="checkbox" class="toggler" onclick="document.getElementById('overlay').style.opacity='1'">
<div class="icon">
<div></div>
</div>
<div class="overlay" id="overlay">
<nav>
<div id="nav-links"></div>
</nav>
</div>
</div>
CSS
#keyframes slideDown {
0% {
transform: translateY(-100%)
}
100% {
transform: translateY(0%)
}
}
#keyframes slideUp {
0% {
transform: translateY(0%)
}
100% {
transform: translateY(-100%);
}
}
.overlay {
position: fixed;
background: var(--taupe-color);
opacity: 0;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.menu .toggler:checked ~ .overlay {
animation: slideDown 2s forwards;
}
.menu .toggler:not(:checked) ~ .overlay {
animation: slideUp 2s forwards;
}
The only issue now is that when the user clicks on a link to navigate to another page from the menu, the menu no longer animates up. My guess is that on page load, the opacity over the overlay menu is set back to 0 so we can't see the animation actually happening on the other pages. My only idea to fix this is to duplicate the overlay class for the other pages and give it a different name but set the opacity to 1. I'm wondering if there is a better solution than the one I came up with. Ideally, the animation only happens when a link is clicked in the menu or when the menu button is toggled.
EDIT
is there a way to have the menu animate only when the user clicks the menu button or clicks one of the nav links in the menu?
I would suggest maybe adding a class to turn the opacity to 1 upon clicking?
I'm not sure if this is what you are looking for, but here is Codepen that I believe does what you're looking for:
#keyframes slideDown {
0% {
transform: translateY(-100%)
}
100% {
transform: translateY(0%)
}
}
#keyframes slideUp {
0% {
transform: translateY(0%)
}
100% {
transform: translateY(-100%);
}
}
.overlay {
position: fixed;
background: var(--taupe-color);
opacity: 0;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.active {
opacity:1;
}
.menu .toggler:checked ~ .overlay {
animation: slideDown 2s forwards;
}
.menu .toggler:not(:checked) ~ .overlay {
animation: slideUp 2s forwards;
}
<div class="menu">
<input type="checkbox" class="toggler" onclick="document.getElementById('overlay').classList.add('active')">
<div class="icon">
<div></div>
</div>
<div class="overlay" id="overlay">
<nav>
<div id="nav-links"></div>
TESTTTTTTTTTTTT
</nav>
</div>
</div>

CSS Zoom into specific image point

I have an image which I need to zoom a specific point depending on which input is focused
Here's a fiddle so far
I used the attributes transform and transform-origin. It's working fine on Firefox (notice how it's moving toward the point while zooming at same time).
However on Chrome, the scale/zoom is done first, then it teleports the point. It's actually very confusing
Any idea how to make this work on Chrome ?
I experimented with putting both the transform and the transform-origin into a CSS animation and it seemed to manage to do them both at once, so avoiding the 2 step problem you saw on Chrome (tested on Edge):
#keyframes focusin {
0% {
transform: scale(1);
transform-origin: 0% 0%;
}
100% {
transform: scale(3);
transform-origin: 25% 75%;
}
}
Here's a snippet. I've put the animation time to 10s so you can see the 'journey' the paper takes when focus is on input1. It seems to be smooth, so a bit of an improvement, but it isn't 'direct' on Edge/Chrome which I guess (and it is only a guess) is to do with how the browser animates (or doesn't) transform-origin.
$("#input1").focus(function(e) {
/* $("#image").css({
"transform": "scale(3)",
"transform-origin": "25% 75%"
});*/
document.getElementById('image').style.animationName = 'focusin';
});
$("#input2").focus(function(e) {
$("#image").css({
"transform": "scale(3)",
"transform-origin": "75% 25%"
});
});
$("#input1, #input2").focusout(function(e) {
$("#image").css({
"transform": "scale(1)"
});
});
#wrapper {
width: 400px;
height: 267px;
border: 1px solid black;
overflow: hidden;
position: relative;
}
#image {
background-image: url('http://i.imgur.com/n9q7jhm.jpg');
background-size: 400px 267px;
background-position: center;
/* transition: all 1s ease; */
width: 100%;
height: 100%;
/* transform: scale(1); */
position: relative;
left: 0;
top: 0;
animation-duration: 10s;
animation-iteration-count: 1;
animation-name: none;
animation-fill-mode: forwards;
}
#keyframes focusin {
0% {
transform-origin: 0% 0%;
transform: scale(1);
}
100% {
transform-origin: 25% 75%;
transform: scale(3);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="input1">
<input type="text" id="input2">
<div id='wrapper'>
<div id='image'></div>
</div>

CSS sliding div on button click

I have designed a div more less like floating action buttons: on a button click a strip slides from left to right but I can not style it properly with my knowledge of css.
<div class="progress mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet">
<button style="float: left;" mdl-button mdl-button-type="mini-fab" (click)="toggleSliding()">
<mdl-icon>check_circle</mdl-icon>
</button>
<div *ngIf="showProgress" class="progress-sliding">TEST</div>
</div>
And my current css:
.progress{
height: 5vh;
}
.progress-sliding{
position: relative;
background-color: #F5F5F5;
height: 6vh;
display: -webkit-box;
border-top-right-radius: 2em;
border-bottom-right-radius: 2em;
left: -1500px;
-webkit-animation: slide 0.6s forwards;
-webkit-animation-delay: 0s;
animation: slide 0.6s forwards;
animation-delay: 0s;
}
#-webkit-keyframes slide {
100% { left: 0; }
}
#keyframes slide {
100% { left: 0; }
}
There are couple of issues:
I have fixed the right border radius but it looks ugly on left side
The div slides from behind the screen on left which looks ugly and how can I make it slide from smoothly from the FAB button itself?
Plunkr: https://plnkr.co/edit/fhFoEqbiXt2cEVQOzzJP?p=preview

CSS3, HTML slow animation 'train'

Please help me to resolve animation issue, here is a link and code:
https://fiddle.jshell.net/gvopk1qe/37/
Description of issue:
This 'train' is infinity but after once the yellow rectange is covered by blue rectangle. You see yellow, black, red, blue rectangle and then should be yellow again, black, red and blue but yellow is covered by blue.
Please help me to resolve this.
Thanks.
Exact problem : animation-delay property is used. It will delay by assigned time before starting animation each time. Therefore, first cycle is good but second cycle onward everything breaks.
Suggested Fix
I would say don't use animation-delay property instead arrange the div's so that they are next to each other and then animate them.
Example Snippet:
/* steps animation */
.steps-animation {
position: relative;
width: 1200px;
height: 250px;
float: left;
background: lightgrey;
border: 1px solid black;
overflow: hidden;
}
.steps-animation span {
display: inline-block;
position: relative;
top: 32%;
left: -100%;
width: 160px;
height: 80px;
margin-left: 100px;
-webkit-animation: stepmoveone 6s linear infinite;
animation: stepmoveone 6s linear infinite;
}
.steps-animation .step1 {
background: yellow;
}
.steps-animation .step2 {
background: black;
}
.steps-animation .step3 {
background: red;
}
.steps-animation .step4 {
background: blue;
}
#keyframes stepmoveone {
to {
left: 100%;
}
}
<div class="steps-animation">
<span class="step1"></span>
<span class="step2"></span>
<span class="step3"></span>
<span class="step4"></span>
</div>
**Need to edit margin-left, height and width as per requirement.
The problem is in timming. I haven't worked too much with animations but I think I know what's the problem. The animation has a loop set on this line
animation: stepmoveone Xs linear infinite;
This will initially wait X seconds but will also show the animation in an X seconds interval. So it will take X seconds for the animation to complete.
In your code you set X to 18 seconds but this is the same time the last div (the blue one) will wait to be animated. So it will be animated exactly when a new cycle of the animation begins. But when this happens the yellow div will show up so the two of them will overlap. You can check this by changing the delay time for the yellow div to 1s.
To fix this you can change the animation time to 24 for example.
Here's the code but with the seconds changed:
/* steps animation */
.steps-animation {
position: relative;
width: 800px;
height: 250px;
float: left;
background: lightgrey;
border: 1px solid black;
overflow: hidden;
}
.steps-animation span {
display: block;
position: absolute;
top: 32%;
left: -100%;
width: 160px;
height: 80px;
-webkit-animation: stepmoveone 8s linear infinite;
animation: stepmoveone 8s linear infinite;
}
.steps-animation .step1 {
animation-delay: 0s;
background: yellow;
}
.steps-animation .step2 {
animation-delay: 2s;
background: black;
}
.steps-animation .step3 {
animation-delay: 4s;
background: red;
}
.steps-animation .step4 {
animation-delay: 6s;
background: blue;
}
#keyframes stepmoveone {
to {
left: 100%;
}
}
<div class="steps-animation">
<span class="step1"></span>
<span class="step2"></span>
<span class="step3"></span>
<span class="step4"></span>
</div>
This code will leave a 2 seconds gap between each element.
Set .steps-animation width to 100% && .steps-animation span to negative of its width to hide from the frame
Check the fiddle

Partial change on parent hover, full change on element hover

I'd like to have a UI element fade in slightly when hovering on its parent div, then fade in completely when hovering on the UI element itself. But it seems that if I set the parent hover, hovering on the child doesn't do anything.
HTML:
<div id="parent">
<div id="child">
</div> <!-- end child -->
</div> <!-- end parent -->
CSS:
#parent {
width: 200px;
height: 200px;
background-color: black;
}
#child {
width: 100px;
height: 100px;
background-color: white;
opacity: 0.3;
}
/* fades in partially, looks nice */
#parent:hover #child {
opacity: 0.6;
}
/* doesn't seem to do anything! */
#child:hover {
opacity: 1;
}
JSFiddle version
The problem is that the rule #parent:hover #child has higher priority than #child:hover because it describes more elements in the DOM tree.
For increasing the priority of #child:hover there are two ways:
Describe it more precisely with
#parent #child:hover
Add !important to opacity: 1:
opacity: 1 !important;
Fiddle
#parent {
width: 200px;
height: 200px;
background-color: black;
}
#child {
width: 100px;
height: 100px;
background-color: white;
opacity: 0.3;
}
#parent:hover #child {
opacity: 0.6;
}
#parent #child:hover {
opacity: 1;
}
<div id="parent">
<div id="child">
</div> <!-- end child -->
</div> <!-- end parent -->
PS: You might also want to add a transition.
It's a specificity issue. The #parent:hover #child selector is "winning out" over #child:hover. Change the second to #parent:hover #child:hover (or just #parent #child:hover), and you should be set. https://jsfiddle.net/1khjo42q/1/
Add transitions
#child {
width: 100px;
height: 100px;
background-color: white;
opacity: 0.3;
/* added these */
-webkit-transition: background-color 500ms ease-out 1s;
-moz-transition: background-color 500ms ease-out 1s;
-o-transition: background-color 500ms ease-out 1s;
transition: background-color 500ms ease-out 1s;
}