CSS) hover on animation - html

In a moving box,
I want to make an animation that turns upside down when I raise the mouse.
I want to implement the movement of the box with the keyframe and designate hover, but it doesn't work.
What should I do?
#www{
background-color: black;
position: absolute;
left: 0;
top: 0;
animation: www 5s infinite;
transition: 1s;
}
#www:hover{
transform: rotate(180deg);
}
#keyframes www{
0% {
transform: translateX(0vw);
}
50% {
transform: translateX(50vw);
}
100% {transform: translateX(0vw);}
}
<div class="box" id="www">WWW</div>

You can use a container to have both transformation properties as you can't achieve different transform on same element using different triggers(hover automatic)
Below styles used are for illustration only (to easily understand) you can use according to need and have a transparent background if want
function func() {
document.getElementById("www").style.transform = "rotate(180deg)"
}
#www {
background-color: black;
transition: 1s transform;
animation: www 10s infinite;
width: fit-content;
}
#keyframes www {
0% {
transform: translateX(0vw);
}
50% {
transform: translateX(50vw);
}
100% {
transform: translateX(0vw);
}
}
.box1 {
transition: 1s;
background-color: red;
margin-top: 100px;
width: fit-content;
}
.box1:hover {
transform: rotate(180deg)
}
<div class="box" id="www" onclick="func()">
<div class="box1">WWW</div>
</div>

Related

CSS hover transform on animating element

I'm trying to perform a simple CSS transform on :hover — which is obviously an easy task usually but I'm trying to do it on an animating div element. The element is infinitely animating on the Y axis with a simple CSS animation using #keyframes{}, but when I attempt to hover over the element nothing happens.
I can get it to kind of work if I use !important on the hover code, but the transform/scale happens instantly instead of using the 300ms transition property that I've applied to the .box class.
Am I missing something obvious, or is this not possible? Essentially I just want the element to scale on hover using the transition effect and timing, but then resume it's original animation when not hovered. Thanks
.box {
width: 50%;
border: solid 3px #555;
animation: box-move 1s infinite alternate-reverse;
transition: transform 300ms;
}
.box:hover {
transform: scale(1.2);
}
#keyframes box-move {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-5px);
}
}
<div class="box">I'm a box. I move up and down, but I don't scale nicely when hovered like I should :(</div>
Because you are using transform property on hover and in animation both.
Try this one.
.box {
width: 50%;
border: solid 3px #555;
animation: box-move 1s infinite alternate-reverse;
transition: transform 300ms;
}
.box:hover {
animation: box-move-anim 1s infinite alternate-reverse;
}
#keyframes box-move {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-5px);
}
}
#keyframes box-move-anim {
0% {
transform: translateY(0) scale(1);
}
100% {
transform: translateY(-5px) scale(1.2);
}
}
Consider another wrapper:
.box {
width: 50%;
animation: box-move 1s infinite alternate-reverse;
}
.box> div {
border: solid 3px #555;
transition: transform 300ms;
transform-origin:top left;
}
.box:hover > div {
transform: scale(1.2);
}
#keyframes box-move {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-5px);
}
}
<div class="box"><div>I'm a box. I move up and down, but I don't scale nicely when hovered like I should :(</div></div>
Ok, so thanks to your clever and helpful suggestions I managed to find a satisfactory solution. The key for me was using the animation-direction property set to forwards on the :hover. I can't really explain why this works but all I know that it doesn't work properly without it.
I would still ideally like the scale out (hover off) to be as smooth as the scale in (it currently just snaps back), but this will do for my needs.
Thanks again.
.box {
width: 50%;
margin: 1em auto 0 auto;
border: solid 3px #555;
cursor: pointer;
animation: box-move 1s infinite alternate-reverse;
}
.box:hover {
animation: box-move-anim 300ms 1 forwards;
}
#keyframes box-move {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-5px);
}
}
#keyframes box-move-anim {
0% {
transform: scale(1);
}
100% {
transform: scale(1.2);
}
}
<div class="box">I'm a box that animates up and down, but I now smoothly scale when hovered :)</div>

Combining #keyframes and transform scale

When I load the page the box will have infinite keyframes of animation jumpin. Now I want the box to increase its scale when I hover it, but I cant seem to work it out. When I add the "hover" code it will only work once. I added "infinite" but still it wont work. but when I removed the keyframe the scale will work just fine the way I want it to be, but I want to combine keyframe and scale together.
https://jsfiddle.net/vucocsym/1/
#tag1 {
position: absolute;
right: 50%;
bottom: 50%;
border-style: none;
background-color: #ff4d4d;
border-radius: 10px;
padding: 20px;
color: #f2f2f2;
animation: jumping 1s 1s ease infinite;
transition: 2s;
}
#tag1:hover {
transform: scale(1.3);
}
#keyframes jumping {
0% {
transform: translateY(0px)
}
50% {
transform: translateY(5px)
}
100% {
transform: translateY(0px)
}
}
<div id="tag1">
<h4>Hello there!</h4>
</div>
The property transform allows multiple functions set together, e.g.
transform: translateY(5px) scale(1.3);
However, if you want to trigger scale(1.3) only on :hover, then you need to set it on a different element, that can be either an inner or a wrapper element.
In the following example, there are three elements for center, scale and bounce.
.center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.scale {
transition: 1s;
}
.scale:hover {
transform: scale(1.3);
}
.bounce {
background-color: crimson;
color: white;
border-radius: 10px;
padding: 20px;
animation: jumping 1s 1s ease infinite;
}
#keyframes jumping {
0% {
transform: translateY(0);
}
50% {
transform: translateY(5px);
}
100% {
transform: translateY(0);
}
}
<div class="center">
<div class="scale">
<div class="bounce">Hello there, hover me!</div>
</div>
</div>

How to scale from right to left in CSS?

I'm trying to animate scale a div element. But the animation starts from the center and spreads. Is it there a way animation to start from right and spread to left?
.graybox {
float: right;
background-color: gray;
height: 100px;
width: 400px;
line-height: 100px;
-webkit-animation: main 250ms;
-moz-animation: main 250ms;
-ms-animation: main 250ms;
animation: main 250ms;
}
#-moz-keyframes main {
0% {
-moz-transform: scaleX(0);
}
100% {
-moz-transform: scaleX(1);
}
}
By default the transform-origin is 50% 50%, you can reset that to 100% 50%, the first value 100% is x-offset, and the second value 50% is y-offset.
To make the div to scale for both width and height, simply change scaleX to scale.
You also need to set the correct #keyframes syntax, -moz prefix will only work on Mozilla browsers like Firefox. I suggest to use autoprefixer for adding popular prefixes.
.graybox {
float: right;
background-color: gray;
width: 100%;
height: 100px;
line-height: 100px;
animation: main 3s;
transform-origin: 100% 50%;
}
#keyframes main {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
<div class="graybox"></div>
Use transform-origin
.graybox {
float: right;
background-color: gray;
height: 100px;
width: 400px;
line-height: 100px;
transform-origin: 100% 50%;
animation: main .5s;
}
#keyframes main {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
<div class="graybox"></div>

Fixing animation loop in CSS loader

I have a loader animation in CSS. It rotates 4 divs in a circular fashion. The issue I'm having is that the 4th div (red) is shown initially with no fade in disrupting the flow of the animation (you may have to refresh to see).
What would be the best way to fix this so that the animation's loop is improved?
The Code (https://jsfiddle.net/bduaxvmp/):
.loader {
position: relative;
height: 50px;
width: 50%;
left: 45.5%
}
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 0s infinite;
}
.loader .bullet:nth-child(1) {
animation-delay: 0.0s;
}
.loader .bullet:nth-child(2) {
animation-delay: 0.15s;
}
.loader .bullet:nth-child(3) {
animation-delay: 0.3s;
}
.loader .bullet:nth-child(4) {
animation-delay: 0.45s;
background: red;
}
#-webkit-keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
<div class="loader">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
Solution:
Set the animation-fill-mode as backwards for the animation. Using this option for the fill mode will make the elements take the state as at the 0% frame during the animation-delay period and hence all the elements will be transparent and in their translated position till the animation actually kicks in.
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 0s infinite backwards;
}
.loader {
position: relative;
height: 50px;
width: 50%;
left: 45.5%
}
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 0s infinite backwards;
}
.loader .bullet:nth-child(1) {
animation-delay: 0.0s;
}
.loader .bullet:nth-child(2) {
animation-delay: 0.15s;
}
.loader .bullet:nth-child(3) {
animation-delay: 0.3s;
}
.loader .bullet:nth-child(4) {
animation-delay: 0.45s;
background: red;
}
#-webkit-keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
#keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
<div class="loader">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
Alternately, you could set the same properties as the 0% frame to the element's default state also and avoid setting animation-fill-mode to backwards but I feel that it is a repetition that could be avoided for this case.
Reason:
The issue I'm having is that the 4th div (red) is shown initially with no fade
Note that the problem is not just the 4th div. Actually the problem is for all the div elements that have the animation delay. Visually only 4th div exhibits the problem because all are absolutely positioned and the 4th div appears on top of the rest due to it being later in the DOM.
If you set a different background color and a higher z-index to the 3rd or 2nd div, you'd see that the same problem happens for them also.
.loader {
position: relative;
height: 50px;
width: 50%;
left: 45.5%
}
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 1s infinite;
}
.loader .bullet:nth-child(1) {
animation-delay: 0.0s;
}
.loader .bullet:nth-child(2) {
animation-delay: 0.15s;
/*background: blue;
z-index: 4 */
}
.loader .bullet:nth-child(3) {
animation-delay: 0.3s;
background: yellow;
z-index: 2;
}
.loader .bullet:nth-child(4) {
animation-delay: 0.45s;
/*background: red;*/
}
#-webkit-keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
#keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
<div class="loader">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
The reason this problem happens is because of the way in which animations work. Any animation will continue to hold its default state (specified outside of the animation) till the time the delay timer expires. Setting animation-fill-mode as backwards makes the animation take the state as at first applicable frame even during the delay period and thus avoids the issue.
From MDN:
backwards
The animation will apply the values defined in the first relevant keyframe as soon as it is applied to the target, and retain this during the animation-delay period.

Spin the Wheel code - WITHOUT javascript

Looking to build something like this - a spin the wheel - using only HTML and CSS, without Javascript
http://tpstatic.com/_sotc/sites/default/files/1010/source/roulettewheel.html
http://www.dougtesting.net/winwheel
Looking for some references or even to see if it can be done.
This is using the Hover effect of spinning. Since css doesn't have event handlers, you can't add/remove classes. However, you can add hover effects:
div {
height: 100px;
width: 100px;
border-radius: 50%;
background: gray;
margin: 0 auto;
text-align: center;
}
div:hover {
-webkit-animation: spin 0.8s infinite linear;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
Hover to see effect: <div>Spin</div>
If you could use a tiny bit of javascript, you could do something like this:
$('div').click(function(){
$(this).toggleClass("thisIsAdded");
});
div {
height: 100px;
width: 100px;
border-radius: 50%;
background: gray;
margin: 0 auto;
text-align: center;
}
.thisIsAdded {
-webkit-animation: spin 0.8s infinite linear;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Click to see:<div>spin</div>
Note:
The script here is purely toggling the class 'thisIsAdded'.
As Justinas pointed out We cant fire css style on click event. You need javascript for that. However you can use CSS animation to achieve the spin effect but only with pseudo-selectors.
below is a sample spin effect using only CSS
<style type="text/css">
.content
{
float:left;cursor:pointer;
}
.content::after
{
content:'>';float:right;margin:0 0 0 10px;
-moz-transition:0.5s all;-webkit-transition:0.5s all;
}
.content:hover::after
{
-moz-transform:rotate(90deg);-webkit-transform:rotate(90deg);
}
</style>
<body>
<div class="content">Sample</div>
</body>
Here you go.. Fiddle
CSS:
.circle {
border-radius: 50%;
position: absolute;
top: 10%;
left: 10%;
width: 120px;
height: 120px;
-webkit-animation:spin 4s linear infinite;
-moz-animation:spin 4s linear infinite;
animation:spin 4s linear infinite;
background: repeating-linear-gradient(
45deg,
#606dbc,
#606dbc 10px,
#465298 10px,
#465298 20px
);
}
#-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
#-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
#keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }