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.