Animazione CSS3: display + opacità


101

Ho un problema con un'animazione CSS3.

.child {
    opacity: 0;
    display: none;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    opacity: 0.9;
    display: block;
}

Questo codice funziona solo se rimuovo la modifica di display.

Voglio cambiare la visualizzazione subito dopo il passaggio del mouse, ma l'opacità dovrebbe essere modificata usando la transizione.


2
Se CSS non funziona come gli altri suggeriscono, ecco un codice Javascript molto semplice per la dissolvenza.
— Abhranil Das

Risposte:


118

Sulla base della risposta di Michaels, questo è il codice CSS effettivo da utilizzare

.parent:hover .child
{
    display: block;

    -webkit-animation: fadeInFromNone 0.5s ease-out;
    -moz-animation: fadeInFromNone 0.5s ease-out;
    -o-animation: fadeInFromNone 0.5s ease-out;
    animation: fadeInFromNone 0.5s ease-out;
}

@-webkit-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

@-moz-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

@-o-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

@keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    1% {
        display: block;
        opacity: 0;
    }

    100% {
        display: block;
        opacity: 1;
    }
}

1
per supportare tutti i browser ..?
— david_adler

CSS3 non è supportato in tutti i browser. Se vuoi estendere, aggiungi i prefissi corretti
— Chris

17
E quando ci si sposta, come implementare fadeOutToNone?
— Verde

4
Poiché puoi usare frazioni di percentuale, è meglio usare qualcosa come 0,001% piuttosto che 1% perché riduce al minimo il ritardo di "inizio", che può diventare evidente con durate di animazione più lunghe
— Zach Saucier

1
La direttiva -o-keyframes è in realtà inutile perché la prima versione di Opera a supportare le animazioni era già basata su webkit.
— Rico Ocepek

43

Puoi fare con le animazioni CSS:

0% display:none ; opacity: 0;
1% display: block ; opacity: 0;
100% display: block ; opacity: 1;

Buona idea, sono riuscito a mantenere la visualizzazione del mio elemento durante il passaggio del mouse con la modalità di riempimento dell'animazione ma poi il mouseout l'elemento scompare.
— Alexis Delrieu

2
puoi usare la modalità di riempimento: avanti per rendere persistenti le modifiche al termine dell'animazione.
— Michael Mullany

42

Se possibile, usa visibilityinvece didisplay

Per esempio:

.child {
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.3s, visibility 0.3s;
}

.parent:hover .child {
    visibility: visible;
    opacity: 1;
    transition: opacity 0.3s, visibility 0.3s;
}

24
Il problema con la proprietà visibilità è che questa non nasconde l'elemento, lo rende solo invisibile. Quindi occuperà ancora spazio.
— Samuel,

6
Non solo invisibile, ma anche trasparente agli eventi (clic, ecc.). Non modificare la visualizzazione significa non ridisporre il documento, il che è una buona cosa. La maggior parte degli elementi che dovrebbero dissolversi in apertura / chiusura attraverso l'opacità dovrebbero comunque avere una posizione fissa o assoluta.
— Rasmus Kaj

13

Questa soluzione alternativa funziona:

  1. definire un "fotogramma chiave":

    @-webkit-keyframes fadeIn { 
      0% { opacity: 0; }
      20% { opacity: 0; }
      40% { opacity: 0.3; }
      60% { opacity: 0.5; }
      80% { opacity: 0.9; }
      100% { opacity: 1; }
    }
    
    @keyframes fadeIn {
      0% { opacity: 0; }
      20% { opacity: 0; }
      40% { opacity: 0.3; }
      60% { opacity: 0.5; }
      80% { opacity: 0.9; }
      100% { opacity: 1; }
    }
  2. Utilizza questo "fotogramma chiave" su "hover":

    div a span { 
      display: none;
    }
    
    div a:hover span {
      display: block;
    
      -webkit-animation-name: fadeIn;
      -webkit-animation-duration: 1s;
      animation-name: fadeIn;
      animation-duration: 1s;
    }

9

Ho usato questo per ottenerlo. Sbiadiscono al passaggio del mouse ma non prendono spazio quando sono nascosti, perfetto!

.child {
    height: 0px;
    opacity: 0;
    visibility: hidden;
    transition: all .5s ease-in-out;
}

.parent:hover .child {
    height: auto;
    opacity: 1;
    visibility: visible;
}

6

Sono cambiato un po 'ma il risultato è bellissimo.

.child {
    width: 0px;
    height: 0px;
    opacity: 0;
}

.parent:hover child {
    width: 150px;
    height: 300px;
    opacity: .9;
}

Grazie a tutti


4
Questo non funziona bene con i lettori di schermo: continueranno a leggere il contenuto.
— ehdv

1
Potresti aggiungere visibility: hidden;a .child / visibility:visible;al passaggio del mouse e questo dovrebbe risolvere il problema dello screen reader
— csilk

6

C'è un altro buon metodo per ottenere questo risultato usando pointer-events:

.child {
    opacity: 0;
    pointer-events: none;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    opacity: 0.9;
    pointer-events: all;
}

Sfortunatamente, questo non è supportato in IE10 e versioni precedenti.


4

Ho avuto lo stesso problema. Ho provato a usare le animazioni invece delle transizioni - come suggerito da @MichaelMullany e @Chris - ma ha funzionato solo per i browser webkit anche se ho copiato-incollato con i prefissi "-moz" e "-o".

Sono stato in grado di aggirare il problema usando visibilityinvece di display. Questo funziona per me perché il mio elemento figlio lo è position: absolute, quindi il flusso di documenti non viene influenzato. Potrebbe funzionare anche per gli altri.

Questo è l'aspetto del codice originale usando la mia soluzione:

.child {
    position: absolute;
    opacity: 0;
    visibility: hidden;

    -webkit-transition: opacity 0.5s ease-in-out;
    -moz-transition: opacity 0.5s ease-in-out;
    transition: opacity 0.5s ease-in-out;
}

.parent:hover .child {
    position: relative;
    opacity: 0.9;
    visibility: visible;
}

Se dovessi tornare con il mouse nel bambino mentre si anima fuori dalla vista, si riprenderebbe poiché l'elemento è semplicemente nascosto. Abbastanza fastidioso se muovi il mouse in un luogo.
— adamj

4

Se stai attivando la modifica con JS, diciamo al clic, c'è una bella soluzione alternativa.

Vedete che il problema si verifica perché l'animazione viene ignorata sul display: nessun elemento tranne il browser applica tutte le modifiche contemporaneamente e l'elemento non viene mai visualizzato: blocca mentre non è animato allo stesso tempo.

Il trucco è chiedere al browser di eseguire il rendering del frame dopo aver modificato la visibilità ma prima di attivare l'animazione.

Ecco un esempio di JQuery:

    $('.child').css({"display":"block"});
    //now ask the browser what is the value of the display property
    $('.child').css("display"); //this will trigger the browser to apply the change. this costs one frame render
    //now a change to opacity will trigger the animation
    $('.child').css("opacity":100);

2
Questa domanda non è contrassegnata con JavaScript né jQuery
— j08691

Lo so, l'ho scritto per spiegare il motivo per cui sta accadendo. Mi è stato molto utile quando l'ho saputo e spero che possa aiutare anche gli altri.
— daniel.sedlacek

1
A proposito, i valori di opacità sono compresi tra 0 e 1
— Amr

2

Su elementi assoluti o fissi potresti anche usare z-index:

.item {
    position: absolute;
    z-index: -100;
}

.item:hover {
    z-index: 100;
}

Altri elementi dovrebbero avere uno z-index compreso tra -100 e 100 ora.


Sfortunatamente questo rovina il simbolo dell'indicatore della password KeePass sui type=passwordcampi. Non è visibile.
— philk

1
Possiamo smettere di usare numeri z-index arbitrari? Qui: z-index: 1; vs z-index: -1 andrà benissimo. Scegliere enormi numeri di z-index rende le cose ingestibili.
— Dudewad

2

Lo so, questa non è davvero una soluzione per la tua domanda, perché chiedi

display + opacità

Il mio approccio risolve una domanda più generale, ma forse questo era il problema di fondo che dovrebbe essere risolto utilizzando displayin combinazione conopacity .

Il mio desiderio era di togliere di mezzo l'Elemento quando non è visibile. Questa soluzione fa esattamente questo: sposta l'elemento fuori dall'esterno e questo può essere utilizzato per la transizione:

.child {
  left: -2000px;
  opacity: 0;
  visibility: hidden;
  transition: left 0s 0.8s, visibility 0s 0.8s, opacity 0.8s;
}

.parent:hover .child {
  left: 0;
  opacity: 1;
  visibility: visible;
  transition: left 0s, visibility 0s, opacity 0.8s;
}

Questo codice non contiene prefissi del browser o hack di compatibilità con le versioni precedenti. Illustra semplicemente il concetto di come l'elemento viene spostato poiché non è più necessario.

La parte interessante sono le due diverse definizioni di transizione. Quando il puntatore del mouse si trova .parentsull'elemento, l' .childelemento deve essere posizionato immediatamente e quindi l'opacità verrà modificata:

transition: left 0s, visibility 0s, opacity 0.8s;

Quando non c'è passaggio del mouse o il puntatore del mouse è stato spostato fuori dall'elemento, è necessario attendere fino al termine della modifica dell'opacità prima che l'elemento possa essere spostato fuori dallo schermo:

transition: left 0s 0.8s, visibility 0s 0.8s, opacity 0.8s;

Spostare l'oggetto lontano sarà una valida alternativa in un caso in cui l'impostazione display:none non rompa il layout.

Spero di aver colto nel segno per questa domanda anche se non ho risposto.


Quel filtro Microsoft è stato deprecato da IE9. Qualche motivo particolare per cui hai voglia di aggiungerlo alle risposte nel 2016?
— TylerH

@TylerH Quanti utenti si è disposti a raggiungere è una questione di gusti.
— Hannes Morgenstern

Considerando che è deprecato e IE <11 non è più supportato da Microsoft, l'utilizzo di quella proprietà è di gusto discutibile, nella migliore delle ipotesi.
— TylerH

@TylerH È comune dover accogliere i clienti che non vogliono o non possono eseguire l'aggiornamento a un browser più recente. Ho una banca ben nota come cliente che utilizza ancora IE6 e si rifiuta di aggiornare per "motivi".
— Marcus Cunningham

@MarcusCunningham La domanda è contrassegnata con css3 che preclude completamente l'uso di IE6 (e IE7 e IE8). Nel primo browser possibile l'OP avrebbe potuto scrivere codice per, il filtro MS in questa risposta era deprecato. E per i futuri lettori, è ancora più inutile poiché non è nemmeno supportato. Non c'è motivo di includerlo in una risposta a questa domanda. È un punto controverso, tuttavia, poiché Hannes lo ha già rimosso dalla sua risposta.
— TylerH

1

Una cosa che ho fatto è stata impostare il margine dello stato iniziale in modo che fosse qualcosa come "margin-left: -9999px" in modo che non appaia sullo schermo, quindi reimpostare "margin-left: 0" nello stato hover. Tienilo "display: block" in quel caso. Ha fatto il trucco per me :)

Modifica: salvare lo stato e non ripristinare lo stato precedente al passaggio del mouse? Ok, qui abbiamo bisogno di JS:

<style>
.hovered { 
    /* hover styles here */
}
</style>

<script type="text/javascript">
$('.link').hover(function() {
   var $link = $(this);
   if (!$link.hasclass('hovered')) { // check to see if the class was already given
        $(this).addClass('hovered');
   } 
});
</script>

Buona idea, ma poi muovo il mouse, l'elemento scompare…
— Alexis Delrieu

Alexis, non è quello che vuoi fare? Hover significa SOLO quando si passa con il mouse. Per favore, chiarisci cosa stai cercando di realizzare.
— Joshua

Sì scusa. Voglio salvare la dissolvenza nel mouseout.
— Alexis Delrieu

Questo cambia tutto. Quasi. Fondamentalmente quello che vuoi è una funzione JS che rileverà lo stato di hover, come hanno indicato altri utenti, e aggiungerà ... beh ... vedi la mia risposta aggiornata.
— Joshua

1

Per avere l'animazione in entrambe le direzioni su HoverIn / Out ho fatto questa soluzione. Spero che possa aiutare qualcuno

@keyframes fadeOutFromBlock {
  0% {
    position: relative;
    opacity: 1;
    transform: translateX(0);
  }

  90% {
    position: relative;
    opacity: 0;
    transform: translateX(0);
  }

  100% {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
  }
}

@keyframes fadeInFromNone {
  0% {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
  }

  1% {
    position: relative;
    opacity: 0;
    transform: translateX(0);
  }

  100% {
    position: relative;
    opacity: 1;
    transform: translateX(0);
  }
}

.drafts-content {
  position: relative;
  opacity: 1;
  transform: translateX(0);
  animation: fadeInFromNone 1s ease-in;
  will-change: opacity, transform;

  &.hide-drafts {
    position: absolute;
    opacity: 0;
    transform: translateX(-999px);
    animation: fadeOutFromBlock 0.5s ease-out;
    will-change: opacity, transform;
  }
}

0

COME ANIMARE L'OPACITÀ CON I CSS:
questo è il mio codice:
il codice CSS

.item {   
    height:200px;
    width:200px;
    background:red;
    opacity:0;
    transition: opacity 1s ease-in-out;
}

.item:hover {
    opacity: 1;
}
code {
    background: linear-gradient(to right,#fce4ed,#ffe8cc);
}
<div class="item">

</div>
<p><code> move mouse over top of this text</code></p>

o controlla questo file demo

function vote () {
var vote = getElementById ("yourOpinion")
if (this.workWithYou):
vote + = 1};
lol


1
Non risponde alla domanda, poiché la displayproprietà è stata semplicemente rimossa.
— Brindisi del

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.