Puoi farlo funzionare nel modo naturale che ti aspettavi - usando display - ma devi limitare il browser per farlo funzionare, usando Javascript o come altri hanno suggerito un trucco di fantasia con un tag all'interno di un altro. Non mi interessa il tag interno in quanto complica ulteriormente CSS e dimensioni, quindi ecco la soluzione Javascript:
https://jsfiddle.net/b9chris/hweyecu4/17/
A partire da una scatola come:
<div id="box" class="hidden">Lorem</div>
Una scatola nascosta
div.hidden {
display: none;
}
#box {
transition: opacity 1s;
}
Utilizzeremo un trucco trovato in una q / a correlata, controllando offsetHeight per limitare istantaneamente il browser:
https://stackoverflow.com/a/16575811/176877
Innanzitutto, una libreria che formalizza il trucco di cui sopra:
$.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;
});
};
Successivamente, lo useremo per rivelare una scatola e per sbiadirla in:
$('#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 });
});
Questo sfuma la scatola dentro e fuori. Quindi, .noTrnsn()
si spegne transizioni, quindi togliamo il hidden
classe, che gira display
da none
alla sua impostazione predefinita, block
. Quindi impostiamo l'opacità su 0 per prepararci a sfumare. Ora che abbiamo impostato il palcoscenico, riaccendiamo le transizioni, con.resumeTrnsn()
. E infine, avvia la transizione impostando l'opacità su 1.
Senza la libreria, sia la modifica da visualizzare sia la modifica all'opacità avrebbero ottenuto risultati indesiderati. Se avessimo semplicemente rimosso le chiamate in libreria, non avremmo alcuna transizione.
Si noti che quanto sopra non imposta nuovamente la visualizzazione su nessuno al termine dell'animazione di dissolvenza. Possiamo diventare più fantasiosi però. Facciamolo con uno che sfuma e cresce in altezza da 0.
Fantasia!
https://jsfiddle.net/b9chris/hweyecu4/22/
#box {
transition: height 1s, opacity 1s;
}
Ora stiamo passando sia all'altezza che all'opacità. Si noti che non stiamo regolazione dell'altezza, il che significa che è il default, auto
. Convenzionalmente questo non può essere trasferito: passare da auto a un valore di pixel (come 0) non ti porterà a nessuna transizione. Lavoreremo su questo con la libreria e un altro metodo di libreria:
$.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();
});
};
Questo è un metodo pratico che ci consente di partecipare alla coda fx / animazione esistente di jQuery, senza richiedere alcun framework di animazione che ora è escluso in jQuery 3.x. Non ho intenzione di spiegare come funziona jQuery, ma basti dire, l' .queue()
e .stop()
idraulico che jQuery fornisce aiutarci a prevenire le nostre animazioni da salire sulla vicenda.
Animiamo l'effetto slide down.
$('#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');
});
}
});
Questo codice inizia controllando #box
e se è attualmente nascosto, controllando la sua classe. Ma realizza di più usando la wait()
chiamata in libreria, aggiungendo ilhidden
classe alla fine dell'animazione di slideout / fade, che ti aspetteresti di trovare se fosse effettivamente nascosta - qualcosa che l'esempio più semplice sopra non potrebbe fare. Ciò accade anche per consentire di visualizzare / nascondere l'elemento più e più volte, che era un bug nell'esempio precedente, perché la classe nascosta non è mai stata ripristinata.
Puoi anche vedere i CSS e i cambi di classe che vengono chiamati dopo .noTrnsn()
per impostare generalmente il palcoscenico per le animazioni, incluso prendere misurazioni, come misurare quale sarà l'altezza finale #box
senza mostrarla all'utente, prima di chiamare.resumeTrnsn()
e animarlo da quel set completo tappa al suo obiettivo valori CSS.
Vecchia risposta
https://jsfiddle.net/b9chris/hweyecu4/1/
Puoi farlo passare con un 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);
Il CSS è quello che indovineresti:
.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 chiave sta limitando la proprietà display. Rimuovendo la classe nascosta e quindi aspettando 50 ms, quindi avviando la transizione tramite la classe aggiunta, otteniamo che appaia e poi si espanda come volevamo, invece di passare semplicemente sullo schermo senza alcuna animazione. Simile si verifica nell'altro modo, tranne per il fatto che attendiamo che l'animazione sia terminata prima di applicare nascosto.
Nota: sto abusando .animate(maxWidth)
qui per evitare le setTimeout
condizioni di gara. setTimeout
è rapido introdurre bug nascosti quando tu o qualcun altro raccogliete il codice inconsapevolmente. .animate()
può essere facilmente ucciso con .stop()
. Lo sto solo usando per mettere un ritardo di 50 ms o 2000 ms nella coda fx standard in cui è facile trovare / risolvere altri programmatori che si basano su questo.