Animação CSS3: exibição + opacidade

Eu tenho um problema com uma animação 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; } 

Este código só funciona se eu remover a mudança de display .

Eu quero mudar a exibição logo após o hover, mas a opacidade deve ser alterada usando a transição.

Com base na resposta Michaels este é o código CSS real para usar

 .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; } } 

Você pode fazer com animações CSS:

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

Se possível, use visibility vez de display

Por exemplo:

 .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; } 

Esta solução alternativa funciona:

  1. definir um “quadro-chave”:

     @-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. Use este “quadro-chave” em “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; } 

Eu mudei um pouco mas o resultado é lindo.

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

Obrigado a todos.

Existe outro bom método para fazer isso usando events de ponteiro:

 .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; } 

Infelizmente, isso não é suportado no IE10 e abaixo.

Eu tive o mesmo problema. Eu tentei usar animações em vez de transições – como sugerido por @MichaelMullany e @Chris – mas ele só funcionava para navegadores de webkit mesmo que eu copiasse e colasse com os prefixos “-moz” e “-o”.

Consegui contornar o problema usando visibility vez de display . Isso funciona para mim porque meu elemento filho é position: absolute , então o stream de documentos não está sendo afetado. Pode funcionar para os outros também.

Isto é o que o código original ficaria usando minha solução:

 .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; } 

Eu usei isso para alcançá-lo. Eles desaparecem no foco, mas não ocupam espaço quando ocultos, perfeitos!

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

Em elementos absolutos ou fixos, você também pode usar o z-index:

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

Outros elementos devem ter um índice z entre -100 e 100 agora.

Eu sei, isso não é realmente uma solução para sua pergunta, porque você pede

exibição + opacidade

Minha abordagem resolve uma questão mais geral, mas talvez esse fosse o problema de segundo plano que deveria ser resolvido usando a display em combinação com a opacity .

Meu desejo era tirar o elemento do caminho quando ele não estivesse visível. Essa solução faz exatamente isso: ela move o elemento para fora, e isso pode ser usado para transição:

 .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; } 

Este código não contém prefixos de navegador ou hacks de compatibilidade com versões anteriores. Apenas ilustra o conceito de como o elemento é removido, já que não é mais necessário.

A parte interessante são as duas diferentes definições de transição. Quando o ponteiro do mouse estiver passando o elemento .parent elemento .child precisará ser colocado imediatamente e, em seguida, a opacidade será alterada:

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

Quando não há nenhum foco, ou o ponteiro do mouse foi movido para fora do elemento, é preciso esperar até que a mudança de opacidade termine antes que o elemento possa ser movido para fora da canvas:

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

Mover o object para longe será uma alternativa viável em um caso em que a display:none configuração display:none não quebraria o layout.

Espero ter acertado na cabeça para esta pergunta, embora não tenha respondido.

Se você estiver acionando a alteração com o JS, digamos que, ao clicar, há uma boa solução alternativa.

Você vê que o problema acontece porque a animação é ignorada na exibição: nenhum elemento, exceto o navegador, aplica todas as alterações de uma vez e o elemento nunca é exibido: bloqueia enquanto não está animado ao mesmo tempo.

O truque é pedir ao navegador para renderizar o quadro depois de alterar a visibilidade, mas antes de acionar a animação.

Aqui está um exemplo da 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); 

Uma coisa que fiz foi definir a margem do estado inicial como algo como “margin-left: -9999px” para que não apareça na canvas e, em seguida, redefina “margin-left: 0” no estado de foco. Mantenha “display: block” nesse caso. Fiz o truque para mim 🙂

Editar: Salvar o estado e não reverter para o estado de foco anterior? Ok, aqui precisamos de JS:

   

Para ter animação nos dois sentidos onHoverIn / Out eu fiz essa solução. Espero que ajude alguém

 @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; } } 

display: não é passível de transição. Você provavelmente precisará usar o jQuery para fazer o que quiser fazer.