Respuesta corta
Usa este CSS:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
Además, este JS (sin jQuery) ...
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
O este JS con jQuery ...
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
... o código equivalente usando cualquier otra biblioteca o marco con el que esté trabajando.
Explicación
Este es realmente un problema bastante sutil.
En primer lugar, probablemente desee crear una clase de 'notransición' que pueda aplicar a los elementos para establecer sus *-transition
atributos CSS none
. Por ejemplo:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
(Menor a un lado - nota la falta de una -ms-transition
. Allí Usted no lo necesita La primera versión de Internet Explorer para las transiciones de apoyo. En absoluto era IE 10, que apoyaron ellas sin prefijo.)
Pero eso es solo estilo, y es la parte fácil. Cuando trates de usar esta clase, te encontrarás con una trampa. La trampa es que un código como este no funcionará de la manera ingenuamente esperada:
// Don't do things this way! It doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
someElement.classList.remove('notransition')
Ingenuamente, puede pensar que el cambio de altura no se animará, porque ocurre mientras se aplica la clase 'notransition'. En realidad, sin embargo, será animado, al menos en todos los navegadores modernos que he probado. El problema es que el navegador está almacenando en caché los cambios de estilo que necesita hacer hasta que JavaScript haya terminado de ejecutarse, y luego está haciendo todos los cambios en un solo reflujo. Como resultado, realiza un reflujo donde no hay un cambio neto en si las transiciones están habilitadas o no, pero hay un cambio neto en la altura. En consecuencia, anima el cambio de altura.
Puede pensar que una forma razonable y limpia de evitar esto sería envolver la eliminación de la clase 'notransition' en un tiempo de espera de 1 ms, como este:
// Don't do things this way! It STILL doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
setTimeout(function () {someElement.classList.remove('notransition')}, 1);
pero esto tampoco funciona de manera confiable. No pude hacer el salto de código anterior en los navegadores WebKit, pero en Firefox (tanto en máquinas lentas como rápidas) a veces (aparentemente al azar) obtendrás el mismo comportamiento que usar el enfoque ingenuo. Supongo que la razón de esto es que es posible que la ejecución de JavaScript sea lo suficientemente lenta como para que la función de tiempo de espera esté esperando para cuando el navegador esté inactivo y de lo contrario estaría pensando en hacer un reflujo oportunista, y si ese escenario sucede, Firefox ejecuta la función en cola antes del reflujo.
La única solución que he encontrado para el problema es forzar un reflujo del elemento, eliminando los cambios de CSS realizados antes de eliminar la clase 'notransition'. Hay varias formas de hacer esto; vea aquí algunas. Lo más parecido a una forma 'estándar' de hacerlo es leer la offsetHeight
propiedad del elemento.
Una solución que realmente funciona, entonces, es
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
Aquí hay un violín JS que ilustra los tres enfoques posibles que he descrito aquí (tanto el enfoque exitoso como los dos fallidos):
http://jsfiddle.net/2uVAA/131/