Design

Como Criar Efeitos de Transição Suave com CSS

Google+ Pinterest LinkedIn Tumblr
Anúncios Google

Um efeito muito agradável e que bem usado pode deixar o site ou blog mais bonito é o de transições, pela propriedade de CSS transition. Com algumas linhas de estilização dá pra fazer mudanças visuais como posições, cores e tamanho de objetos, acontecerem de forma gradual, como uma animação.

Não entendeu? Passe o link sobre algum item do menu aqui do blog e veja como a cor de fundo muda suavemente – o normal seria passar de uma vez para a outra cor. Antes, quando os navegadores ainda não estavam totalmente compatíveis com CSS3, haviam soluções em jQuery para isso, mas vamos ver aqui como fazer só com CSS – a única restrição é com o (sempre ele) Internet Explorer, pelo menos até a versão 9.

Pra ficar mais claro, um exemplo específico: a propriedade transition pode ser aplicada a diversos elementos, como links (a), listas (li), divs, imagens (img), bordas (border), cores de fundo (background-color) e texto (através de estilos de font, uso de containers como spans, etc), entre outros. Alguns não funcionam, como posição de background.

Vamos ver cada um com alguns exemplos.

Propriedades das Transições

  • A propriedade transition-timing-function com os valores: ease, linear, ease-in, ease-out, ease-in-out e bezier-cubic, permite controlar a progressão da transição;
  • A propriedade transition-property, com valores que são outras propriedade de CSS como background-color, font-size, position e muito mais, permite indicar quais propriedades são ou não afetadas pelo transition; não declarar indica o uso de all (afeta tudo que estiver contido no elemento afetado; por exemplo, uma div com todo seu conteúdo e propriedades);
  • A propriedade transition-duration, com valores em segundos (podem ser decimais ou microssegundos), permite controlar o tempo de duração da transição;
  • A propriedade transition-delay, com valores em segundos (podem ser decimais ou microssegundos), permite controlar o atraso no tempo de início da transição;
  • A propriedade transition permite agrupar vários valores de transition, sem precisar escrever todos. Por exemplo, em vez de usar várias propriedades como transition-duration, transition-property e transition-delay, agrupam-se os valores na propriedade transition (algo como {3s ease-out background-color 0.2s}).

Exemplos

Abra a página com os exemplos em ação aqui.

Vendor prefixes, ou prefixos proprietários

Note que em cada regra são escritas sempre variações com prefixos (também conhecidos como vendor prefixes) proprietários, ou seja, que funcionam em navegadores de motores específicos como o -moz de Mozilla, -o do Opera e -webkit do Chrome.

Conforme os navegadores são atualizados, a tendência é que só a propridedade “pura” seja usada e lida normalmente, mas enquanto os desatualizados estiverem rodando por aí, esses prefixos são necessários para manter o visual que você criou em qualquer navegador, seja ele moderno ou antigo.

Então, não estranhe ao ver uma regra repetida, assim:

seletor {
transition: x; /* lida por navegadores modernos */
-moz-transition: x; /* para Mozilla antigo */
-o-transition: x; /* para Opera antigo */
-webkit-transition: x /* para Chrome e similares antigos */

Links simples com transição

Vamos ver um link simples, que vai mudar de cor quando passar o mouse. Isso qualquer um faz, mas aplicaremos a transição na mudança.

A classe normal do link fica:

a {
color: #000;
font-weight: bold /* negrito no texto */
}

e ao passar o mouse, quero ele na cor vermelha:

a:hover {
color: #f00;
}

Com isso, seus links ficariam como no Exemplo 1 (lá na página de exemplos).

Como você nota a cor muda de uma vez ao passar o mouse, o que é o comportamento normal. Queremos que seja gradual, então vamos usar a regra transition. O CSS do link fica:

a {
color: #000;
font-weight: bold /* negrito no texto */
-webkit-transition: 0.5s ease-in;
-moz-transition: 0.5s ease-in;
-o-transition: 0.5s ease-in;
transition: 0.5s ease-in;
}

Os valores das propridades foram agrupadas num único transition, para não ficar com muitas linhas. O primeiro valor é do transition-duration, que no caso foi ajustado para meio segundo. O segundo é o transition-timing-function, que foi ajustado para o valor ease-in (o efeito começa mais lento e acelera no final).

Ficou ainda a propriedade transition-property: all ativa, já que nenhuma outra foi marcada – poderia-se escolher aplicar a transição em algumas propriedades do alvo, como background-image (imagem de fundo) ou background-color (cor de fundo).

A mesma estilização (sem as regras proprietárias -moz, -o e -webkit) sem agrupar as propriedades, ficaria:

a {
color: #000;
font-weight: bold /* negrito no texto */
transition-duration: 0.5s;
transition-timing-function: ease-in;
transition-property: all;
}

Cor de div com transição

O mesmo vale para outras propriedades como cor de fundo de div. Veja na página de exemplo. As regras para a div1 ficaram:

.div1 {
background: yellow;
width: 80%; /* largura da div */
height:40px; /* altura da div */
border:1px solid #999; /* borda da div */

}
.div1:hover {
background: blue;
-webkit-transition: 0.5s ease-out;
-moz-transition: 0.5s ease-out;
-o-transition: 0.5s ease-out;
transition: 0.5s ease-out;
}

Se você testou isso, verá uma diferença da minha página de exemplos: a mudança de volta ao estado original não tem transição suave, isso porque não colocamos as propridades transition no estilo original dos elementos (sem hover).

Para fazer a div voltar suavemente também à cor original, é só colocar o transition na classe div1 normal, assim:

.div1 {
background: red;
width: 80%; /* largura da div */
height:40px; /* altura da div */
border:1px solid #999; /* borda da div */
-webkit-transition: 0.5s ease-out;
-moz-transition: 0.5s ease-out;
-o-transition: 0.5s ease-out;
transition: 0.5s ease-out;
}

Notou a mudança? Isso porque o efeito hover herda os estilos da div normal, então tanto ao passar o mouse quanto ao tirar o ease é ativado.

Do ease-in, passei o estado original para ease-out (acelera no começo do efeito). Veja na página de exemplos.

Mais Algumas Transições

Posição – depois de posicionar um elemento com CSS, você pode tornar seu movimento para outra posição suave com transition. Veja na página de exemplo.

O estilo:

#divmove {
width:50px;
height:50px;
background:#0C3;
position:relative;
top:0px;
left: 0px;
-webkit-transition: 0.5s ease-in;
-moz-transition: 0.5s ease-in;
-o-transition: 0.5s ease-in;
transition: 0.5s ease-in;
}
#divmove:hover {
left: 30px;
-webkit-transition: 0.5s ease-in;
-moz-transition: 0.5s ease-in;
-o-transition: 0.5s ease-in;
transition: 0.5s ease-in;
}

No caso, a mudança no hover da propriedade left leva a div um pouco para a esquerda, e o transition suaviza o movimento. Você já deve ter visto muito isso por aí naquelas tabs que movem-se bem devagar ao passar o mouse, em menus, por exemplo.

Cor de fundo em formulários – como qualquer outro elemento, tipo divs, também dá pra usar transitions nas propriedades de CSS em campos de formulário. Clique no campo de formulário na página de exemplo e veja a suave alteração de cor de fundo. O CSS:

input:focus {
background:#CCC;  
-webkit-transition: 0.5s ease-in;
-moz-transition: 0.5s ease-in;
-o-transition: 0.5s ease-in;
transition: 0.5s ease-in;
} 

Tamanho de imagens – com CSS, é só fazer o mesmo processo de alterar o tamanho de uma div, usando a transition em conjunto com as propriedades width e height. No nosso exemplo foi usado:

.imagem {
width: 80px;
height: 100px;
-webkit-transition: 0.5s ease-in;
-moz-transition: 0.5s ease-in;
-o-transition: 0.5s ease-in;
transition: 0.5s ease-in;	
}

.imagem:hover {
width: 269px;
height: 300px;	
}

Foi dada a classe .imagem a nossa imagem (ok, não foi muito original, mas vale a intenção…), e na primeira regra estão altura e largura de exibição normal, além das transições. No hover, muda a altura e largura. A transição é herdada, sendo aplicada tanto no hover quanto ao voltar ao estado normal.

Com outras propriedades CSS – além de combinar as transições com propriedades já bem conhecidas como cor de fundo e tamanhos, use com outras propriedades modernas para conseguir efeitos ainda mais interessantes; dá até pra criar pequenas animações.

Um exemplo bacana: um texto transparente com shadow (sombra), que aparece e fica nítido ao passar o mouse, com transição suave.

.textosombra {
color:transparent;
text-shadow: 0 0 5px #999;
-webkit-transition: 0.5s ease-in;
-moz-transition: 0.5s ease-in;
-o-transition: 0.5s ease-in;
transition: 0.5s ease-in;	
}

.textosombra:hover {
color:#999;
text-shadow:none;
}

O texto foi colocado num parágrafo com a classe “textosombra”. Usamos um text-shadow de CSS3 e o valor “transparent” para a cor do texto, para escondê-lo. Quando passar o mouse (hover) ele fica na cor cinza (#999) e a sombra desaparece (valor none na propriedade text-shadow).

Delay e transições lineares – como você viu, o ease serve para suavizar quase tudo. Acontece que você pode não querer uma animação com desaceleração, e sim contínua, ou que acelera no começo… Para isso existem as propriedades transition-timing-function.

Já com o transition-delay você também pode atrasar o início da transição em um número de segundos (ou microssegundos) especificado.

Veja na página de exemplo a diferença entre as propriedades transition-timing-function, e como cada uma muda as transições.

Para conseguir a animação linear e com atraso, use algo como:

seletor {
-webkit-transition: 3s linear 2s;
-moz-transition: 3s linear 2s;
-o-transition: 3s linear 2s;
transition: 3s linear 2s;
}

Com isso, a transição vai durar 3 segundos (primeiro valor), será linear e terá delay (atraso, no segundo valor) de 2 segundos para ativar. Para conseguir outras transições, é só mudar o linear por outro valor da transition-timing-function (já vimos lá no começo).

Animação e Filtros com Transition

Filtros do WebKit também podem ser usados com transition; vamos ver uma animação básica, em que um personagem recebeu desfoque com o filtro (blur), então vai para a esquerda de seu container com left:100%. Confira na página de exemplo.

O CSS ficou assim:

#animacao { /*div que contém a imagem animada */
width:80%;
height:100px;
}

#animacao img { /* largura e altura da imagem */
width: 80px;
height: 100px;

/* fixar posição à esquerda */
position:relative;
left:0;

/* transition-property apontando filtro e alinhamento */
-webkit-transition-property: -webkit-filter, left;
-moz-transition-property: -moz-filter, left;
-o-transition-property: -o-filter, left;
transition-property: filter, left;

/* transition-duration apontando duração das transições de property marcadas antes */
-webkit-transition-duration: 2s, 2s ;
-moz-transition-duration: 2s, 2s;
-o-transition-duration: 2s, 2s;
transition-duration: 2s,2s;


/* atraso das transições marcadas antes */
-webkit-transition-delay: 0s, 2s ;
-moz-transition-delay: 0s, 2s;
-o-transition-delay: 0s, 2s;
transition-delay: 0s,2s;

/* filtros de navegador aplicados na imagem */
-webkit-filter: blur(10px);
-moz-filter: blur(10px);
-o-filter: blur(10px);
filter: blur(10px);
}

#animacao:hover img { /* filtros de navegador aplicados na imagem ao passar o mouse no container */
-webkit-filter: blur(0px); 
-moz-filter: blur(0px);
-o-filter: blur(0px);
filter: blur(0px);

/* manda a imagem para a outra ponta do container */
left:100%
}

Passo a passo: primeiro a div que contém a imagem animada, com largura quase total (80% da página) e altura igual a da imagem.

Dentro da div foi inserida a imagem, que é afetada pelo seletor CSS img. O #animacao img define sua altura e largura, posição relativa ao container (0 pixels da margem esquerda), e aí entram os transition-property: filter, left;

O primeiro valor afeta o filter, propriedade que aparece depois. Depois da vírgula, outra propriedade que deve ser alterada, a posição left (que foi marcada em 0 no estado inicial, em left:0.

De modo similar, o transition-duration: 2s, 2s, em que os valores determinam a duração de cada transição – como você já viu, serão 2 segundos de duração para a transição do filter, depois mais 2 segundos durante a transição da posição left.

Depois vêm os atrasos com transition-delay: 0s, 2s. 0 segundos para iniciar a transição do filtro (ou seja, começa assim que alguém passa o mouse na imagem), e 2 segundos até começar a alterar a posição left.

Finalmente o filtro do WebKit: blur(10px). Ele aplica desfoque de 10px na imagem em estado normal.

Em #animacao:hover img, as regras para a imagem quando a div recebe o mouse. Só precisamos mudar a posição left (para 100%, assim ela fica a 100% de distância da margem esquerda do container) e a força do filtro, que passou para 0.

Lista de propriedades para transições

Essa é a lista de propriedades que podem ser afetadas pelas transições. Cores, valores integrais como posicionamento e tamanho, sombras e muito mais pode ser visado.

Propriedade O que muda
background-color Cor
background-image Só degradês
background-position Porcentagem, largura
border-bottom-color Cor
border-bottom-width Largura
border-color Cor
border-left-color Cor
border-left-width Largura
border-right-color Cor
border-right-width Largura
border-spacing Largura
border-top-color Cor
border-top-width Largura
border-width Largura
bottom Largura, porcentagem
color Cor
crop Retangular
font-size Largura, porcentagem
font-weight Número
grid-* Diversos
height Largura, porcentagem
left Largura, porcentagem
letter-spacing Largura
line-height Número, largura, porcentagem
margin-bottom Largura
margin-left Largura
margin-right Largura
max-height Largura, porcentagem
max-width Largura, porcentagem
min-height Largura, porcentagem
min-width Largura, porcentagem
opacity Número
outline-color Cor
outline-offset Integer
outline-width Largura
padding-left Largura
padding-right Largura
padding-top Largura
right Largura, porcentagem
text-indent Largura, porcentagem
text-shadow Sombra
top Largura, porcentagem
vertical-align Keywords, largura, porcentagem
visibility Visibilidade
width Largura, porcentagem
word-spacing Largura, porcentagem
z-index Integer
zoom Número

Conclusão

Vale lembrar que você nunca deve usar estilos que não sejam plenamente compatíveis com os navegadores atuais, a não ser de forma experimental como fiz aqui com o filtro do WebKit. Se você aplicar um estilo importante para o aproveitamento da página e o navegador do visitante não renderizar aquilo, você perde um leitor.

Isso não quer dizer que nada seja aproveitável. Transitions já estão bem difundidas e quase todos os navegadores atuais aceitam a propriedade. O Internet Explorer continua sendo o atrasado na história, mas não fique preso no passado por causa dele: só não use estilizações onde regras mais novas como transition sejam imprescindíveis; use-as como um “plus”, algo a mais para os visitantes que já tiveram a feliz decisão de trocar de browser. A versão 10 do velho navegador da Microsoft deve ter suporte total a HTML5 e CSS3.

Fundador do Tutoriart em 2010, é ex-instrutor de Photoshop, design web e gráfico. Em quase uma década de redação online, tem cerca de 1500 artigos publicados. Gerencia também o Memória BIT.

26 Comentários

  1. Olá, Estou fazendo um menu só com CSS3 e preciso de ajuda, gostaria que ele ficasse semelhante ao primeiro item do seu menu, que ao passar o mouse o item “tutoriais” me mostra uma DIV grande com outras DIVs dentro dela, mas, quando passo o mouse por cima do meu exemplo (menu) ao mostrar a DIV oculta eu consigo ver o transition suave, mas quando tiro o mouse a DIV desaparece de maneira rápida e não suavemente como eu gostaria, por favor como resolver isso, me parece ser algo simples mas, eu não sei como resolver, me ajuda aí.

    • Provavelmente é algo como:

      #suadiv, #sua div:hover {efeito}

      O transition deve estar setado só para o hover, aí ao tirar o mouse ele não ativa.

  2. Camilly Santos Responder

    Olá! Eu sei o “transition em movimento” e ele funcionou super bem, mas eu queria ele indo pra cima, alguém pode me ajudar? Eu já troquei o left:30px; por left:30px; mas não adiantou

    • Oi, Camilly! O “left” é pra movimento da esquerda pra direita. Você tem que usar “top”, exemplo: #divmove:hover {top: 30px; etc…

      Lembrando que “top” é a distância do elemento em relação ao topo do elemento-pai.

  3. Bons efeitos, mas eu não consegui deixar o meu hover suave.
    Eu quero fazer o seguinte:
    div#menu > ul > li.has-sub:hover .sub_ul{

    }

    Eu quero usar o hover para exibir uma ul ou uma div suavemente, mas não funciona.

    • Vixe, que confusão de classes aí hein? Pode ser que você esteja “errando o alvo”.

  4. Parabéns pelo post, muito bom. Respondendo a dúvida do Gabriel você também já respondeu a minha dúvida. Muito Obrigado! Obs: Gostei do seu site todo responsivo.

  5. Muito bons esses efeitos, Daniel. Parabéns pelo post! Só fiquei com uma dúvida, se puder me ajudar, fico agradecido. O efeito transition pode ser aplicado a uma div com “display: none”? Pq acontece o seguinte: eu tenho uma div com display none e quero aplicar esse efeito no momento em que ativá-la ao display: block, para ela não aparecer de repente, como se piscasse na tela, mas de forma mais suave. Isso seria possível?

    Obrigado!

    • Oi Gabriel, obrigado. Com certeza não funciona com o display, mas tem uma abordagem aqui http://stackoverflow.com/questions/3331353/transitions-on-the-display-property que sugere usar o seletor .active de CSS.

      Ou seja, não usar display:none e sim opacity 0 e depois opacity:1 quando a div estiver “active”. Não se servirá pro seu caso.

      Algo assim:
      div {
      display: block;
      -webkit-transition: opacity 1s ease-out;
      opacity: 0;
      height: 0;
      overflow: hidden;
      }

      div.active {
      opacity: 1;
      height: auto;
      }

  6. Olá amigo, achei muito interessante e muito útil sua explicação sobre transições com CSS. Quero saber se pode me ajudar, fiz uma aplicação web (c#, .Net4) para uma amigo e na parte superior na master page deixei uma div fixa para que o usuário possa escolher qual imagem deseja usar como fundo, esta div tem 180px de altura máxima e a imagem que vai dentro sempre terá sua altura padrão e largura máxima de 800px, mas sabemos que as fotos sempre terão mais que isso. Então eu gostaria de uma solução que deixasse a imagem rolando no sentido vertical, de cima para baixo e retorna ao topo, constantemente.. achei algumas dicas na web mas todas elas dependem da ação do hover, eu gostaria de deixar algo constante. Você tem alguma dica especial para isso? Para você ter uma idéia visual, veja a tela de perfil do facebook onde fica a imagem de fundo, a idéia é a mesma mas que a imagem fique rolando e não estática. Já tentei fixar a imagem mas desfoca ou a posição de 180px de altura mostra uma parte apenas na foto. A principio o que eu fiz foi altera a propriedade margen para um valor negativo para (mais ou menos) centralizar no meio da foto.
    Ufa… valeu pela sua paciência e obrigado se puder ajudar.

  7. Daniel, vc poderia me ajudar solucionar um problema? É o seguinte: não estou conseguindo aplicar o efeito de transição numa DIV contendo o efeito GRADIENTE. Poderia me ajudar.

    Abaixo o código:

    nav ul li a:hover {width: 8em;
    height: 6.5em;
    padding: 0 1em;
    display: block;
    background-image: -webkit-gradient(
    linear, left top, left bottom, from(rgba(80,80,80,0.2)),
    to(rgba(50,50,50,0.8)));

    -webkit-transition: all 1s ease-in-out;
    -moz-transition: all 0.5s ease-in-out;
    -ms-transition: all 0.5s ease-in-out;
    -o-transition: all 0.5s ease-in-out;
    transition: all 0.5s ease-in-out;}

    • Pesquisei mais e parece que gradients não tem suporte para animações em CSS, Rogério, vou até removê-lo da lista de compatibilidade que postei.

      Tem um método alternativo, em que anima-se o background sólido deixando um degradê por cima, assim:

      .nav ul li a {
      width: 8em;
      height: 6.5em;
      padding: 0 1em;
      display: block;
      
      background-color: #dbdbdb;
      background-image: -webkit-gradient(linear, left top, left bottom,color-stop(0%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(0, 0, 0, 0.6)));
      -webkit-transition: all 1s ease-in-out;
      -moz-transition: all 0.5s ease-in-out;
      -ms-transition: all 0.5s ease-in-out;
      -o-transition: all 0.5s ease-in-out;
      transition: all 0.5s ease-in-out;
      }
      
      .nav ul li a:hover {
      width: 8em;
      height: 6.5em;
      padding: 0 1em;
      display: block;
      
      background-color: #353535;
      }
      

      Mais exemplos aqui: http://lab.tylergaw.com/css-gradient-transition-sorta/

  8. Amigo, boa tarde.
    Preciso fazer uma transição de imagens, porem sem colocar o mouse em cima.
    Ela teria que fazer de forma automática.
    TEM ALGUMA ALTERAÇÃO NO CODIGO PARA ISSO???

  9. @Daniel na página inicial tem continue lendo,gostaria de aplicar esse efeito,mas como é imagem não consegui até o momento.
    Fora que demora um pouco para ver as alterações,já que uso o cloud flare.

    Abraço!

  10. @Tentei colocar no continue lendo que é uma imagem,mas não muda nada.Pensei que era o cloud flare,mas sempre limpo pelo w3 total cache e pela minha conta na cloudflare.

    Fiz o da div,não sei se era o correto.

  11. Olá Daniel!

    Estava procurando a respeito desse efeito,já vou testar em meu blog no readmore…

    Abraço!

    P.S. Cliquei em curtir e dá um erro,não na hora de curtir,mas sim como aparece na timeline de quem curtiu.Então copie e colei o link.

Deixe um Comentário

Pin