Using :hover to trigger #keyframes animation when the element uses multiple animations - css

I have a set of icons that transition from the center of the page to a set point, and then remain there. What I want to do is set them to transition to have a thicker border and scale to 130x130px whenever I mouse over one of them, but only the initial animation occurs
CSS:
.iconborder {
border-width: 5px;
border-style: solid;
border-radius: 100em;
border-color: white;
}
.iconborder:hover {animation-name: icongrow; animation-duration: 0.2s; animation-timing-function: cubic-bezier;}
#keyframes icongrow {
0% {
border-width: 5px;
width: 100px;
height: 100px;
}
100% {
border-width: 10px;
width: 130px;
height: 130px;
}
}
#FTPSlideOut
{
position: fixed;
width: 100px;
height: 100px;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
z-index: 6;
visibility: hidden;
animation-name: FTPSlideOut;
animation-duration: 0.4s;
animation-timing-function: cubic-bezier;
animation-delay: 1s;
animation-fill-mode: forwards;
}
#keyframes FTPSlideOut {
0% {
transform: translate(0px, 0px);
visibility: visible;
}
100% {
transform: translate(-300px, -150px);
visibility: visible;
}
}
And HTML:
<body style="background-color:#D4D4D4;height:100%;width:100%">
<img id="SlideUp" class="dropshadow" src="picCenterDotFinalwText.png">
<img id="FTPSlideOut" class="dropshadow iconborder" src="FTP.png">
<img id="PicturesSlideOut" class="dropshadow iconborder" src="Pictures.png">
<img id="VideosSlideOut" class="dropshadow iconborder" src="Videos.png">
<img id="MusicSlideOut" class="dropshadow iconborder" src="Music.png">
<img id="DocumentsSlideOut" class="dropshadow iconborder" src="Documents.png">
<img id="EmailSlideOut" class="dropshadow iconborder" src="Email.png">
</body>
Any clues?

Im not sure why are you using keyframes for just a simple hover animation.
You can use css3 transitions just for that animation
see demo
#-webkit-keyframes icongrow {
0%{
border-width: 5px;
width: 100px;
height: 100px;
}
100% {
border-width: 10px;
width: 130px;
height: 130px;
border-color:#ccc;
}
}
.iconborder{
text-align:center;
border: solid 5px #fff; /* use shorthand */
border-radius: 100em;
/* customize */
-webkit-transition : border 0.2s linear;
/*-webkit-animation-duration: 0.2s;*/
}
.iconborder:hover{
border: 10px solid #fff;
width: 130px;
height: 130px;
cursor:pointer;
/* -webkit-animation-name: icongrow;
-webkit-animation-fill-mode: forwards;*/
}
#-webkit-keyframes FTPSlideOutAnimate {
0%{
opacity:0;
-webkit-transform: translate(0,0);
}
100% {
opacity:1;
-webkit-transform: translate(-300px, -150px);
}
}
#FTPSlideOut{
position: fixed;
width: 100px;
height: 100px;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
z-index: 6;
/* customize */
opacity:0.1;
-webkit-transition: -webkit-transform 1s ease-in,
opacity 0.5s linear;
}
#FTPSlideOut:hover{
-webkit-transform: translate(-300px, -150px);
opacity:1;
/*-webkit-animation: FTPSlideOutAnimate 0.2s linear;
-webkit-animation-fill-mode: forwards; */
}
http://jsfiddle.net/phcba/2/
in that fiddle you can uncomment the keyframes properties just to check and see how bad the animation it was when using Keyframes if not done right for your hover effect
Also im not sure how the #FTPSlideOut is position and displayed on your site, so I made it barely visible in that demo. Ive used Opacity instead of visibilty, you'll need to modify it in your case.
For more info about CSS3 transtions:
http://css-tricks.com/almanac/properties/t/transition/
cheers

Just put your animation in the class pseudo selector with the hover in it? like this
.clickMes {
color: white;
font-size: 17pt;
text-decoration: none;
}
.clickMes:active {
color: cyan;
}
.clickMes:hover {
animation: clickmes 1.3s infinite;
}
#keyframes clickmes {
0% {
background-color: none;
}
50% {
background-color: cyan;
}
100% {
background-color: none;
}
}

Related

CSS - Animation scale with border-radius

I'm working on a animation with scaling a box and it is rounded with 8px. Ref: https://codepen.io/anon/pen/ePGxqy. However, the rounded angle is weird when the box expanded and I don't want to scale it by changing its width in keyframes. How can I correctly scale a rounded box with a rounded border?
#box {
position: relative;
width: 55px;
height: 55px;
background: #aaa;
margin: 0 auto;
border-radius: 8px;
animation-name: singleRevert;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#box:hover {
animation-name: singleExpend;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#keyframes singleRevert {
0% {
transform: scaleX(7.5) scaleY(0.46)
}
50% {
transform: scaleX(1) scaleY(0.46)
}
100% {
transform: scaleX(1) scaleY(1)
}
}
#keyframes singleExpend {
0% {
transform: scaleX(1) scaleY(1)
}
50% {
transform: scaleX(1) scaleY(0.46)
}
100% {
transform: scaleX(7.5) scaleY(0.46)
}
}
<div id="box"></div>
Basically you need to animate your border radius to match the scale of your box.
For simplicity's sake if your box radius is 8px and you scale your box by 8 times your border radius should be 1px at the scaled size. If your box is 0.5 scaled the border would be 16px;
Alternatively you could animate the width and height of the box. This would respect the borders and you would not have to change them in this case.
Updated your version:
#box {
position: relative;
width: 55px;
height: 55px;
background: #aaa;
margin: 0 auto;
border-radius: 8px;
animation-name: singleRevert;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#box:hover {
animation-name: singleExpend;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#keyframes singleRevert {
0% {
transform: scaleX(8) scaleY(0.5);
border-radius: 1px;
}
50% {
transform: scaleX(1) scaleY(0.5)
border-radius: 8px;
}
100% {
transform: scaleX(1) scaleY(1)
border-radius: 8px;
}
}
#keyframes singleExpend {
0% {
transform: scaleX(1) scaleY(1)
border-radius: 8px;
}
50% {
transform: scaleX(1) scaleY(0.5)
border-radius: 8px;
}
100% {
transform: scaleX(8) scaleY(0.5)
border-radius: 1px;
}
}
<div id="box"></div>
Simple version:
#box {
position: relative;
width: 55px;
height: 55px;
background: #aaa;
margin: 0 auto;
border-radius: 8px;
animation-name: singleRevert;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#box:hover {
animation-name: singleExpend;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#keyframes singleRevert {
0% {
width: 400px;
height: 40px;
}
50% {
width: 55px;
height: 40px;
}
100% {
width: 55px;
height: 55px;
}
}
#keyframes singleExpend {
0% {
width: 55px;
height: 55px;
}
50% {
width: 55px;
height: 40px;
}
100% {
width: 400px;
height: 40px;
}
}
<div id="box"></div>
The problem with animating it by using transform is that you are stretching the element. So whatever border-radius you have it set to, will also get stretched along with the width and height of your element. ScaleX and ScaleY scales the ENTIRE element, not just the dimensions.
A better solution to animating the size of your element while having the border radius be consistent is to animate the height and width. Something like this would work:
#keyframes singleExpend {
0% {
width: 55px;
height: 55px;
}
50% {
width: 55px;
height: 40px;
}
100% {
width: 400px;
height: 40px;
}
}
Good luck!

Delay between CSS Animation with 0.1s duration

i have a little issue with the css animation and keyframe feature...
i have a little monster with blinking eyes... the eyes should blink just 0.1s
And then i want to have a duration... and then the animation should loop.
This is my animation/keyframe:
#keyframes blinkingEyes {
0% {
transform: rotateX(0deg);
}
36% {
transform: rotateX(90deg);
}
100% {
transform: rotateX(90deg);
}
}
And this is my animation property:
animation: blinkingEyes 0.15s 1s infinite linear;
JSFIDDLE
I found a workaround with a x% between my start and end value. But nothing works for me.. i hope you could help me
You need several keyframes for this, and then make the animation run infinite times.
See:
#monster {
margin-top: 60px;
height: 93px;
width: 75px;
border-radius: 120px;
background: yellow;
/* text-align: center; */
position: relative;
}
.eye {
height: 12px;
width: 8px;
background: black;
border-radius: 10px;
margin-top: 30px;
float: left;
animation: blinkingEyes 1.5s linear infinite;
}
.eyeLeft {
margin-left: 18px;
}
.eyeRight {
margin-left: 22px;
}
.mouth {
font-weight: 900;
transform-origin: 50% 50%;
/* display: inline-block; */
width: 5px;
margin: 0 auto;
height: 20px;
/* text-align: center; */
/* left: 47%; */
position: absolute;
top: 47px;
transform: rotate(90deg);
left: 35px;
}
#keyframes blinkingEyes {
0%, 97%, 100% {
transform: rotateX(0deg);
}
98%, 99% {
transform: rotateX(90deg);
}
}
<div id="monster">
<div class="monsterBody">
<div class="eye eyeLeft">
</div>
<div class="eye eyeRight">
</div>
<div class="mouth">
)
</div>
</div>
</div>

Animate CSS background-position with smooth results (sub-pixel animation)

I'm trying to animate the background-position of a div, slowly, but without it having jerky movement. You can see the result of my current efforts here:
http://jsfiddle.net/5pVr4/2/
#-webkit-keyframes MOVE-BG {
from {
background-position: 0% 0%
}
to {
background-position: 187% 0%
}
}
#content {
width: 100%;
height: 300px;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
text-align: center;
font-size: 26px;
color: #000;
-webkit-animation-name: MOVE-BG;
-webkit-animation-duration: 100s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
}
I have been at this for hours and can't find anything that will animate slowly and smoothly at a sub-pixel level. My current example was made from the example code on this page: http://css-tricks.com/parallax-background-css3/
The smoothness of animation I'm after can be seen on this page's translate() example:
http://css-tricks.com/tale-of-animation-performance/
If it can't be done with the background-position, is there a way to fake the repeating background with multiple divs and move those divs using translate?
Checkout this example:
#content {
height: 300px;
text-align: center;
font-size: 26px;
color: #000;
position:relative;
}
.bg{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
animation-name: MOVE-BG;
animation-duration: 100s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
#keyframes MOVE-BG {
from {
transform: translateX(0);
}
to {
transform: translateX(-187%);
}
}
<div id="content">Foreground content
<div class="bg"></div>
</div>
http://jsfiddle.net/5pVr4/4/
Animating background-position will cause some performance issues. Browsers will animate transform properties much cheaply, including translate.
Here is an example using translate for an infinite slide animation (without prefixes):
http://jsfiddle.net/brunomuller/5pVr4/504/
#-webkit-keyframes bg-slide {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.wrapper {
position:relative;
width:400px;
height: 300px;
overflow:hidden;
}
.content {
position: relative;
text-align: center;
font-size: 26px;
color: #000;
}
.bg {
width: 200%;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) repeat-x;
position:absolute;
top: 0;
bottom: 0;
left: 0;
animation: bg-slide 20s linear infinite;
}
You should adjust your HTML and CSS little bit
Working Demo
HTML
<div id="wrapper">
<div id="page">
Foreground content
</div>
<div id="content"> </div>
</div>
CSS
#-webkit-keyframes MOVE-BG {
from { left: 0; }
to { left: -2000px; }
}
#wrapper {
position:relative;
width:800px;
height: 300px;
overflow:hidden;
}
#page {
text-align: center;
font-size: 26px;
color: #000;
}
#content {
width: 2000px;
height: 300px;
background: url(http://www.gstatic.com/webp/gallery/1.jpg) 0% 0% repeat;
position:absolute;
top: 0;
left: 0;
z-index:-1;
-webkit-animation-name: MOVE-BG;
-webkit-animation-duration: 100s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
}

Firefox: Multiple borders with border-radius set, overlayed on top of each other, show ragged edges

The HTML
<div id='loader'>
<div id='loaderLargeSlice' class='loaderSlice'>
<div class='arc'></div>
<div class='arc'></div>
<div class='arc'></div>
</div>
</div>
The CSS
#loader{
position: relative;
width: 100px;
height: 100px;
margin: 14px;
border-radius: 50%;
background: none;
}
.loaderSlice
{
position:absolute;
display:block;
opacity: 0.5;
}
#loaderLargeSlice
{
height: 100px;
width: 100px;
animation: spin 4s linear 0s infinite forwards;
-webkit-animation: spin 4s linear 0s infinite forwards;
}
.arc
{
position: absolute;
top: -14px;
left: -14px;
width: 100%;
height: 100%;
background: none;
border: 14px solid rgba(0,0,0,0);
border-top-color: black;
border-radius: 50%;
}
.arc + .arc
{
transform: rotate(70deg);
-webkit-transform: rotate(70deg);
}
.arc + .arc + .arc
{
transform: rotate(140deg);
-webkit-transform: rotate(140deg);
}
The Problem
Firefox shows ragged edges
Anyone know of a fix?
Answering as unfixable. See #Eevee's comment on the main post.

Drawing animated arc with pure CSS

I know it is possible to draw and animate arcs in SVG and canvas. However, is it possible in CSS?
I have created an arc using the following method:
.arc{
width:150px;
height:400px;
border-radius:50%;
border-right:1px solid black;
border-left:1px solid black;
border-top:1px solid black;
border-bottom:1px solid white;
}
But, how can I animate this? The only way I can think of is having a pure white div over it and sliding that div to the right gradually revealing the arc. Is there a better way?
Here is working demo with minimum of hard-coded variables. This works based on animated circle halves:
.circle {
display: inline-flex;
overflow: hidden;
}
.circle__half {
height: 200px;
width: 100px;
position: relative;
overflow: hidden;
}
.circle__half:before {
height: inherit;
width: inherit;
position: absolute;
content: "";
border-radius: 100px 0 0 100px;
background-color: lime;
transform-origin: 100% 50%;
/* hidden by default */
transform: rotate(180deg);
opacity: 0.65;
animation-name: rotate-circle-half;
animation-duration: 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.circle__half--right {
transform: scale(-1, -1);
}
.circle .circle__half--right:before {
animation-name: rotate-circle-half--right;
}
/* show half of circle half of the time */
#keyframes rotate-circle-half {
0% {
transform: rotate(180deg);
}
50% {
transform: rotate(0deg);
}
100% {
transform: rotate(0deg);
}
}
#keyframes rotate-circle-half--right {
0% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(0deg);
}
}
<div class="circle">
<div class="circle__half"></div>
<div class="circle__half circle__half--right"></div>
</div>
Also the same look as iConnor's answer but doesn't have drawback of hardcoded background-color:
*,
*:before,
*:after {
box-sizing: border-box;
}
.circle {
display: inline-flex;
overflow: hidden;
}
.circle__half {
height: 200px;
width: 100px;
position: relative;
overflow: hidden;
}
.circle__half:before {
height: inherit;
width: inherit;
position: absolute;
content: "";
border-radius: 100px 0 0 100px;
border: 10px solid #00507c;
border-right-color: transparent;
background-color: #0087cf;
transform-origin: 100% 50%;
/* hidden by default */
transform: rotate(180deg);
opacity: 0.65;
animation-name: rotate-circle-half;
animation-duration: 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.circle__half--right {
transform: scale(-1, -1);
}
.circle .circle__half--right:before {
animation-name: rotate-circle-half--right;
}
/* show half of circle half of the time */
#keyframes rotate-circle-half {
0% {
transform: rotate(180deg);
}
50% {
transform: rotate(0deg);
}
100% {
transform: rotate(0deg);
}
}
#keyframes rotate-circle-half--right {
0% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(0deg);
}
}
<div class="circle">
<div class="circle__half"></div>
<div class="circle__half circle__half--right"></div>
</div>
If you need sole CSS3, then you can set a width+height, set border-radius to 100%, disable the extra borders (use only 1 or 2) and add some good pixels to it.
Then you can animate using animate: time animation ease timingFunction;
Declare the animation itself using #-prefix-keyframes { . . . } (Eh yea, looks like most browser engines require prefix for this one, chrome does :S)
I think I might have something close to what you mean:
.qLoader2 {
border: 4px solid blue;
width: 10vw;
height: 10vw;
width: 72px;
height: 72px;
position: absolute;
top: 12vh;
right: 45vw;
left: 45vw;
background: white;
opacity: 0.45;
border-right: none;
border-top: none;
border-left: none;
z-index: 2000;
background-color: transparent;
border-radius: 100%;
transform: rotateZ(0);
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
/* #-moz-keyframes spin { . . . } */
/* #-ms-keyframes spin { . . . } */
/* #-o-keyframes spin { . . . } */
#-webkit-keyframes spin {
from {
transform: rotateZ(0deg) scale(1);
}
50% {
transform: rotateZ(540deg) scale(0.9);
border-color: #0099ff;
}
to {
transform: rotateZ(1080deg) scale(1);
}
}
#keyframes spin {
from {
transform: rotateZ(0deg) scale(1);
}
50% {
transform: rotateZ(540deg) scale(0.9);
border-color: #0099ff;
}
to {
transform: rotateZ(1080deg) scale(1);
}
}
<div class="qLoader2"></div>
On JSFiddle
Feel free to use and modify.
Alternatively you could check something with SVG it's fairly decent as well and supported by most nowadays browsers.
EDIT: Using two arcs, you can have the animation draw cleanly from left-to-right AND have the background show through:
http://jsfiddle.net/sPv4A/6/
Vendor prefixes not included for CSS:
.arcContain {
width: 150px;
height: 400px;
position: relative;
margin: 20px;
}
.arc {
width: 150px;
height: 400px;
border-radius: 50%;
border: 2px solid black;
border-bottom: 2px solid transparent;
position: absolute;
top: 0;
right: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.archideLeft .arc {
top: auto;
bottom: 0;
right: auto;
left: 0;
}
.archide {
width: 50%;
height: 0%;
position: absolute;
top: 0;
right: 0;
overflow: hidden;
animation: appear 1.2s ease-in 1.2s forwards;
}
.archideLeft {
top: auto;
bottom: 0;
right: auto;
left: 0;
animation: appear 1.2s ease-out forwards;
}
#keyframes appear {
to {
height: 100%;
}
}
<div class="arcContain">
<div class="archide archideLeft">
<div class="arc"></div>
</div>
<div class="archide">
<div class="arc"></div>
</div>
</div>
OLD ANSWER: Maybe using two child divs to cover it up, and then have them shrink away to reveal it:
.arc {
width: 150px;
height: 400px;
border-radius: 50%;
border-right: 1px solid black;
border-left: 1px solid black;
border-top: 1px solid black;
border-bottom: 1px solid white;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
position: relative;
}
.arcInner {
background: white;
height: 402px;
width: 77px;
position: absolute;
}
.arcLeft {
top: -2px;
left: -2px;
-webkit-transition: height 2s linear;
-moz-transition: height 2s linear;
-ms-transition: height 2s linear;
-o-transition: height 2s linear;
transition: height 2s linear;
}
.arcRight {
bottom: 0;
right: -2px;
-webkit-transition: height 2s 2s linear;
-moz-transition: height 2s 2s linear;
-ms-transition: height 2s 2s linear;
-o-transition: height 2s 2s linear;
transition: height 2s 2s linear;
}
.appear .arcInner {
height: 0;
}
<div class="arc">
<div class="arcInner arcLeft"></div>
<div class="arcInner arcRight"></div>
</div>
As Per Chris B's suggestion on the original question, the answer is to contain the arc in another div and then animate the width of the container:
http://jsfiddle.net/AZb3X/
CSS:
body{
background:orange;
}
.arc{
width:150px;
height:400px;
border-radius:50%;
border-right:1px solid black;
border-left:1px solid black;
border-top:1px solid black;
border-bottom:1px solid white;
float:left;
}
.hider{
width:0px;
overflow:hidden;
-webkit-animation:unhide 12s;
}
#-webkit-keyframes unhide{
100%{width:400px}
}
HTML:
<div class='hider'>
<div class="arc"></div>
</div>
I may be a little late, but I think using two "hiders" and translating one up and one down will look a little better.
Working Example
<div class="wrap">
<div class="arc"></div>
</div>
body {
background:orange;
}
.wrap {
position:absolute;
height:400px;
width:170px;
overflow: hidden;
}
.arc {
position:absolute;
width:150px;
height:400px;
margin:10px;
border-radius:50%;
border-right:1px solid black;
border-left:1px solid black;
border-top:1px solid black;
border-bottom:1px solid transparent;
}
.arc:before {
content:"";
position:absolute;
left:-1px;
top:-2px;
background: orange;
width:76px;
height:375px;
animation:unhide1 5s linear both;
}
.arc:after {
content:"";
position:absolute;
left:75px;
top:-2px;
background: orange;
float: right;
width:76px;
height:375px;
animation: unhide2 5s linear 5s both;
}
#keyframes unhide1 {
100% {
transform: translatey(-375px);
}
}
#keyframes unhide2 {
100% {
transform: translatey(375px);
}
}

Resources