Search code examples
twitter-bootstrapcssanimationcss-animationsbootstrap-material-design

Is that a way to skip css3 animation at shown?


Animation always play when an element from display:none to shown status. If I want style a custom checkbox. I only need it play animate when user check or uncheck it.

input[type=checkbox] { opacity: 0; } // native checkbox hidden
input[type=checkbox] ~ .mycheck {
    animation: uncheck 300ms ease-out forwards; // play uncheck animate
}
input[type=checkbox]:checked ~ .mycheck {
    animation: check 300ms ease-out forwards; // play checked animate
}

The issue is check and uncheck not only play when user click it. It play when page load also. Or when the parent element switch hidden to shown. e.g. in bootstrap tabs.

I know javascript can deal with it easily. But in fact, this issue come from an interest github project https://github.com/FezVrasta/bootstrap-material-design/issues/48. That handsome boy want implement google material design by bootstrap3.

Currently I can think of a way(not perfect). When :not(:hover) set animation-duration: 1ms;. Let animate ended quickly. But user still look a short flickr.

input[type=checkbox]:not(:hover) ~ .mycheck {
    animation-duration: 1ms;
}

Cannot set to 0ms. otherwise animate doesn't played until user hover it.

Is there any better ways?


Solution

  • You could use the solution you thought about with the :not(:hover) and simply cancel the animation with:

    input[type=checkbox]:not(:hover) ~ .mycheck {
        animation: none;
    }
    

    or, and I think it is the best solution here, don't use animations, and use transitions instead. That would result in something like that (assuming you're animating the opacity) :

    input[type=checkbox] ~ .mycheck {
        opacity: 0;
        transition: opacity .3s ease-out;
    }
    
    input[type=checkbox]:checked ~ .mycheck {
        opacity: 1;
    }
    

    Also, depending on the browsers support you want to achieve, mind the vendor prefixes, as Chrome only recently dropped them on the transition property

    EDIT: After some testing, I've come to think using only the :focus pseudo-class should be enough:

    input[type=checkbox]:focus ~ .mycheck {
        animation: uncheck 300ms ease-out forwards;
    }
    input[type=checkbox]:focus:checked ~ .mycheck {
        animation: check 300ms ease-out forwards;
    }
    

    The only drawback i can see is when the checkbox loses focus, the animation may get canceled