Glitchy hover animation and animations running on load

Hi all,

I’ve been experimenting with CSS3 animation to animate a rotated button on hover. The button should be rotated initally, then on hover it should rise by about 2rem. In the example below I’ve done an exaggerated animation to demonstrate my problem (button rises by 20rem on hover).

https://codepen.io/anon/pen/mgVLRM

You’ll notice that the animation is very glitchy, particularly if you hover just above the bottom of the button. How can I ensure this doesn’t happen - is there something wrong with my HTML markup or do I need to adjust my CSS?

Also, in addition to the above problem I’ve got issues with all of my animations running on page load, rather than when they are activated by the user (i.e hover). Below I’ve pasted in all of the CSS I have which contains various animations for different elements on the page including buttons and navigation links.

*{
    padding:0;
    margin:0;
}

/*********************** 
*** START pseudo
***********************/

body{
    font-family:'Sarabun', Arial, sans-serif;
    line-height:normal;
}

article{
    position: relative;
}

h2{
    font-family:'Muli Black', 'Arial Black', sans-serif;
    font-size:3rem;
    color:#313737;
}

h3,p{
    font-family:'Sarabun Light', Arial, sans-serif;
    color:#313737;
}

h3{
    margin:1rem 0;
    font-size:1.4rem;
}

h3{
    margin:0;
    margin-top:1rem;
    font-family: 'Muli', Arial, sans-serif;
    font-weight:400;
}

h3 a{
    font-family:'Sarabun', Arial, sans-serif;
    color:#000000;
    text-decoration: underline;
}

h4{
    font-size:1.5rem;
}


h5{
    font-family:'Muli SemiBold', Arial, sans-serif;
    font-size:1.2rem;
}

h5{
    font-style:italic;
}

h6{
    font-family:'Muli Regular', Arial, sans-serif;
    font-size:1.1rem;
}

p{
    font-size:1.2rem;
}

/*********************** 
*** END pseudo
***********************/

/*********************** 
*** START links
***********************/

.web{
    color:#7dced0;
}

.graphics{
    color:#d2baa6;
}

.photo{
    color:#dbdaaf;
}

.but--sliding_bg {
    display: inline-block;
    background: #929d9d;
    background-image: linear-gradient(120deg, #c5c5c5 50%, transparent 51%);
    background-size: 100px 100px;
    background-position: -50px -50px;
    background-repeat: no-repeat;
    transition: background cubic-bezier(0.1, 0.5, 0.5, 0.9) 0.3s;
    border-radius: 2px;
    padding: 17px 22px;
    margin:1rem 1rem 1rem 0;
    font-family: 'OpenSansBold', sans-serif;
    font-size: 1rem;
    font-weight: 400;
    color: #ffffff;
    letter-spacing: 1px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.but--sliding_bg span{
    opacity:0;
    display:inline-block;
    margin-left:15px;
    color:transparent;
}

.but--sliding_bg--web{
    background-image: linear-gradient(120deg, #7dced0 50%, transparent 51%);
}

.but--sliding_bg--graphics{
    background-image: linear-gradient(120deg, #d2baa6 50%, transparent 51%);
}

.but--sliding_bg--photo{
    background-image: linear-gradient(120deg, #dbdaaf 50%, transparent 51%);
}

.latestwork:hover .but--sliding_bg,
.but--sliding_bg:hover {
    background-size: 200% 200%;
    background-position: 0px 0px;
    color: #ffffff;
    text-decoration: none;
}

.latestwork:hover .but--sliding_bg span,
.but--sliding_bg:hover span{
    margin-left:15px;
    color:#ffffff;
    transition: opacity ease-in 0.15s 0s;
    opacity:1;
}

.backtotop{
    z-index:1;
    cursor:pointer;
    position:absolute;
    right:10%;
    bottom:0;
    margin:0;
    padding:10px 20px 15px 20px;
    background:#e4e4c6;
    font-size:1.4rem;
    color:#313737;
    line-height:normal;
    transform: rotateZ(90deg);
    transform-origin: 100% 100%;
    transition: bottom ease 0.3s;
}

.backtotop:hover{
    bottom:2rem;
}

/*********************** 
*** END links
***********************/

/*********************** 
*** START header
***********************/
header{
    margin:1rem 0;
}

header a,
ul.nav{
    overflow: hidden;
}

header a hr {
    height: 0.25rem;
    width: 100%;
    margin:0.25rem 0 0 -100%;
    background: #e4e4c6;
    border: none;
    transition: 0.3s ease-in-out;
}

header a:hover{
    text-decoration: none;
}

header a:hover hr {
    margin-left: 0;
}

.logo{
    display:inline-block;
    font-family:'Sarabun', Arial, sans-serif;
    font-size:1.8rem;
    font-weight:300;
    color:#6f6f6f;
}

.logo span{
    font-family:'Sarabun', Arial, sans-serif;
    font-weight:700;
}

.logo:hover{
    color:#6f6f6f;
    text-decoration: none;
}

.nav-container{
    display:flex;
    align-items: center;
    justify-content: center;
}

ul.nav{
    width:100%;
}

ul.nav li[class^='col']{
    display: inline;
    padding-left:0;
    padding-right:0;
    text-align: center;  
}

ul.nav a {
    display: block;
    padding: 0;
    padding-bottom: 0.75rem;
    margin: 0;
    font-size:1.2rem;
    text-decoration: none;
    color: #6f6f6f;
}

ul.nav a:hover{
    color:#313737;
}
/*********************** 
*** END header
***********************/

/*********************** 
*** START intro
***********************/
.intro-container{
    padding:1.5rem 1rem;
    background:#e4e4c6;
    border-top:12px solid #d3d3d3;
}

/*********************** 
*** END intro
***********************/

/*********************** 
*** START footer
***********************/
footer p{
    font-size:1rem;
}

footer .footer__inner{
    padding-top:1rem;
    margin-top:2rem;
    border-top:12px solid #d3d3d3;
}
/*********************** 
*** END footer
***********************/

/*********************** 
*** START homepage
***********************/
.latestwork{
    display:block;
    margin-bottom:3rem;
    padding:0;
}

.latestwork,
.latestwork:hover{
    color:inherit;
    text-decoration: none;
}

.latestwork picture img{
    width:100%;
}

.latestwork__overlay{
    position:absolute;
    bottom:0;
    left:0;
    padding:0;
    background: rgba(236,237,205,0.6);
    background:#f2f2f2;
}

.latestwork__overlay p{
    font-size:1.2rem;
}

/*********************** 
*** END homepage
***********************/

/*********************** 
*** START work
***********************/
.body-work h5{
    font-style:normal;
    text-align:center;
}

.mix,
.gap {
    display: inline-block;
    vertical-align: top;
}

.mix {
    position: relative;
    background: black;
    border-radius: 2px;
    margin-bottom: 1rem;
    min-width:100px;
}

.mix:before {
    content: '';
    display: inline-block;
    padding-top: 56.25%;
}

.filter-container{
    margin:0;
}

.filter{
    width:24%;
    margin:0 1%;
    padding:0.75rem 0;
    border:0;
    outline:0;
    font-size:1.1rem;
    color:#ffffff;
    background-size: 100% 200%;
    background-image: linear-gradient(to bottom, #929d9d 50%, #c5c5c5 50%);
    transition: background-position 0.15s;
    background-position:0 -5px;
}

.filter:hover,
.filter[class*='active']{
    cursor:pointer;
    background-position:0 100%;
}

.filter:focus{
    outline:0;
}

.filter--web{
    background-image: linear-gradient(to bottom, #929d9d 50%, #35c6ca 50%);
}

.filter--graphic{
    background-image: linear-gradient(to bottom, #929d9d 50%, #d0a27d 50%);
}

.filter--photo{
    background-image: linear-gradient(to bottom, #929d9d 50%, #d0cb7d 50%);
}

.work-tab-container{
    display:flex;
    align-items: center;
    margin-top:2rem;
}

.work-tab{
    display: block;
    align-items: center;
    justify-content: center;
    width: 24%;
    margin: 0 7px;
    background: #929d9d;
    overflow: hidden;
}

.work-tab h6{
    z-index: 1;
    padding: 20% 0;
    margin:0;
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size:0rem;
    transform: scale(1);
    transition: all 0.6s;
}

.work-tab h6 span{
    opacity:0;
    padding:1rem;
    background-color:rgba(95,107,107,0.8);
    color:#ffffff;
    text-align:center;
    transition: background-color 0.5s, opacity 0.3s;
}

.work-tab img{
    position:absolute;
    top:0;
    left:0%;
    width:100%;
    transition: all 0.6s;
}

.work-tab:hover{
    cursor: pointer;
}

.work-tab:hover img{
    transform: scale(1.15);
}

.work-tab:hover h6{
    font-size:1.2rem;
}

.work-tab:hover h6 span{
    opacity:1;
    background-color:rgba(95,107,107,1);
}

.work-tab .overlay{
    z-index:2;
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
}

.work-tab.web .overlay{
    background-image: linear-gradient(140deg, #35c6ca 0%,#35c6ca 5%, transparent 5%);
    transition: background-position linear 1s;
}

.work-tab.graphic .overlay{
    background-image: linear-gradient(140deg, #d0a27d 0%,#d0a27d 5%, transparent 5%);
}

.work-tab.photo .overlay{
    background-image: linear-gradient(140deg, #d0cb7d 0%,#d0cb7d 5%, transparent  5%);
}

/*********************** 
*** END work
***********************/

/*********************** 
*** START about
***********************/
.body-about h3{
    margin:2rem 0 1rem 0;
}

.cv-container{
    margin-top:2rem;
    padding: 2rem;
    background-color:#eeecdb;
}

.cv-container h4,
.cv-container h5,
.cv-container h6{
    margin:0.25rem 0;
}

.cv-container h4:nth-child(n+2){
    margin-top:3rem;
}

.cv-container h5{
    margin:1rem 0;
    margin-top:2rem;
}

.cv-container h6{
    margin:0.5rem 2rem;
    margin-top:1.5rem;
}

.cv-container p{
    margin-bottom:0;
    margin-left:2rem;
}

.experience-table{
    margin: 2rem;
}

.experience-table p{
    margin:0;
}
/*********************** 
*** END about
***********************/

/*********************** 
*** START project
***********************/
.intro-container--project{
    background-repeat:no-repeat;
    background-position:center top;
    background-size:90%;
}

.intro-container--project--sizeguide{
    background-image:url('../images/project_wssizeguide_headerbg.png');
}

.intro-container--project h2{
    margin:0;
    font-size:2.2rem;
}

.intro-container--project h5{
    font-size:1.3rem;
    font-style: normal;
}

.intro-container--project ul{
    margin-bottom:0;
}

.intro-container--project ul li{
    display:inline-block;
    margin:0 0.25rem;
    list-style-type: none;
}

.intro-container--project ul li:first-child{
    margin-left:0;
}


.intro-container--project a{
    margin:0;
}

/*********************** 
*** END project
***********************/

/*********************** 
*** START media queries
***********************/

@media(max-width:1200px){
    .latestwork__overlay{
        position:relative;
        background:none;
        margin-top:1rem;
    }
}

@media(max-width:991px){
    .work-tab{
        width:49%;
        margin:0.5%;
    }
    
    .work-tab h6{
        font-size:1rem;
    }

    .work-tab h6 span{
        opacity:1;
        background-color:rgba(95,107,107,1);
    }
}

@media(max-width:768px){
    h4{
        text-align:center;
    }

    .cv-container h4{
        text-align:left;
    }

    .work-tab{
        transition: none;
    }

    .work-tab h6,
    .work-tab:hover h6{
        font-size:1.2rem;
    }
}

@media(max-width:575px){    
    .nav-container{
        margin-top:1rem;
    }

    h2,
    .intro-container--project h2{
        margin-bottom:1rem;
        font-size:2rem;
    }

    .work-tab{
        width:100%;
        margin:7px 0;
    }

    .cv-container h6{
        margin-left: 0;
        margin-right: 0;

    }

    .cv-container p{
        margin-left:0;
    }

    .experience-table{
        margin:2rem 0;
    }

    .experience-table div[class^='col'] p{
        margin-bottom:0.5rem;
    }
}

@media (min-width: 576px) { 
    .latestwork-container h3 .but--sliding_bg{
        margin-left:1rem;
    }

    .cv-container{
        padding-right:4rem;
    }
}

@media (min-width: 768px) { 
    .latestwork__overlay{
        padding:1rem 1rem 0 1rem;
    }

    ul.nav li ~ hr{
        margin-left:-33.33%;
    }

    ul.nav li:hover ~ hr{
        background:#e4e4c6;
    }
    
    ul.nav li:nth-child(1):hover ~ hr {
        margin-left: 0%;
    }
    
    ul.nav li:nth-child(2):hover ~ hr {
        margin-left: 33.33%;
    }
    
    ul.nav li:nth-child(3):hover ~ hr {
        margin-left: 66.66%;
    }
    
    
    ul.nav hr {
        height: .25rem;
        width:33.33%;
        margin: 0;
        margin-top:-0.25rem;
        background: transparent;
        border: none;
        transition: .3s ease-in-out;
    }
}

@media (min-width: 992px) { }

@media (min-width: 1200px) { }

/*********************** 
*** END media queries
***********************/

Any thoughts please?

Thanks in advance!

Of course it will be glitchy because as soon as you hover over the element you move it out of the way which means its no longer hovered and the animation stops. The cycle is then repeated ad infinitum :slight_smile:

What you need to do is place a span inside the anchor and move the span when the anchor is hovered which means the cursor stays over the anchor and the hover is solid. Also avoid using position to move things as that causes a reflow. It’s much better to use translate where possible.

e.g.

.backtotop {
  z-index: 1;
  cursor: pointer;
  position: fixed;
  right: 10%;
  bottom: 2rem;
  margin: 0;
  line-height: normal;
  transform: rotateZ(90deg);
  transform-origin: 100% 100%;
}

.backtotop span {
  padding: 10px 20px 15px 20px;
  background: #e4e4c6;
  font-size: 1.4rem;
  color: #313737;
  display: block;
  transition: transform ease 0.5s;
}
.backtotop:hover span {
  transform: translateX(-1rem);
}

<a class="backtotop"><span>&lt; Back to top</span></a>

I’m guessing you also want position:fixed rather than absolute as absolute is relative to the document (assuming no positioned parent) and not fixed in relation to the viewport as with position:fixed

Ah of course, thanks! And thanks for the recommendation about using translate where possible.
My plan is to animate this in when the user scrolls to the bottom of the page so it isn’t there at all times, hence using absolute positioning and bottom and then positioning it relative to my container.

Do you have any recommendations as to why my animations are firing on load rather than waiting for interaction? I’m guessing it’s because the transition is set on the initial state, as in the example below?

.but--sliding_bg {
    display: inline-block;
    background: #929d9d;
    background-image: linear-gradient(120deg, #c5c5c5 50%, transparent 51%);
    background-size: 100px 100px;
    background-position: -50px -50px;
    background-repeat: no-repeat;
    transition: background cubic-bezier(0.1, 0.5, 0.5, 0.9) 0.3s;
    border-radius: 2px;
    padding: 17px 22px;
    margin:1rem 1rem 1rem 0;
    font-family: 'OpenSansBold', sans-serif;
    font-size: 1rem;
    font-weight: 400;
    color: #ffffff;
    letter-spacing: 1px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

Thanks again.

Do you have a working example as I don’t see a problem with the above?

If you are only changing on hover then the transitions shouldn’t run until hovered but if you are adding dynamic classes then that may trigger an animation.

I’d need to see it in action to debug.

Hmm very strange then - I can only assume it’s something that’s been set elsewhere as all animations are affected by it.

Something else I’m struggling with animation-wise is to create a “forwards” and “backwards” animation for my buttons, signifying the user going forward to another page or “back”.

Here is what I have so far - I thought by swapping the gradient colours over and the degree angle that it would be enough but this gives very strange behaviour!

https://codepen.io/Shoxt3r/pen/JVKXLJ

Thanks again for your help Paul.

I’d need to know what effect you were going for exactly as the 2 buttons in your demo have different behaviours? What is supposed to happen?

Is the first one correct and you want the second one to do the same but go from right/top to left/bottom?

Looks a bit strange to me?

The buttons aren’t square anyway so going corner to corner will be awkward assuming you want it split equally.

Animating gradients isn’t really possible as you can only animate the background-positions and gets quite awkward. It all depends on what type of effect you wanted.

Here’s a button example.

Ah that’ll be why I haven’t found many examples then…

The left button is correct but I wanted the right button to do the opposite, going right to left. The idea is that it signifies going forwards, going backwards in an abstract way.

I had a feeling this could be challenging though so might have to opt for the left to right angled option for all buttons.

You could animate a rotated pseudo element and translate it into the desired direction. It could just swipe a solid colour across the background.

I’m offline now otherwise I’d throw up a demo

If you meant the left button on your demo then you could do somethng like this:

1 Like

Many thanks Paul!
I should have pointed out that the extreme height was purely to demonstrate the problems I was facing with the animation (assume you guessed this?). Thank you for sorting out a demo - apologies I’ve been offline most of the weekend so only just getting around to replying.

I’ve tweaked the values slightly and changed the layout so that the button text is always visible and it’s only the span element that fades in.

I still haven’t quite figured out how you’ve managed to “reverse” the animation so it goes right to left though compared to what I had before?

Thanks again.

1 Like

I just fiddled about with the background size in devtools until it seemed to do what I wanted.:slight_smile:

Haha ah OK cool!

Thanks again for your help with this - was driving me nuts for a while! :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.