No momento, estou criando um menu 'mega dropdown' de CSS - basicamente, um menu suspenso apenas de CSS comum, mas que contém tipos diferentes de conteúdo.
No momento, parece que as transições CSS 3 não se aplicam à propriedade 'display' , ou seja, você não pode fazer nenhum tipo de transição de display: none
para display: block
(ou qualquer combinação).
Existe uma maneira de o menu de segunda camada do exemplo acima aparecer gradualmente quando alguém passa o mouse sobre um dos itens de menu de nível superior?
Estou ciente de que você pode usar transições na visibility:
propriedade, mas não consigo pensar em uma maneira de usá-lo efetivamente.
Eu também tentei usar a altura, mas isso apenas falhou miseravelmente.
Também estou ciente de que é trivial conseguir isso usando JavaScript, mas eu queria me desafiar a usar apenas CSS, e acho que estou ficando um pouco curto.
fonte
z-index:0
também.visibility: hidden
menos que você queira que os leitores de tela o leiam (enquanto os navegadores comuns não). Ele apenas define a visibilidade do elemento (como dizeropacity: 0
) e ainda é selecionável, clicável e o que quer que fosse; simplesmente não é visível.pointer-events
no IE 8,9,10, por isso nem sempre é okRespostas:
Você pode concatenar duas transições ou mais e
visibility
é isso que é útil dessa vez.(Não esqueça os prefixos do fornecedor da
transition
propriedade.)Mais detalhes estão neste artigo .
fonte
Você precisa ocultar o elemento por outros meios para que isso funcione.
Consegui o efeito posicionando os dois
<div>
absolutamente e colocando o oculto emopacity: 0
.Se você alternar a
display
propriedade denone
parablock
, sua transição para outros elementos não ocorrerá.Para contornar isso, sempre permita que o elemento seja
display: block
, mas oculte o elemento ajustando qualquer um destes meios:height
como0
.opacity
como0
.overflow: hidden
.Provavelmente existem mais soluções, mas você não pode executar uma transição se alternar o elemento para
display: none
. Por exemplo, você pode tentar algo como isto:Mas isso não vai funcionar. Pela minha experiência, descobri que isso não faz nada.
Por esse motivo, você sempre precisará manter o elemento
display: block
- mas poderá contorná-lo fazendo algo assim:fonte
visibility:hidden; opacity:0; -webkit-transition: all .2s ease-in-out;
não apenas faz a transição corretamente, mas o elemento de destino nunca será exibido. O controle de qualidade falhará com você, eu e sua mãe.height: 0;
e não fizer a transição, a transição não funcionará. Eu tentei isso apenas tentando fazer a transição da opacidade. Eu tive que remover oheight: 0;
overflow: hidden
obrigado!No momento desta publicação, todos os principais navegadores desabilitam as transições CSS se você tentar alterar a
display
propriedade, mas as animações CSS ainda funcionam bem para que possamos usá-las como uma solução alternativa.Código de exemplo (você pode aplicá-lo ao seu menu de acordo) Demonstração :
Adicione o seguinte CSS à sua folha de estilo:
Em seguida, aplique a
fadeIn
animação à criança no foco principal (e, é claro, no conjuntodisplay: block
):Atualização 2019 - Método que também suporta o desbotamento:
(É necessário algum código JavaScript)
fonte
height: 0
truque (para transições) mencionado acima não parece funcionar porque a altura é definida como 0 na transição de desvanecimento, mas esse truque parece funcionar muito bem.display
propriedade - não há realmente nenhuma razão para isso. E mesmo que eles fizeram , por que animações trabalhar então? Você também não pode usar adisplay
propriedade nas animações CSS.Eu suspeito que o razão qual as transições sejam desabilitadas se
display
alteradas seja por causa do que a exibição realmente faz. Ele não mudar qualquer coisa que poderia concebivelmente ser bem animado.display: none;
evisibility: hidden;
são duas coisas completamente diferentes.Ambos têm o efeito de tornar o elemento invisível, mas com
visibility: hidden;
ele ainda é renderizado no layout, mas não de forma visível .O elemento oculto ainda ocupa espaço e ainda é renderizado em linha ou como um bloco ou bloco em linha ou tabela ou o que o
display
elemento solicitar que ele renderize como e ocupa espaço em conformidade.Outros elementos não se movem automaticamente para ocupar esse espaço. O elemento oculto simplesmente não renderiza seus pixels reais para a saída.
display: none
por outro lado, na verdade, impede que o elemento seja renderizado inteiramente .Não ocupa nenhum espaço de layout.
Outros elementos que ocupariam parte ou todo o espaço ocupado por esse elemento agora se ajustam para ocupar esse espaço, como se o elemento simplesmente não existisse .
display
não é apenas outro atributo visual.Estabelece todo o modo de renderização do elemento, como se é um
block
,inline
,inline-block
,table
,table-row
,table-cell
,list-item
, ou qualquer outra coisa!Cada um deles tem ramificações de layout muito diferentes, e não haveria maneira razoável de animar ou fazer a transição suave (tente imaginar uma transição suave de
block
parainline
ou vice-versa, por exemplo!).É por isso que as transições são desativadas se a exibição é alterada (mesmo que a mudança seja para ou de
none
-none
não é apenas invisibilidade, é o seu próprio modo de renderização de elemento que significa que não é renderizada!).fonte
display
não podem ser transferidas suavemente como outras propriedades, mas isso não significa que o tempo não seja importante. Ser capaz de controlar quando a transição dedisply:block
paradisplay:none
acontece é muito importante. Assim como @CurtisYallop descreveu. Se eu quiser fazer a transição deopacity:1
paraopacity:0
e depois mudardisplay:block
paradisplay:none
, devo poder fazê-lo.Em vez de retornos de chamada, que não existem no CSS, podemos usar a
transition-delay
propriedadeEntão, o que está acontecendo aqui?
Quando a
visible
classe é adicionada, ambosheight
eopacity
iniciam a animação sem demora (0 ms), masheight
levam 0 ms para concluir a animação (equivalente adisplay: block
) eopacity
levam 600 ms.Quando a
visible
classe é removida,opacity
inicia a animação (atraso de 0 ms, duração de 400 ms) e a altura espera 400 ms e somente então instantaneamente (0 ms) restaura o valor inicial (equivalentedisplay: none
ao retorno de chamada da animação).Observe que essa abordagem é melhor do que as que estão usando
visibility
. Nesses casos, o elemento ainda ocupa o espaço na página e nem sempre é adequado.Para mais exemplos, consulte este artigo .
fonte
height:100%
qual pode destruir o layout em alguns casos. Ótima solução, se isso não for um problema. Um dos poucos trabalhos bidirecionais.transition: height 0ms 0ms, opacity 600ms 0ms
, eu apenas useitransition-delay: 0s
.display
não é uma das propriedades em que a transição funciona.Consulte Propriedades CSS animativas para obter a lista de propriedades CSS que podem ter transições aplicadas a elas. Consulte Módulo 4 de valores e unidades de CSS, combinando valores: interpolação, adição e acumulação para saber como eles são interpolados.
Até CSS 3 foi listado em 9.1. Propriedades do CSS (feche o pop-up de aviso)
Na última vez em que fiz isso, usei
max-height
, que é uma propriedade que pode ser animada (embora tenha sido um pouco hackeada, funcionou), mas cuidado com o fato de que pode ser muito instável para páginas complexas ou usuários com dispositivos móveis de última geração dispositivos.fonte
Você pode adicionar uma animação personalizada à propriedade block agora.
Demo
Nesta demonstração, o submenu muda de
display:none
paradisplay:block
e ainda consegue desaparecer.fonte
myfirst
estarshowNav
aqui? E o Firefox? Infelizmente, não consigo encontrar algo relacionado na página de demonstração que você está mencionando.De acordo com W3C Working Draft de 19 de novembro de 2013,
display
não é uma propriedade que pode ser animada . Felizmente,visibility
é animador. Você pode encadear sua transição com uma transição de opacidade ( JSFiddle ):HTML:
CSS:
JavaScript para teste:
Observe que, se você apenas tornar o link transparente, sem definir
visibility: hidden
, ele permanecerá clicável.fonte
0
para0s
. Aparentemente, no passado, o navegador que eu usava para testar suportava zero tempo sem unidade. No entanto, horários sem unidade não fazem parte da Recomendação de Candidato do W3C, 29 de setembro de 2016 .Edit: display none não está sendo aplicado neste exemplo.
O que está acontecendo acima é que, através de 99% da exibição da animação, é definido um bloqueio enquanto a opacidade diminui. No último momento, a propriedade de exibição está definida como nenhuma.
E o mais importante é reter o último quadro após o término da animação, usando o modo de preenchimento da animação:
Aqui estão dois exemplos: https://jsfiddle.net/qwnz9tqg/3/
fonte
display: none
não funciona então?display: none
nunca é realmente implementado. jsfiddle.net/3e6sduqhMeu puro truque de JavaScript é separar todo o cenário em duas funções diferentes !
Para preparar as coisas, uma variável global é declarada e um manipulador de eventos é definido:
Então, ao ocultar o elemento, eu uso algo assim:
Para reaparecer o elemento, estou fazendo algo assim:
Funciona até agora!
fonte
Encontrei isso hoje, com um
position: fixed
modal que estava reutilizando. Eu não pude mantê-lodisplay: none
e depois animá-lo, pois ele apareceu rapidamente ez-index
(valores negativos, etc.) também fizeram coisas estranhas.Eu também estava usando um
height: 0
paraheight: 100%
, mas só funcionou quando o modal apareceu. É o mesmo que se você usasseleft: -100%
ou algo assim.Então me ocorreu que havia uma resposta simples. Et voila:
Primeiro, o seu modal oculto. Observe o
height
é0
e confira aheight
declaração nas transições ... ele tem um500ms
, que é mais longo que a minhaopacity
transição . Lembre-se de que isso afeta a transição de desaparecimento gradual: retornando o modal ao seu estado padrão.Segundo, seu modal visível. Digamos que você esteja definindo um
.modal-active
para obody
. Agora oheight
é100%
, e minha transição também mudou. Eu queroheight
que isso seja instantaneamente alterado eopacity
que você aceite300ms
.É isso, funciona como um encanto.
fonte
Tomando algumas dessas respostas e algumas sugestões em outros lugares, o seguinte funciona muito bem para menus suspensos (estou usando isso com o Bootstrap 3, especificamente):
Você também pode usar
height
no lugar demax-height
se especificar os dois valores, poisheight:auto
não é permitido comtransition
s. O valor de foco demax-height
necessidades precisa ser maior que oheight
do menu pode ser possível.fonte
Encontrei uma maneira melhor para esse problema. Você pode usar a animação CSS e criar um efeito incrível ao mostrar itens.
fonte
Eu me deparei com esse problema várias vezes e agora simplesmente acompanhava:
Ao adicionar a classe,
block--invisible
o Elements inteiro não poderá ser clicado, mas todos os elementos por trás dele serãopointer-events:none
suportados por todos os principais navegadores (sem IE <11).fonte
pointer-events
Mude
overflow:hidden
paraoverflow:visible
. Funciona melhor. Eu uso assim:visible
é melhor porqueoverflow:hidden
age exatamente como adisplay:none
.fonte
O JavaScript não é necessário e nenhuma altura máxima escandalosamente enorme é necessária. Em vez disso, defina seus
max-height
elementos de texto e use uma unidade relativa à fonte, comorem
ouem
. Dessa forma, você pode definir uma altura máxima maior que o seu contêiner, evitando um atraso ou "popping" quando o menu for fechado:HTML
CSS
Veja um exemplo aqui: http://codepen.io/mindfullsilence/pen/DtzjE
fonte
Depois que a resposta aceita de Guillermo foi escrita, a especificação de transição CSS de 03/04/2012 mudou o comportamento da transição de visibilidade e agora é possível resolver esse problema de maneira mais curta , sem o uso de atraso de transição:
O tempo de execução especificado para ambas as transições geralmente deve ser idêntico (embora um tempo um pouco mais longo para visibilidade não seja um problema).
Para uma versão em execução, consulte minha postagem no blog CSS Transition Visibility .
Escreva o título da pergunta "Transições na tela: propriedade" e em resposta aos comentários de Rui Marques e Jos à resposta aceita:
Essa solução funciona nos casos em que é irrelevante se a propriedade de exibição ou visibilidade for usada (como provavelmente foi o caso nesta pergunta).
Ele não remove completamente o elemento
display:none
, apenas o torna invisível, mas ainda permanece no fluxo do documento e influencia a posição dos seguintes elementos.Transições que removem completamente o elemento semelhante
display:none
podem ser feitas usando height (conforme indicado por outras respostas e comentários), max-height ou margin-top / bottom, mas também consulte Como posso fazer a transição de height: 0; à altura: auto; usando CSS? e meu post no blog Soluções alternativas para transições CSS nas propriedades Display e Height .Em resposta ao comentário de GeorgeMillo: Ambas as propriedades e as duas transições são necessárias: A propriedade opacity é usada para criar uma animação de entrada e saída e a propriedade de visibilidade para evitar que o elemento ainda reaja aos eventos do mouse. São necessárias transições na opacidade para o efeito visual e na visibilidade para atrasar a ocultação até que o fade-out esteja concluído.
fonte
Finalmente encontrei uma solução para mim, combinando
opacity
composition absolute
(para não ocupar espaço quando oculto).fonte
Eu suspeito que alguém que está iniciando transições CSS descobre rapidamente que elas não funcionam se você estiver modificando a propriedade display (block / none) ao mesmo tempo. Uma solução alternativa que ainda não foi mencionada é que você pode continuar a usar
display:block/none
para ocultar / mostrar o elemento, mas defina sua opacidade como 0 para que, mesmo quando estiverdisplay:block
, ainda esteja invisível.Em seguida, para incorporá-lo, adicione outra classe CSS, como "on", que define a opacidade como 1 e define a transição para a opacidade. Como você pode imaginar, você precisará usar JavaScript para adicionar essa classe "on" ao elemento, mas pelo menos você ainda está usando CSS para a transição real.
PS Se você se encontrar em uma situação em que precisa fazer as duas coisas
display:block
e adicionar a classe "on", ao mesmo tempo, adie a última usando setTimeout. Caso contrário, o navegador apenas vê as duas coisas acontecendo ao mesmo tempo e desativa a transição.fonte
display:none
.É tão simples como o seguinte :)
Faça com que desapareça e depois faça
height 0;
. Também certifique-se de usar os encaminhamentos para que eles permaneçam no estado final.fonte
Esta solução tem excelente compatibilidade e ainda não a vi:
Explicação : ele usa o
visibility: hidden
truque (que é compatível com "mostrar e animar" em uma etapa), mas usa a combinaçãoposition: absolute; z-index: -1; pointer-events: none;
para garantir que o contêiner oculto não ocupe espaço e não responda às interações do usuário .fonte
position
still fará o elemento estremecer, não?position: absolute
significa que o elemento não ocupa espaço, como descrito na explicação. Quando ele muda paraposition: static
e aparece, ele ocupa espaço como um elemento normal, que é o objetivo desta pergunta. Eu sugiro que você experimente isso!Você pode fazer com que isso funcione da maneira natural que você esperava - usando a exibição - mas você precisa acelerar o navegador para fazê-lo funcionar, usando Javascript ou outros sugeriram um truque sofisticado com uma tag dentro de outra. Não ligo para a tag interna, pois ela complica ainda mais o CSS e as dimensões, então aqui está a solução Javascript:
https://jsfiddle.net/b9chris/hweyecu4/17/
Começando com uma caixa como:
Uma caixa escondida.
Vamos usar um truque encontrado em um q / a relacionado, verificando offsetHeight para acelerar o navegador instantaneamente:
https://stackoverflow.com/a/16575811/176877
Primeiro, uma biblioteca que formaliza o truque acima:
Em seguida, vamos usá-lo para revelar uma caixa e inseri-la em:
Isso desbota e desbota a caixa. Assim,
.noTrnsn()
desliga transições, então remover ahidden
classe, que viradisplay
a partirnone
de seu padrão,block
. Em seguida, definimos a opacidade como 0 para nos prepararmos para o desbotamento. Agora que montamos o cenário, ativamos as transições novamente.resumeTrnsn()
. E, finalmente, inicie a transição configurando a opacidade para 1.Sem a biblioteca, tanto a alteração a ser exibida quanto a opacidade teriam obtido resultados indesejáveis. Se simplesmente removêssemos as chamadas da biblioteca, não teríamos nenhuma transição.
Observe que as opções acima não definem a exibição para nenhuma novamente no final da animação fadeout. Podemos ficar mais extravagantes. Vamos fazer isso com um que desbota e cresce em altura a partir de 0.
Chique!
https://jsfiddle.net/b9chris/hweyecu4/22/
Agora estamos fazendo a transição de altura e opacidade. Observe que não estamos definindo a altura, o que significa que é o padrão
auto
,. Convencionalmente, não é possível fazer a transição - passar de automático para um valor de pixel (como 0) não fará a transição. Vamos contornar isso com a biblioteca e mais um método de biblioteca:Esse é um método de conveniência que nos permite participar da fila de animação / animação existente do jQuery, sem exigir nenhuma estrutura de animação que agora está excluída no jQuery 3.x. Não vou explicar como o jQuery funciona, mas basta dizer que o
.queue()
e.stop()
encanamento que jQuery fornece ajuda-nos a prevenir nossas animações de pisar no outro.Vamos animar o efeito deslizar para baixo.
Esse código começa verificando
#box
e se está oculto no momento, verificando sua classe. Mas realiza mais usando await()
chamada de biblioteca, adicionando ohidden
classe no final da animação slideout / fade, que você esperaria encontrar se estivesse de fato oculta - algo que o exemplo mais simples acima não poderia fazer. Isso também permite exibir / ocultar o elemento repetidamente, o que foi um erro no exemplo anterior, porque a classe oculta nunca foi restaurada.Você também pode ver as alterações de CSS e de classe sendo chamadas depois
.noTrnsn()
para definir o cenário das animações, incluindo a tomada de medidas, como medir qual será a altura final#box
sem mostrar isso ao usuário, antes de chamar.resumeTrnsn()
e animar a partir desse conjunto completo estágio para seus valores CSS de meta.Resposta antiga
https://jsfiddle.net/b9chris/hweyecu4/1/
Você pode fazer a transição ao clicar com:
O CSS é o que você imagina:
A chave está limitando a propriedade de exibição. Ao remover a classe oculta e, em seguida, à espera de 50 ms, em seguida, iniciar a transição através da classe acrescentou, podemos obtê-lo para aparecer e, em seguida, expandir-se como queríamos, em vez de apenas blipping na tela sem qualquer animação. Similar ocorre de outra maneira, exceto que esperamos até que a animação termine antes de aplicar a ocultação.
Nota: Estou abusando
.animate(maxWidth)
aqui para evitarsetTimeout
condições de corrida.setTimeout
é rápido para introduzir bugs ocultos quando você ou outra pessoa pega o código que não o conhece..animate()
pode ser facilmente morto com.stop()
. Estou apenas usando-o para colocar um atraso de 50 ms ou 2000 ms na fila fx padrão, onde é fácil encontrar / resolver por outros codificadores construídos sobre isso.fonte
Eu tive um problema semelhante ao qual não consegui encontrar a resposta. Algumas pesquisas no Google mais tarde me levaram até aqui. Considerando que não encontrei a resposta simples que esperava, encontrei uma solução elegante e eficaz.
Acontece que a
visibility
propriedade CSS tem um valorcollapse
que geralmente é usado para itens de tabela. No entanto, se usado em outros elementos, ele os torna efetivamente ocultos , praticamente iguais,display: hidden
mas com a capacidade adicional de que o elemento não ocupa espaço e você ainda pode animar o elemento em questão.Abaixo está um exemplo simples disso em ação.
fonte
A solução universal mais simples para o problema é: sinta-se à vontade para especificar
display:none
em seu CSS; no entanto, você precisará alterá-lo parablock
(ou qualquer outra coisa) usando JavaScript e, em seguida, também precisará adicionar uma classe ao seu elemento em questão que realmente faz a transição com setTimeout () . Isso é tudo.Ou seja:
Isso foi testado nos mais recentes navegadores sãos. Obviamente, ele não deve funcionar no Internet Explorer 9 ou anterior.
fonte
Eu acho que SalmanPK tem a resposta mais próxima. Ele desvanece ou desvanece um item, com as seguintes animações CSS. No entanto, a propriedade de exibição não anima suavemente, apenas a opacidade.
Se você deseja animar o elemento movendo-se do bloco de exibição para nenhum, não vejo como isso é atualmente possível apenas com CSS. Você precisa obter a altura e usar uma animação CSS para diminuir a altura. Isso é possível com o CSS, conforme mostrado no exemplo abaixo, mas seria complicado saber os valores exatos de altura que você precisa animar para um elemento.
Exemplo de jsFiddle
CSS
Javascript
fonte
Você pode fazer isso com eventos de transição, para criar duas classes CSS para a transição, uma segurando a animação outra, mantendo o estado de exibição nenhum. E você os troca depois que a animação termina? No meu caso, posso exibir os divs novamente se pressionar um botão e remover as duas classes.
Experimente o trecho abaixo ...
fonte
Se você estiver usando o jQuery para definir suas classes, isso funcionará 100%:
É claro que você pode usar jQuery
.fadeIn()
e.fadeOut()
funções, mas a vantagem de definir classes é se você deseja fazer a transição para um valor de exibição diferente deblock
(como é o padrão com.fadeIn()
e.fadeOut()
).Aqui estou fazendo a transição para exibir
flex
com um bom efeito de desbotamento.fonte
Em vez de usar,
display
você pode armazenar o elemento 'fora da tela' até precisar dele e, em seguida, definir sua posição para onde você deseja e transformá-lo ao mesmo tempo. Isso traz uma série de outros problemas de design, portanto, sua milhagem pode variar.Você provavelmente não gostaria de usá-lo de
display
qualquer maneira, pois gostaria que o conteúdo fosse acessível aos leitores de tela, que, na maioria das vezes, tentam obedecer às regras de visibilidade - ou seja, se não deveriam ser visíveis aos olhos, não aparecerá como conteúdo para o agente.fonte
Você pode simplesmente usar a visibilidade do CSS : oculto / visível em vez de display : none / block
fonte
Comecei um projeto de esqueleto de código aberto chamado Toggle Display Animate .
Esse auxiliar de esqueleto permitirá que você imite facilmente o show / ocultar do jQuery, mas com animações de transição de entrada e saída de CSS 3.
Ele usa alternância de classes para que você possa usar qualquer método CSS desejado nos elementos além da exibição: none | block | table | inline, etc., bem como outros usos alternativos que podem ser pensados.
Seu principal objetivo de design é o estado de alternância do elemento e suporta um estado de reversão em que ocultar o objeto permite executar o quadro-chave em sentido inverso ou reproduzir uma animação alternativa para ocultar o elemento.
A maior parte da marcação para o conceito em que estou trabalhando é CSS, e há muito pouco JavaScript realmente usado.
Há uma demonstração aqui: http://marcnewton.co.uk/projects/toggle-display-animate/
fonte