Transição CSS com visibilidade não funciona

102

No violino abaixo, eu tenho uma transição na visibilidade e opacidade separadamente. O último funciona, mas o primeiro não. Além disso, em caso de visibilidade, o tempo de transição é interpretado como atraso na saída do mouse. Acontece no Chrome e no Firefox. Isso é um inseto?

http://jsfiddle.net/0r218mdo/3/

Caso 1:

#inner{
    visibility:hidden;
    transition:visibility 1000ms;
}
#outer:hover #inner{
    visibility:visible;
}

Caso 2:

#inner1{
    opacity:0;
    transition:opacity 1000ms;
}
#outer1:hover #inner1{
    opacity:1;
}
user4150760
fonte
4
o último funciona porque o opacitypode assumir vários valores entre 0e 1, enquanto visibilitypode ser apenas visibleou hidden(sem valores intermediários)
Fabrizio Calderan

Respostas:

148

Isso não é um bug - você só pode fazer a transição em propriedades ordinais / calculáveis ​​(uma maneira fácil de pensar nisso é qualquer propriedade com um valor numérico inicial e final ... embora haja algumas exceções).

Isso ocorre porque as transições funcionam calculando quadros-chave entre dois valores e produzindo uma animação extrapolando valores intermediários.

visibility neste caso, é uma configuração binária (visível / oculto), então, uma vez que a duração da transição termina, a propriedade simplesmente muda de estado, você vê isso como um atraso - mas pode realmente ser visto como o quadro-chave final da animação da transição, com o quadros-chave intermediários não tendo sido calculados (o que constitui os valores entre oculto / visível? Opacidade? Dimensão? Como não é explícito, não são calculados).

opacity é uma configuração de valor (0-1), então os quadros-chave podem ser calculados ao longo da duração fornecida.

Uma lista de propriedades transicionáveis ​​(animáveis) pode ser encontrada aqui

SW4
fonte
7
dev.w3.org/csswg/css-transitions/#animtype-visibility especifica que os valores intermediários mapeiam para "visível".
Beni Cherniavsky-Paskin
@ BeniCherniavsky-Paskin - isso depende da função de tempo:other values of the timing function (which occur only at the start/end of the transition or as a result of cubic-bezier() functions with Y values outside of [0, 1]) map to the closer endpoint
SW4
1
A resposta do SW4 é enganosa e não explica o mal-entendido quanto ao propósito da visibilidade.
JesseMonroy650
@ JesseMonroy650 - embora eu hesite em refutar, é mais fácil fazê-lo sem nenhuma prova suplementar para essa alegação. Seria fascinante se você pudesse elaborar? O OP não estava perguntando o propósito da visibilidade (que é diferente de exibir, opacidade), mas por que não pode ser animado como uma propriedade, ou seja, pela razão dada - é efetivamente uma configuração liga / desliga. A resposta não busca abordar 'o que é visibilidade', mas 'por que não pode ser animada'
SW4
Podemos questionar o significado do OP, mas vou contra-atacar. Irritado com o tema constante (incompleto) e a impossibilidade de fazer este trabalho, decido investigá-lo. Primeiro, é importante notar que a documentação é pobre ; as explicações são pobres, a especificação é mal escrita (o editor também tem uma nota). Embora documentado como animatable, na verdade, possui apenas algumas das propriedades; uma dessas propriedades sendo o tempo . Vou blogar em breve.
JesseMonroy650
67

A visibilidade é animável. Verifique esta postagem do blog sobre isso: http://www.greywyvern.com/?post=337

Você também pode ver aqui: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

Digamos que você tenha um menu que deseja aumentar e diminuir gradualmente ao passar o mouse. Se você usar opacity:0apenas, seu menu transparente ainda estará lá e será animado quando você passar o mouse sobre a área invisível. Mas se você adicionar visibility:hidden, pode eliminar este problema:

div {
    width:100px;
    height:20px;
}
.menu {
    visibility:hidden;
    opacity:0;
    transition:visibility 0.3s linear,opacity 0.3s linear;
    
    background:#eee;
    width:100px;
    margin:0;
    padding:5px;
    list-style:none;
}
div:hover > .menu {
    visibility:visible;
    opacity:1;
}
<div>
  <a href="#">Open Menu</a>
  <ul class="menu">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
</div>

Sevban Öztürk
fonte
2
Isso não é verdade. O artigo mostra claramente: 1: O usuário passa o mouse sobre o elemento 2: a visibilidade muda para visível 3: a animação de transição de opacidade começa
Ben Racicot,
5
E, no entanto, o artigo atinge o equivalente funcional da visibilidade animada, ao fazer a transição habilmente para a opacidade. Ele explica bem por que você ainda precisa mexer na visibilidade para poder clicar nas coisas "abaixo" de um objeto oculto, como em um menu suspenso. Mas essa resposta seria melhor se desse um exemplo e um resumo localmente . (Links quebrados; acabei de consertar um.)
Bob Stein
esta resposta é um pouco enganosa, mas mesmo assim funcionou, obrigado!
JaTo de
2
@BobStein-VisiBone Eu editei minha resposta e dei um exemplo. Obrigado por sua ajuda :)
Sevban Öztürk
20

Visibilidade é uma propriedade animável de acordo com as especificações, mas as transições na visibilidade não funcionam gradualmente, como seria de se esperar. Em vez disso, as transições na visibilidade atrasam a ocultação de um elemento. Por outro lado, tornar um elemento visível funciona imediatamente. É assim que é definido pela especificação (no caso da função de tempo padrão) e é implementado nos navegadores.

Este também é um comportamento útil, pois de fato podemos imaginar vários efeitos visuais para ocultar um elemento. O esmaecimento de um elemento é apenas um tipo de efeito visual especificado por meio de opacidade. Outros efeitos visuais podem afastar o elemento usando, por exemplo, a propriedade transform, consulte também http://taccgl.org/blog/css-transition-visibility.html

Muitas vezes é útil combinar a transição de opacidade com uma transição de visibilidade! Embora a opacidade pareça fazer a coisa certa, elementos totalmente transparentes (com opacidade: 0) ainda recebem eventos do mouse. Assim, por exemplo, os links em um elemento que foi esmaecido apenas com uma transição de opacidade, ainda respondem a cliques (embora não sejam visíveis) e os links atrás do elemento esmaecido não funcionam (embora sejam visíveis através do elemento esmaecido). Consulte http://taccgl.org/blog/css-transition-opacity-for-fade-effects.html .

Esse comportamento estranho pode ser evitado usando apenas as duas transições, a transição para visibilidade e a transição para opacidade. Assim, a propriedade de visibilidade é usada para desabilitar os eventos do mouse para o elemento, enquanto a opacidade é usada para o efeito visual. No entanto, deve-se ter cuidado para não ocultar o elemento durante a reprodução do efeito visual, que de outra forma não seria visível. Aqui, a semântica especial da transição de visibilidade torna-se útil. Ao ocultar um elemento, o elemento permanece visível enquanto reproduz o efeito visual e é oculto depois. Por outro lado, ao revelar um elemento, a transição de visibilidade torna o elemento visível imediatamente, ou seja, antes de reproduzir o efeito visual.

Helmut Emmelmann
fonte