Is there any better and simpler way writing opacity ease-in-out effect below?
CSS:
.button-hover {
font-family: arial black;
font-size: 100px;
color: #000;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
opacity: 1;
}
.button-hover:hover {
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
opacity: 0.5;
}
As you can see that I repeat these lines twice which does not seem ideal:
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
HTML:
<div class="container">
HOVER ME
</div>
jsfiddle
Don't repeat the transition rules. CSS pre-processors can help with the vendor prefixing but you really don't need to (and shouldn't) repeat the transition declarations in the :hover. Just set them once in elements's default state like so:
.button-hover {
font-family: arial black;
font-size: 100px;
color: #000;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
opacity: 1;
}
.button-hover:hover {
opacity: 0.5;
}
<div class="container">
HOVER ME
</div>
Understanding CSS3 Transitions
SASS & LESS can make this easy for you. You can use SASS & LESS Mixins for this.
Example (SASS):
/* Create a Mixin (SASS) */
#mixin transition($property, $time, $method) {
-webkit-transition: $property $time $method;
-moz-transition: $property $time $method;
-ms-transition: $property $time $method;
-o-transition: $property $time $method;
transition: $property $time $method;
}
/* Include this Mixin (SASS) */
.button-hover:hover {
#include transition(opacity, 1s, ease-in-out);
}
Example (LESS):
/* Create a Mixin (LESS) */
.transition(#property, #time, #method) {
-webkit-transition: #arguments;
-moz-transition: #arguments;
-ms-transition: #arguments;
-o-transition: #arguments;
transition: #arguments;
}
/* Include this Mixin (LESS) */
.button-hover:hover {
.transition(opacity, 1s, ease-in-out);
}
This will convert into CSS:
.button-hover:hover {
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-ms-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
More about SASS, LESS
Those are prefixes needed for browser support.
You can see here which browsers versions needs a prefix and decide if you can delete them based on what browsers you want to support.
For example the -moz- prefix is for Firefox and you can see that from Firefox 16 it is not needed anymore, so you can use transition without -moz- for Firefox 16+.
Read more about prefixes here.
Related
I'm trying to have one element exit slowly and another one come in just as slow, but I want the first element to come in fast and the second one to exit fast too. Is this possible? Here's what I tried. This is for a deck.js slide set.
.slide.long.in {
-webkit-transition: -webkit-transform 5000ms ease-in;
transition: transform 5000ms ease-in;
transition: transform 500ms ease-out;
}
.slide.long.out {
-webkit-transition: -webkit-transform 5000ms ease-out;
transition: transform 500ms ease-in;
transition: transform 5000ms ease-out;
}
Deck.js has javascript functions that change the class on a section if it is previous, current, or next. Using Imgonzalves hint, I added the following classes and it seems to work.
> .slide.long.in.deck-current {
-webkit-transition: -webkit-transform 5000ms ease-in;
transition: transform 2500ms ease-in;
}
> .slide.long.in.deck-next {
-webkit-transition: -webkit-transform 500ms ease-out;
transition: transform 500ms ease-out;
}
> .slide.long.in.deck-previous {
-webkit-transition: -webkit-transform 500ms ease-out;
transition: transform 500ms ease-out;
}
> .slide.long.out.deck-current {
-webkit-transition: -webkit-transform 5000ms ease-out;
transition: transform 500ms ease-out;
}
> .slide.long.out.deck-next {
-webkit-transition: -webkit-transform 500ms ease-out;
transition: transform 500ms ease-out;
}
> .slide.long.out.deck-previous {
-webkit-transition: -webkit-transform 500ms ease-out;
transition: transform 5000ms ease-out;
}
I want to add a simple blend-in image transition for mouse hover.
The hover itself works fine.
If I remove the display:none , the transition will work, but the hover image swap will fall apart. Any ideas how to fix that ?
Here is the CSS that I used:
div.effect img.image{
opacity: 1;
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
display:block;
}
div:hover.effect img.image{
opacity: 0;
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
display:none;
}
div.effect img.hover{
opacity: 0;
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
display:none;
}
div:hover.effect img.hover{
display:block;
opacity: 1;
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
And here is the live (not working) demo to play with: http://jsfiddle.net/46AKc/65/
Assuming all the images are the same height, you could set a fixed height on the parent element and then relatively position it.
.effect {
position:relative;
height:94px;
}
Absolutely positioning the img elements and remove display:none.
div.effect img.image {
opacity: 1;
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
-o-transition: opacity 0.5s ease-in-out;
-ms-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
position:absolute;
}
The reason this works is because the child img elements are absolutely positioned relative to the parents, effectively positioning both images on top of each other. You no longer need to change the display of the element, thus allowing the transition to take place.
UPDATED EXAMPLE HERE
Alternatively, if the images aren't all the same height, omit the height, but still relatively position the parent element. As opposed to absolutely positioning both images, just position one and it will still work.
ALTERNATIVE EXAMPLE HERE
div.effect img.hover {
opacity: 0;
position:absolute;
top:0;
}
It's also worth noting that you don't need to include the transition properties on all the elements if they have the same values. Having it on the div.effect img.image will suffice.
Take a look at this example.
css
.score {
-moz-transition: all 1s ease-in-out;
-webkit-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
.score-big {
-webkit-transform: scale(3);
}
js
$('.score').addClass('score-big')
scale applying but without transition. When i toggling scale in chrome console, transition works. What problem?
I have a mixin:
#mixin transition($duration) {
-webkit-transition: all $durations ease-in-out;
-moz-transition: all $durations ease-in-out;
-ms-transition: all $durations ease-in-out;
-o-transition: all $durations ease-in-out;
transition: all $durations ease-in-out;
}
but in its current state it's broken because it's clearly going to look for a variable named $durations instead of $duration and then suffixing an s for seconds. Is there a way to pull this off?
You need to use string interpolation:
#mixin transition($duration) {
-webkit-transition: all #{$duration}s ease-in-out;
-moz-transition: all #{$duration}s ease-in-out;
-ms-transition: all #{$duration}s ease-in-out;
-o-transition: all #{$duration}s ease-in-out;
transition: all #{$duration}s ease-in-out;
}
.foo {
#include transition(1);
}
I've started using transitions to "modernise" the feel of a site. So far, :hover transitions are working great. Now I'm wondering if it's possible to trigger a transition based on other things, such as when a class changes.
Here's the relevant CSS:
#myelem {
opacity: 0;
display: none;
transition: opacity 0.4s ease-in, display 0.4s step-end;
-ms-transition: opacity 0.4s ease-in, display 0.4s step-end;
-moz-transition: opacity 0.4s ease-in, display 0.4s step-end;
-webkit-transition: opacity 0.4s ease-in, display 0.4s step-end;
}
#myelem.show {
display: block;
opacity: 1;
transition: opacity 0.4s ease-out, display 0.4s step-start;
-ms-transition: opacity 0.4s ease-out, display 0.4s step-start;
-moz-transition: opacity 0.4s ease-out, display 0.4s step-start;
-webkit-transition: opacity 0.4s ease-out, display 0.4s step-start;
}
The JavaScript to trigger the change is:
document.getElementById('myelem').className = "show";
But the transition doesn't seem to be happening - it's just jumping from one state to the other.
What am I doing wrong?
It does work when you remove the display properties.
#myelem {
opacity: 0;
transition: opacity 0.4s ease-in;
-ms-transition: opacity 0.4s ease-in;
-moz-transition: opacity 0.4s ease-in;
-webkit-transition: opacity 0.4s ease-in;
}
#myelem.show {
opacity: 1;
transition: opacity 0.4s ease-out;
-ms-transition: opacity 0.4s ease-out;
-moz-transition: opacity 0.4s ease-out;
-webkit-transition: opacity 0.4s ease-out;
}
JSFiddle.
The reason for this is that only CSS properties with numbers can be transitioned. What do you think the "50% state" should be between "display: none;" and "display: block;"? Since that can't be calculated, you can't animate the display property.
You cannot use the display property for transitioning between states.
The answer provided by #MarcoK including the comments shows already the right direction. Setting display property hinders transition.
A better practice is though to put the unprefixed (standards) version after the browser-vendor prefixed ones, in order to be future-proof. The latter properties overwrite the former.
Other improvements:
As #Charmander pointed out, -ms-transition isn't supported by any Internet Explorer
There's also Opera's vendor prefixed -o-transition for Op 10.5-12 & Op Mobile 10-12, which currently is probably supported by less than .1% of global browser. I'll put it in for completion
CSS:
#myelem {
opacity: 0;
-webkit-transition: opacity .4s ease-in;
-moz-transition: opacity .4s ease-in;
-o-transition: opacity .4s ease-in;
transition: opacity .4s ease-in;
}
#myelem.show {
opacity: 1;
-webkit-transition: opacity .4s ease-out;
-moz-transition: opacity .4s ease-out;
-o-transition: opacity .4s ease-out;
transition: opacity .4s ease-out;
}
It is possible to animate show and hide elements in css, just instead of:
display: none;
/* and */
display: block;
use:
overflow: hidden;
max-height: 0;
/* and */
max-height: 9999999px;
Since you replace this properties, you are able to animate any css value with transition.
working example:
https://jsfiddle.net/utyja8qx/