Puede hacer que esto funcione de la manera natural que esperaba, usando la pantalla, pero debe acelerar el navegador para que funcione, ya sea usando Javascript o como otros han sugerido un truco elegante con una etiqueta dentro de otra. No me importa la etiqueta interna, ya que complica aún más el CSS y las dimensiones, así que aquí está la solución de Javascript:
https://jsfiddle.net/b9chris/hweyecu4/17/
Comenzando con un cuadro como:
<div id="box" class="hidden">Lorem</div>
Una caja escondida.
div.hidden {
display: none;
}
#box {
transition: opacity 1s;
}
Vamos a usar un truco que se encuentra en un q / a relacionado, verificando offsetHeight para estrangular el navegador instantáneamente:
https://stackoverflow.com/a/16575811/176877
Primero, una biblioteca que formaliza el truco anterior:
$.fn.noTrnsn = function () {
return this.each(function (i, tag) {
tag.style.transition = 'none';
});
};
$.fn.resumeTrnsn = function () {
return this.each(function (i, tag) {
tag.offsetHeight;
tag.style.transition = null;
});
};
A continuación, lo usaremos para revelar un cuadro y desvanecerlo en:
$('#button').on('click', function() {
var tag = $('#box');
if (tag.hasClass('hidden'))
tag.noTrnsn().removeClass('hidden')
.css({ opacity: 0 })
.resumeTrnsn().css({ opacity: 1 });
else
tag.css({ opacity: 0 });
});
Esto desvanece la caja dentro y fuera. Entonces, .noTrnsn()
apaga las transiciones, luego eliminamos elhidden
clase, que voltea display
a partir none
de su valor por defecto, block
. Luego establecemos la opacidad en 0 para prepararnos para desvanecernos. Ahora que hemos preparado el escenario, activamos las transiciones nuevamente con .resumeTrnsn()
. Y finalmente, inicie la transición estableciendo la opacidad en 1.
Sin la biblioteca, tanto el cambio para mostrar como el cambio para la opacidad nos hubieran dado resultados indeseables. Si simplemente elimináramos las llamadas a la biblioteca, no obtendríamos ninguna transición.
Tenga en cuenta que lo anterior no establece la visualización en ninguno nuevamente al final de la animación de desvanecimiento. Sin embargo, podemos ser más elegantes. Hagámoslo con uno que se desvanece y crece en altura desde 0.
¡Lujoso!
https://jsfiddle.net/b9chris/hweyecu4/22/
#box {
transition: height 1s, opacity 1s;
}
Ahora estamos haciendo la transición tanto de altura como de opacidad. Tenga en cuenta que no tenemos intención de altura, lo que significa que es el valor por defecto, auto
. Convencionalmente, esto no se puede hacer la transición: pasar de automático a un valor de píxel (como 0) no conseguirá ninguna transición. Vamos a solucionar eso con la biblioteca y un método de biblioteca más:
$.fn.wait = function (time, fn) {
if (time)
this.delay(time);
if (!fn)
return this;
var _this = this;
return this.queue(function (n) {
fn.call(_this);
n();
});
};
Este es un método conveniente que nos permite participar en la cola fx / animación existente de jQuery, sin requerir ninguno del marco de animación que ahora está excluido en jQuery 3.x. No voy a explicar cómo funciona jQuery, pero basta con decir, el .queue()
y .stop()
plomería que jQuery proporciona ayuda a prevenir las animaciones de pisar el uno al otro.
Animamos el efecto deslizante hacia abajo.
$('#button').on('click', function() {
var tag = $('#box');
if (tag.hasClass('hidden')) {
// Open it
// Measure it
tag.stop().noTrnsn().removeClass('hidden').css({
opacity: 0, height: 'auto'
});
var h = tag.height();
tag.css({ height: 0 }).resumeTrnsn()
// Animate it
.css({ opacity: 1, height: h })
.wait(1000, function() {
tag.css({ height: 'auto' });
});
} else {
// Close it
// Measure it
var h = tag.noTrnsn().height();
tag.stop().css({ height: h })
.resumeTrnsn()
// Animate it
.css({ opacity: 0, height: 0 })
.wait(1000, function() {
tag.addClass('hidden');
});
}
});
Este código comienza verificando #box
y si está actualmente oculto, verificando su clase. Pero logra más utilizando la wait()
llamada a la biblioteca, al agregar elhidden
clase al final de la animación de deslizamiento / desvanecimiento, que esperaría encontrar si de hecho está oculta, algo que el ejemplo más simple anterior no podría hacer. Esto también permite mostrar / ocultar el elemento una y otra vez, lo cual fue un error en el ejemplo anterior, porque la clase oculta nunca se restauró.
También puede ver los cambios de clase y CSS que se solicitan después .noTrnsn()
para establecer generalmente el escenario para las animaciones, incluida la toma de medidas, como medir cuál será la altura final #box
sin mostrar eso al usuario, antes de llamar .resumeTrnsn()
, y animarlo desde ese conjunto completo etapa a sus valores de CSS objetivo.
Vieja respuesta
https://jsfiddle.net/b9chris/hweyecu4/1/
Puede hacer la transición al hacer clic con:
function toggleTransition() {
var el = $("div.box1");
if (el.length) {
el[0].className = "box";
el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {
el[0].className = "box hidden";
});
} else {
el = $("div.box");
el[0].className = "box";
el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {
el[0].className = "box box1";
});
}
return el;
}
someTag.click(toggleTransition);
El CSS es lo que adivinarías:
.hidden {
display: none;
}
.box {
width: 100px;
height: 100px;
background-color: blue;
color: yellow;
font-size: 18px;
left: 20px;
top: 20px;
position: absolute;
-webkit-transform-origin: 0 50%;
transform-origin: 0 50%;
-webkit-transform: scale(.2);
transform: scale(.2);
-webkit-transition: transform 2s;
transition: transform 2s;
}
.box1{
-webkit-transform: scale(1);
transform: scale(1);
}
La clave es limitar la propiedad de visualización. Al eliminar la clase oculta y luego esperar 50 ms, luego comenzar la transición a través de la clase agregada, hacemos que aparezca y luego se expanda como quisiéramos, en lugar de que simplemente aparezca en la pantalla sin ninguna animación. Similar ocurre al revés, excepto que esperamos hasta que termine la animación antes de aplicar oculta.
Nota: Estoy abusando .animate(maxWidth)
aquí para evitar las setTimeout
condiciones de carrera. setTimeout
es rápido para introducir errores ocultos cuando usted u otra persona recoge el código sin darse cuenta. .animate()
se puede matar fácilmente con .stop()
. Solo lo estoy usando para poner un retraso de 50 ms o 2000 ms en la cola de fx estándar, donde es fácil de encontrar / resolver por otros codificadores que se basan en esto.