Simple rotating hover effect wont work - css

I am trying to create a simple effect so that when I hover on the inner most circle, the two outer rings rotate around to create a cool effect. I thought this would be an easy task but I cannot seem to figure out what I am doing wrong. When I hover over the inner circle, all that changes are the two inner rings move towards the bottom right hand corner of the screen, without rotating at all. What am I missing here? Thanks
.wrapper {
position: relative;
width: 400px;
height: 400px;
margin: auto auto;
background: black;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: grey;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle-1 {
width: 108px;
height: 108px;
border-radius: 50%;
background-color: transparent;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 2px;
border-style: solid;
border-color: white white white transparent;
transition: 1.5s all ease-in-out;
}
.circle-2 {
width: 118px;
height: 118px;
border-radius: 50%;
background-color: transparent;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 2px;
border-style: solid;
border-color: white transparent white white;
transition: 1.5s all ease-in-out;
}
.circle:hover .circle-2 {
transform: rotate(360deg);
}
.circle:hover .circle-1 {
transform: rotate(-360deg);
}
<div class="wrapper">
<div class="circle">
<div class="circle-1"></div>
<div class="circle-2"></div>
</div>
</div>

You are using transform with translation in order to center your element then you are overriding the transform with the rotation which create the issue. Instead you can adjust the top/left values in order to center and avoid using transform then you will have the needed rotation:
.wrapper {
position: relative;
width: 400px;
height: 400px;
margin: auto auto;
background: black;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: grey;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle-1 {
width: 108px;
height: 108px;
border-radius: 50%;
background-color: transparent;
position: absolute;
top: calc(50% - 55px);
left: calc(50% - 55px);
border: 2px;
border-style: solid;
border-color: white white white transparent;
transition: 1.5s all ease-in-out;
}
.circle-2 {
width: 118px;
height: 118px;
border-radius: 50%;
background-color: transparent;
position: absolute;
top: calc(50% - 60px);
left:calc(50% - 60px);
border: 2px;
border-style: solid;
border-color: white transparent white white;
transition: 1.5s all ease-in-out;
}
.circle:hover .circle-2 {
transform: rotate(360deg);
}
.circle:hover .circle-1 {
transform: rotate(-360deg);
}
<div class="wrapper">
<div class="circle">
<div class="circle-1"></div>
<div class="circle-2"></div>
</div>
</div>
You can also simplify your code by using pseudo elements like this:
* {
box-sizing:border-box;
}
.wrapper {
position: relative;
width: 400px;
height: 400px;
margin: auto;
background: black;
}
.circle {
width: 120px;
height: 120px;
border-radius: 50%;
background:radial-gradient(circle at center, grey 50px,transparent 51px);
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle:before,
.circle:after {
content:"";
border-radius: 50%;
position: absolute;
transition: 1.5s all ease-in-out;
border: 2px solid white;
}
.circle:before {
top:0;
left:0;
right:0;
bottom:0;
border-left-color:transparent;
}
.circle:after{
top:5px;
left:5px;
bottom:5px;
right:5px;
border-right-color:transparent;
}
.circle:hover::before {
transform: rotate(360deg);
}
.circle:hover::after {
transform: rotate(-360deg);
}
<div class="wrapper">
<div class="circle">
</div>
</div>

Setting the transform property in the :hover will overwrite the existing transform property, so you need to include the translate transforms in the :hover versions to avoid moving the circles in the process of setting their rotation.
If you want the rotation to animate you'll also need to set initial values for the rotation transform.
One additional note: using transition, the rotation will only happen once. If you want repeated rotations you'll need to use an animation (you can do this by uncommenting the animation lines in the snippet).
Demo:
.wrapper {
position: relative;
width: 400px;
height: 200px;
margin: auto auto;
background: black;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: grey;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle-1 {
width: 108px;
height: 108px;
border-radius: 50%;
background-color: transparent;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
border: 2px;
border-style: solid;
border-color: white white white transparent;
transition: 1.5s all ease-in-out;
}
.circle-2 {
width: 118px;
height: 118px;
border-radius: 50%;
background-color: transparent;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
border: 2px;
border-style: solid;
border-color: white transparent white white;
transition: 1.5s all ease-in-out;
}
.circle:hover .circle-2 {
/*animation: spin 1.5s infinite linear;*/
transform: translate(-50%, -50%) rotate(360deg);
}
.circle:hover .circle-1 {
/*animation: spin 1.5s infinite linear reverse;*/
transform: translate(-50%, -50%) rotate(-360deg);
}
#keyframes spin {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
<div class="wrapper">
<div class="circle">
<div class="circle-1"></div>
<div class="circle-2"></div>
</div>
</div>

Related

Trying to fill an image with color and making it go down with css

I'm trying to fill this nos bottle then slowly empty it up with css so first the "fill" goes up then slowly slowly drains down, I tried but came with a very terrible result
#bottle, #fill {
position: fixed;
top: 50%;
left: 50%;
}
.box {
width: 96px;
height: 195px;
border-radius: 10px;
text-align: center;
color: #ddd;
font-size: 25px;
font-weight: 600;
position: relative;
overflow: hidden;
top: 50%;
left: 50%;
}
.box:before {
content: "";
position: absolute;
width: 400px;
height: 400px;
background: #00acee;
left: 50%;
transform: translateX(-50%);
border-radius: 40%;
animation: fill 1s cubic-bezier(0, 1.62, 0.27, -0.67) infinite;
z-index: -1;
}
#keyframes fill {
from {
top: 250px;
transform: translateX(-50%) rotate(0deg);
}
to {
top: -50px;
transform: translateX(-50%) rotate(360deg);
}
}
<div class="box">
<img id="bottle" src="https://cdn.discordapp.com/attachments/350561379234873354/813833593084313650/bottle.png" width=100 height=200>
</div>
If anyone could point how can i achieve this would be awesome.
You can try something like that, but you should consider just left backgroung transparent inside bottom image, outside put a solid color, like black.
#bottle, #fill {
top: 50%;
left: 50%;
}
.box {
width: 96px;
height: 195px;
border-radius: 10px;
text-align: center;
color: #ddd;
font-size: 25px;
font-weight: 600;
position: relative;
overflow: hidden;
top: 50%;
left: 50%;
}
.box:before {
content: "";
position: absolute;
width: 400px;
height: 400px;
background: #00acee;
left: 50%;
transform: translateX(-50%);
border-radius: 40%;
animation: fill 7s cubic-bezier(1, 2.7, 1, -1.7) infinite;
z-index: -1;
}
#keyframes fill {
from {
top: 450px;
transform: translateX(-50%) rotate(0deg);
}
to {
top: -50px;
transform: translateX(-50%) rotate(360deg);
}
}
<div class="box">
<img id="bottle" src="https://cdn.discordapp.com/attachments/350561379234873354/813833593084313650/bottle.png" width=100 height=200>
</div>
I'm not absolutely sure what effect you want, but one thing to notice is that you can have the filling and the emptying all in the same animation, without necessarily needing to involve a cubic Bezier function, which in this case seemed to partly fill the bottle, then empty then partly fill but to a different level.
Simplifying things but introducing more detail into the keyframes here's an example of the bottle filling much faster than it empties, by having the percentage of the animation used for filling as much smaller than the emptying.
There are of course many variations on this which can be achieved by having the percentages differ. Also you could reintroduce a cubic Bezier to make the movement less uniform, but that's for your experimentation as I don't know exactly what final effect is wanted.
<head>
<style>
#bottle, #fill {
/* position: fixed; NOTE. had to change this position fixed to absolute get it to line up on Stack Overflow. Outside SO it was fine as fixed */
position: absolute;
top: 50%;
transform: translateY(-50%);
left: calc(50% - 50px);
}
.box {
width: 96px;
height: 195px;
border-radius: 10px;
text-align: center;
color: #ddd;
font-size: 25px;
font-weight: 600;
position: relative;
overflow: hidden;
top: 50%;
left: 50%;
}
.box:before {
content: "";
position: absolute;
width: 400px;
height: 400px;
background: #00acee;
left: 50%;
transform: translateX(-50%);
border-radius: 40%;
/* animation: fill 20s cubic-bezier(0, 1.62, 0.27, -0.67) infinite; */
animation: fill 20s linear infinite;
z-index: -1;
animation-fill-mode: forwards; /* added */
}
#keyframes fill {
0% {
top: 250px;
transform: translateX(-50%) rotate(0deg);
}
10% {
top: -50px;
top: 75px;
transform: translateX(-50%) rotate(360deg);
}
20% {
top: 75px;
transform: translateX(-50%) rotate(0deg);
}
22% {
top: 75px;
transform: translateX(-50%) rotate(0deg);
}
80% {
transform: translateX(-50%) rotate(360deg);
}
100% {
top: 250px;
transform: translateX(-50%) rotate(0deg);
}
}
</style>
</head>
<body>
<div class="box">
<img id="bottle" src="https://cdn.discordapp.com/attachments/350561379234873354/813833593084313650/bottle.png" width=100 height=200>
</div>
</body>
Note: in the SO snippet system the position fixed had the effect of separating the blob (liquid) from the bottle - it was fine when the code was just run as it was outside the SO system. To demo it here I have made the bottle position absolute and centered the bottle and blob, just so you can get an idea while here. You can remove the absolute and go back to fixed outside SO.

Animating superposed elements with CSS Animations

Hi StackOverflow community,
I am trying to produce an "Orbit" on-hover animation, where a number of div elements are stacked on top of one another and they have different sizes so I can play with the borders circling around the "planet" (ie: main element).
My problem though is that it seems like when I stack one div over another and both are supposed to be animated, only the front element plays the animation and not those under.
I thought a z-index property could fix this, but as I thought about this I just thought I'd be switching one animation for the other, since the one I'd elevate with the z-index would then become the front and cover the one element that's now below.
Here's some code:
#spinner {
position: relative;
display: inline-block;
margin: 50px;
width: 100px;
height: 100px;
background: #eee;
border-radius: 50%;
}
/* -- -- -- Spin Animation -- -- -- */
#spinner-1 {
position: absolute;
top: -4px;
left: -4px;
width: 100px;
height: 100px;
border-radius: 50%;
border: 4px solid transparent;
border-top-color: black;
border-bottom-color: black;
}
#spinner-1:hover {
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg) scale(1);
}
50% {
transform: rotate(180deg) scale(1.2);
}
100% {
transform: rotate(360deg) scale(1);
}
}
/* -- -- -- Orbit Ring -- -- -- */
#spinner-4 {
position: absolute;
top: -8px;
left: -8px;
width: 110px;
height: 110px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #333;
border-bottom-color: #333;
border-left-color: #333;
}
#spinner-4:hover {
animation: spin-2 2s linear infinite;
}
#keyframes spin-2 {
0% {
transform: rotate(0deg) scale(1);
}
50% {
transform: rotate(-180deg) scale(1.3);
}
100% {
transform: rotate(-360deg) scale(1);
}
}
}
<div id="spinner">
<div id="spinner-1"></div>
<div id="spinner-4"></div>
</div>
So, basically I want both spinner-1 and spinner-4 to execute their animation when I hover over the spinner. Any ideas?
Set the hover on their shared parent element.
#spinner {
position: relative;
display: inline-block;
margin: 50px;
width: 100px;
height: 100px;
background: #eee;
border-radius: 50%;
}
/* -- -- -- Spin Animation -- -- -- */
#spinner-1 {
position: absolute;
top: -4px;
left: -4px;
width: 100px;
height: 100px;
border-radius: 50%;
border: 4px solid transparent;
border-top-color: black;
border-bottom-color: black;
}
#spinner:hover #spinner-1 {
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg) scale(1);
}
50% {
transform: rotate(180deg) scale(1.2);
}
100% {
transform: rotate(360deg) scale(1);
}
}
/* -- -- -- Orbit Ring -- -- -- */
#spinner-4 {
position: absolute;
top: -8px;
left: -8px;
width: 110px;
height: 110px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #333;
border-bottom-color: #333;
border-left-color: #333;
}
#spinner:hover #spinner-4 {
animation: spin-2 2s linear infinite;
}
#keyframes spin-2 {
0% {
transform: rotate(0deg) scale(1);
}
50% {
transform: rotate(-180deg) scale(1.3);
}
100% {
transform: rotate(-360deg) scale(1);
}
}
}
<div id="spinner">
<div id="spinner-1"></div>
<div id="spinner-4"></div>
</div>

CSS on hover out text disappears instead of sliding out like image

Can someone explain why does the image slide back nicely and the text disappears right away when you hover out?
.wrapper {
position: relative;
overflow: hidden;
width: 100px;
height: 100px;
border: 1px solid black;
}
#image {
position: absolute;
left: 0;
width: 100px;
height: 100px;
background: blue;
transition: 1s;
}
.wrapper:hover #image {
transition: 1s;
left: -100px;
}
.wrapper:hover .text {
transition: 1s;
left: 50%;
}
.text {
white-space: nowrap;
//color: black;
font-size: 20px;
position: absolute;
overflow: hidden;
top: 50%;
left: 150%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
<div class="wrapper">
<img id="image" src="http://lorempixel.com/output/cats-q-c-100-100-4.jpg" />
<div class="text">text</div>
</div>
So what I want is that the text also slides out nicely on hover out and not just disappear.
You also need to add the transition property to the .text:
.wrapper {
position: relative;
overflow: hidden;
width: 100px;
height: 100px;
border: 1px solid black;
}
#image {
position: absolute;
left: 0;
width: 100px;
height: 100px;
background: blue;
transition: 1s;
}
.wrapper:hover #image {
transition: 1s;
left: -100px;
}
.wrapper:hover .text {
transition: 1s;
left: 50%;
}
.text {
white-space: nowrap;
//color: black;
font-size: 20px;
position: absolute;
overflow: hidden;
top: 50%;
left: 150%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transition: 1s;
}
<div class="wrapper">
<img id="image" src="http://lorempixel.com/output/cats-q-c-100-100-4.jpg" alt="">
<div class="text">text</div>
</div>

Creating a 3d box effect, face keeps appearing over the other

How can I achieve the desired effect? I want to create a kind of box that flips around in 3d in the x axis and reveals the other face, all while conserving the same dimensions. Currently the effect is almost working but for some reason one face is always visible. Why does that happen and how to change that?
#div1 {
width: 100px;
height: 100px;
position: relative;
margin: 100px;
perspective: 300px;
perspective-origin: 50% 50%;
transition: all 1s;
}
#div2 {
width: 100px;
height: 100px;
position: absolute;
border: 1px solid black;
background-color: red;
transform-origin: 50% 50% -50px;
transition: all 1s;
}
#div3 {
width: 100px;
height: 100px;
position: absolute;
border: 1px solid black;
background-color: orange;
transform-origin: 50% 50% -50px;
transform: rotateX(90deg);
transition: all 1s;
}
#div1:hover {
//transform: rotate(180deg)
}
#div1:hover #div2 {
transform: rotateX(-90deg);
}
#div1:hover #div3 {
transform: rotateX(0deg);
}
hover me!
<div id="div1">
<div id="div2"></div>
<div id="div3"></div>
</div>
Just add this css properties,
#div2 { z-index: 1;}
#div1:hover #div2 { z-index: 0;}
#div1 {
width: 100px;
height: 100px;
position: relative;
margin: 100px;
perspective: 300px;
perspective-origin: 50% 50%;
transition: all 1s;
}
#div2 {
z-index: 1;
width: 100px;
height: 100px;
position: absolute;
border: 1px solid black;
background-color: red;
transform-origin: 50% 50% -50px;
transition: all 1s;
}
#div3 {
width: 100px;
height: 100px;
position: absolute;
border: 1px solid black;
background-color: orange;
transform-origin: 50% 50% -50px;
transform: rotateX(90deg);
transition: all 1s;
}
#div1:hover {
//transform: rotate(180deg)
}
#div1:hover #div2 {
transform: rotateX(-90deg);
z-index: 0;
}
#div1:hover #div3 {
transform: rotateX(0deg);
}
hover me!
<div id="div1">
<div id="div2"></div>
<div id="div3"></div>
</div>
Add backface-visibility:hidden;
div {
backface-visibility: hidden;
}
#div1 {
width: 100px;
height: 100px;
position: relative;
margin: 100px;
perspective: 300px;
perspective-origin: 50% 50%;
transition: all 1s;
}
#div2 {
width: 100px;
height: 100px;
position: absolute;
border: 1px solid black;
background-color: red;
transform-origin: 50% 50% -50px;
transition: all 1s;
}
#div3 {
width: 100px;
height: 100px;
position: absolute;
border: 1px solid black;
background-color: orange;
transform-origin: 50% 50% -50px;
transform: rotateX(90deg);
transition: all 1s;
}
#div1:hover {
//transform: rotate(180deg)
}
#div1:hover #div2 {
transform: rotateX(-90deg);
}
#div1:hover #div3 {
transform: rotateX(0deg);
}
<div id="div1">
<div id="div2"></div>
<div id="div3"></div>
</div>

Make a lines orbiting around circle div

i am trying to create animation that a few lines are rotating around circle div.
Something like this
http://prntscr.com/dxoe8o
this is my html & css
.outCircle {
width: 20px;
height: 20px;
background-color: lightblue;
left: 270px;
position: absolute;
top: 50px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
border-radius: 100px;
}
.duringTen {
-webkit-animation-duration: 5s;
}
.infinite {
-webkit-animation-iteration-count: infinite;
}
.linear {
-webkit-animation-timing-function: linear;
}
.counter {
width: 30px;
height: 30px;
-webkit-animation-duration: inherit;
-webkit-animation-direction: reverse;
-webkit-animation-timing-function: inherit;
-webkit-animation-iteration-count: inherit;
-webkit-animation-name: inherit;
}
.rotate {
width: 100%;
height: 100%;
-webkit-animation-name: circle;
position: relative;
z-index: 10;
display: block;
}
.inner {
width: 20px;
height: 2px;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 100px;
position: absolute;
left: 0px;
top: 5px;
background-color: red;
display: block;
}
.red {
background: red;
}
.green {
background: green;
}
#keyframes circle {
from {
-webkit-transform: rotateZ(0deg)
}
to {
-webkit-transform: rotateZ(360deg)
}
}
<div class="outCircle">
<div class="rotate linear infinite duringTen">
<div class="counter">
<div class="inner">
</div>
</div>
</div>
</div>
My try is only with one line but i would like to create a few more lines like on the picture i posted above.
This is as far as i have come
Perhaps something like this:
.outCircle {
width: 20px;
height: 20px;
background-color: lightblue;
position: relative;
border-radius: 50%;
margin: 100px auto;
}
.marker {
width: 50px;
height: 2px;
position: absolute;
top: 50%;
left: 50%;
background: linear-gradient(to right, black, black 25%, transparent 25%, transparent 75%, black 75%);
transform: translate(-50%, -50%);
}
.vert {
width: 2px;
height: 50px;
background: linear-gradient(to bottom, black, black 25%, transparent 25%, transparent 75%, red 75%);
transform: translate(-50%, -50%);
}
.angle-1 {
transform: translate(-50%, -50%) rotate(45deg);
}
.angle-2 {
transform: translate(-50%, -50%) rotate(-45deg);
}
.inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
animation: circle 3s linear infinite;
}
#keyframes circle {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
<div class="outCircle">
<div class="inner">
<div class="marker horiz"></div>
<div class="marker vert"></div>
<div class="marker angle-1"></div>
<div class="marker angle-2"></div>
</div>
</div>
Note, this is quick and dirty...with a little time it could be simplified, perhaps by using pseudo-elements for some of the markers.
In general though, a SVG might be better.

Resources