Existe alguma maneira de animar uma elipse com animações CSS?

95

Estou tentando fazer uma animação de reticências e gostaria de saber se isso seria possível com animações CSS ...

Então pode ser como

Loading...
Loading..
Loading.
Loading...
Loading..

E basicamente continue assim. Alguma ideia?

Editar: assim: http://playground.magicrising.de/demo/ellipsis.html

Rey
fonte
3
Animações não são transformações, não são transições. Por favor, não confunda os três.
BoltClock
Veja minha resposta a uma pergunta semelhante: stackoverflow.com/a/24349758/282729
feklee

Respostas:

90

Que tal uma versão ligeiramente modificada da resposta de @xec : http://codepen.io/thetallweeks/pen/yybGra

HTML

Uma única classe adicionada ao elemento:

<div class="loading">Loading</div>

CSS

Animação que usa steps. Veja os documentos MDN

.loading:after {
  overflow: hidden;
  display: inline-block;
  vertical-align: bottom;
  -webkit-animation: ellipsis steps(4,end) 900ms infinite;      
  animation: ellipsis steps(4,end) 900ms infinite;
  content: "\2026"; /* ascii code for the ellipsis character */
  width: 0px;
}

@keyframes ellipsis {
  to {
    width: 20px;    
  }
}

@-webkit-keyframes ellipsis {
  to {
    width: 20px;    
  }
}

A resposta de @xec tem mais efeito de deslizamento nos pontos, enquanto isso permite que os pontos apareçam instantaneamente.

as semanas todas
fonte
1
Quer dizer, você respondeu 3 anos depois, mas provavelmente é melhor.
Rey
3
@ xckpd7 sim, mas pesquisei isso no Google hoje e acabei de encontrar a resposta. O SO não é apenas para o OP, é um recurso para todos!
Matt Parrilla
1
@MattParrilla Eu sou o OP, e se você percebeu, mudei a resposta Aceito para esta antes de fazer esse comentário.
Rey
10
Se você estiver usando isso em um texto centralizado ou alinhado à direita, sugiro adicionar uma inicial margin-right(ou preenchimento?) De 20pxe animá-lo 0pxse não quiser que o texto seja alterado durante a animação.
Kimball de
1emno lugar de 20pxpode funcionar melhor para o CSS nesta resposta
Jeevan Takhar
57

Você pode tentar usar o animation-delay propertytempo e cada caractere de reticências. Neste caso, coloquei cada caractere de reticências em um<span class> para poder animá-los separadamente.

Fiz uma demonstração , que não é perfeita, mas mostra pelo menos o que quero dizer :)

O código do meu exemplo:

HTML

Loading<span class="one">.</span><span class="two">.</span><span class="three">.</span>

CSS

.one {
    opacity: 0;
    -webkit-animation: dot 1.3s infinite;
    -webkit-animation-delay: 0.0s;
    animation: dot 1.3s infinite;
    animation-delay: 0.0s;
}

.two {
    opacity: 0;
    -webkit-animation: dot 1.3s infinite;
    -webkit-animation-delay: 0.2s;
    animation: dot 1.3s infinite;
    animation-delay: 0.2s;
}

.three {
    opacity: 0;
    -webkit-animation: dot 1.3s infinite;
    -webkit-animation-delay: 0.3s;
    animation: dot 1.3s infinite;
    animation-delay: 0.3s;
}

@-webkit-keyframes dot {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

@keyframes dot {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
Christofer Vilander
fonte
Eu gosto dessa ideia e apenas a expandi um pouco para mostrar "elipses em marcha": jsfiddle.net/toddwprice/cRLMw
Todd Price
Não funcionou (?), Então adicionei display: inline; e então os pontos. É assim que deveria funcionar? jsfiddle.net/cRLMw/3
Christofer Vilander
4
Desculpe @Christofer - esqueci de salvar meu violino atualizado. Aqui está novamente: jsfiddle.net/toddwprice/cRLMw/8 Além disso, aqui está um artigo que acabei de ler que tem algumas animações CSS interessantes: tympanus.net/Tutorials/LoadingAnimations/index4.html
Todd Price
Usando o Firefox, não consigo arrastar se eu simplesmente clicar e arrastar a imagem em uma foto. Mas se eu clicar primeiro na imagem e depois clicar e arrastar, não sou impedido de arrastar.
Sam Rueby
2
Ajustei um pouco o HTML e o CSS para usar tags <i> ... jsfiddle.net/DkcD4/77
Adam Youngers
32

Mesmo uma solução mais simples, funciona muito bem!

<style>
    .loading:after {
      display: inline-block;
      animation: dotty steps(1,end) 1s infinite;
      content: '';
    }

    @keyframes dotty {
        0%   { content: ''; }
        25%  { content: '.'; }
        50%  { content: '..'; }
        75%  { content: '...'; }
        100% { content: ''; }
    }
</style>
<div class="loading">Loading</div>

Acabei de editar o conteúdo com animação em vez de esconder alguns pontos ...

Demonstração aqui: https://jsfiddle.net/f6vhway2/1/


Edit: Obrigado a @BradCollins por apontar que contentnão é uma propriedade animável.

https://www.w3.org/TR/css3-transitions/#animatable-css

Portanto, esta é uma solução apenas para WebKit / Blink / Electron. (Mas também funciona nas versões FF atuais)

CodeBrauer
fonte
Eu estava olhando este tópico na semana passada. Boa resposta simples!
r8n5n
1
1 para animação content. Para obter um ritmo de animação uniforme, você deve usar steps(1)e definir um quadro-chave extra. A função step determina o número de etapas entre os quadros principais e, como estamos especificando cada quadro, queremos apenas uma única etapa entre eles. codepen.io/anon/pen/VmEdXj
Jeff Camera
Embora eu adore a elegância dessa solução, deve-se observar que o IE11 e (no momento da redação deste artigo) o Firefox não suportam a animação da contentpropriedade. (Não sei sobre o Edge.)
Brad Collins
@BradCollins obrigado por isso! Eu editei minha resposta!
CodeBrauer
15

A resposta curta é "não realmente". No entanto, você pode brincar com a animação de largura e estouro oculto e talvez obter um efeito que seja "próximo o suficiente". (código abaixo adaptado apenas para firefox, adicione prefixos do fornecedor conforme necessário).

html

<div class="loading">Loading</div>

css

.loading:after {
    overflow: hidden;
    display: inline-block;
    vertical-align: bottom;
    -moz-animation: ellipsis 2s infinite;
    content: "\2026"; /* ascii code for the ellipsis character */
}
@-moz-keyframes ellipsis {
    from {
        width: 2px;
    }
    to {
        width: 15px;
    }
}

demonstração: http://jsfiddle.net/MDzsR/1/

editar

Parece que o cromo tem problemas com a animação do pseudoelemento. Uma solução fácil é envolver a elipse em seu próprio elemento. Confira http://jsfiddle.net/MDzsR/4/

xec
fonte
Não está funcionando no Chromium (sim, mudei o prefixo do fornecedor para -webkitde -moz).
David diz para restabelecer Monica em
@DavidThomas você está certo - testado no Chrome agora e parece que tem problemas com o pseudoelemento. Você poderia envolver as reticências em seu próprio elemento e animá-lo (funcionaria no firefox também) jsfiddle.net/MDzsR/4
xec
1
Uma solução muito boa e perfeita para um aplicativo do Firefox OS que estou desenvolvendo. Ajustou um pouco: jsfiddle.net/feklee/x69uN
feklee
Aqui está uma versão melhorada que funciona no Chrome, bem como funciona corretamente com elementos não alinhados à esquerda (não altera a largura). Além disso, ele mostra cada ponto consecutivamente, sem este artefato revelador deslizante: jsfiddle.net/fze2qxsv
Aayla Secura
@AaylaSecura A resposta aceita tem uma solução mais limpa usando etapas em vez de stackoverflow.com/a/28074607/833146
xec
4

Uma adição tardia, mas descobri uma maneira de fazer isso que oferece suporte a texto centralizado.

<element>:after {
    content: '\00a0\00a0\00a0';
    animation: progress-ellipsis 5s infinite;
}

@keyframes progress-ellipsis {
    0% {
        content: '\00a0\00a0\00a0';
    }
    30% {
        content: '.\00a0\00a0';
    }
    60% {
        content: '..\00a0';
    }
    90% {
        content: '...';
    }
}
anon-e-mouse
fonte
3

Você pode animar clip(ou melhor, clip-pathse não precisar do suporte do IE)

div {
  position: relative;
  display: inline-block;
  font-size: 1.4rem;
}

div:after {
  position: absolute;
  margin-left: .1rem;
  content: ' ...';
  display: inline-block;
  animation: loading steps(4) 2s infinite;
  clip: rect(auto, 0px, auto, auto);
}

@keyframes loading {
  to {
    clip: rect(auto, 20px, auto, auto);
  }
}
<div>Loading</div>

Jakob E
fonte
1

Bem, na verdade existe uma maneira pura de CSS de fazer isso.

Peguei o exemplo do CSS Tricks, mas fiz também para ser compatível com o Internet Explorer (testei no 10+).

Verifique a demonstração: http://jsfiddle.net/Roobyx/AT6v6/2/

HTML:

<h4 id="searching-ellipsis"> Searching
    <span>.</span>
    <span>.</span>
    <span>.</span>
</h4>

CSS:

@-webkit-keyframes opacity {
  0% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
    opacity: 1;
  }
  100% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    opacity: 0;
  }
}

@-moz-keyframes opacity {
  0% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
    opacity: 1;
  }

  100% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    opacity: 0;
  }
}

@-webkit-keyframes opacity {
  0% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
    opacity: 1;
  }
  100% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    opacity: 0;
  }
}

@-moz-keyframes opacity {
  0% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
    opacity: 1;
  }
  100% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    opacity: 0;
  }
}

@-o-keyframes opacity {
  0% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
    opacity: 1;
  }
  100% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    opacity: 0;
  }
}

@keyframes opacity {
  0% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
    opacity: 1;
  }
  100% {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    opacity: 0;
  }
}
#searching-ellipsis span {
  -webkit-animation-name: opacity;
  -webkit-animation-duration: 1s;
  -webkit-animation-iteration-count: infinite;
  -moz-animation-name: opacity;
  -moz-animation-duration: 1s;
  -moz-animation-iteration-count: infinite;
  -ms-animation-name: opacity;
  -ms-animation-duration: 1s;
  -ms-animation-iteration-count: infinite;
}
#searching-ellipsis span:nth-child(2) {
  -webkit-animation-delay: 100ms;
  -moz-animation-delay: 100ms;
  -ms-animation-delay: 100ms;
  -o-animation-delay: 100ms;
  animation-delay: 100ms;
}
#searching-ellipsis span:nth-child(3) {
  -webkit-animation-delay: 300ms;
  -moz-animation-delay: 300ms;
  -ms-animation-delay: 300ms;
  -o-animation-delay: 300ms;
  animation-delay: 300ms;
}
MRadev
fonte
Você está adicionando filtros proprietários apenas do IE em quadros-chave específicos do mozilla e do webkit. Como isso é uma melhoria em relação à solução já aceita? Ele ainda tem o mesmo problema (nos frames 4 e 5 apenas os dois últimos e os últimos pontos são visíveis, respectivamente, ao contrário do que está delineado na pergunta, que tem 3 estados repetidos, não 5)
x de
A questão é sobre a criação de pontos de carregamento, e há apenas um exemplo próximo, não obrigatório. O que adicionei são prefixos, para que o IE possa reconhecê-los melhor e exibi-los.
MRadev
3
-webkit-keyframessó se aplica ao webkit, e dentro de você tem código apenas do IE. Este código não faz nada além de desperdiçar espaço.
x
0

Aqui está minha solução com css puro https://jsfiddle.net/pduc6jx5/1/ explicado: https://medium.com/@lastseeds/create-text-ellipsis-animation-with-pure-css-7f61acee69cc

scss



.dot1 {
 animation: visibility 3s linear infinite;
}

@keyframes visibility {
 0% {
 opacity: 1;
 }
 65% {
 opacity: 1;
 }
 66% {
 opacity: 0;
 }
 100% {
 opacity: 0;
 }
}

.dot2 {
 animation: visibility2 3s linear infinite;
}

@keyframes visibility2 {
 0% {
  opacity: 0;
 }
 21% {
  opacity: 0;
 }
 22% {
  opacity: 1;
 }
 65% {
  opacity: 1;
 }
 66% {
  opacity: 0;
 }
 100% {
  opacity: 0;
 }
}

.dot3 {
 animation: visibility3 3s linear infinite;
}

@keyframes visibility3 {
 0% {
  opacity: 0;
 }
 43% {
  opacity: 0;
 }
 44% {
  opacity: 1;
 }
 65% {
  opacity: 1;
 }
 66% {
  opacity: 0;
 }
 100% {
  opacity: 0;
 }
}

html

Loading <span class="dot dot1">.</span><span class="dot dot2">.</span><span class="dot dot3">.</span>
repo
fonte