有没有一种使用CSS动画来使省略号发生动画的方法?

140

我正在尝试让省略号动画化,想知道是否可以使用CSS动画实现...

就像这样

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

然后就像那样继续进行。有任何想法吗?

编辑:像这样:http://playground.magicrising.de/demo/ellipsis.html


3
动画、变形和过渡是三个不同的概念,请不要混淆它们。 - BoltClock
1
请参考我对类似问题的答案:https://dev59.com/VmUp5IYBdhLWcg3wRWFD#24349758 - feklee
10个回答

137

这里是稍作修改的版本,基于@xec的答案http://codepen.io/thetallweeks/pen/yybGra

CSS动画使用steps。请参考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: 40px;
  }
}

@-webkit-keyframes ellipsis {
  to {
    width: 40px;
  }
}
<h1 class="loading">Loading</h1>

@xec的答案更像是滑入效果,而这个效果可以让圆点立即出现。


3
我明白,您是指您之前回答了这个问题,但是现在的回答可能更好。 - Rey
8
是的,但我今天在谷歌上搜到了这个答案。SO不仅仅是给提问者提供资源,它也是给大家提供资源! - Matt Parrilla
1
@MattParrilla 我是楼主,如果你注意到了,我在发表那条评论之前已经将我接受的答案改成了这个。 - Rey
12
如果你要在居中或右对齐的文本上使用此代码,我建议添加一个初始的margin-right(或padding?)为20px,并在动画期间将其动画化为0px,以避免文本在动画期间移位。 - Kimball
在这个答案的CSS中,使用1em代替20px可能效果更好。 - Jeevan Takhar
不确定这个答案比@CodeBrauer的答案更好在哪里。上面的答案对我不起作用,而且我也看不出为什么它会起作用。display: inline-block;实际上完全隐藏了文本。 - rm.rf.etc

79

甚至更简单的解决方案也能很好地工作!

<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>

将内容改为以动画方式显示而不是隐藏一些点...

演示在此处:https://jsfiddle.net/f6vhway2/1/


编辑: 感谢@BradCollins指出content不可动画化的属性

目前(2021年),这适用于Chrome/WebKit/Blink/Electron和Firefox以及新版本的Edge。


1
我上周刚看过这个帖子。很简单明了的答案! - r8n5n
2
+1 用于为 content 添加动画效果。为了获得均匀的动画节奏,您应该使用 steps(1) 并定义一个额外的关键帧。步骤函数决定了关键帧之间的步数,由于我们正在指定每一帧,因此我们只需要在它们之间进行单个步骤。http://codepen.io/anon/pen/VmEdXj - Jeff Camera

65
你可以尝试使用animation-delay 属性并计时每个省略号字符。在这种情况下,我将每个省略号字符都放在一个 <span class>中,以便可以单独进行动画处理。

我制作了一个演示,虽然不是完美的,但至少展示了我的意思 :)

我的示例代码:

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

我喜欢这个想法,只是稍微扩展了一下,展示了“行进的椭圆形”:http://jsfiddle.net/toddwprice/cRLMw/ - Todd Price
它没有起作用(?), 所以我添加了display: inline; 然后加上了点。这是它应该的工作方式吗?http://jsfiddle.net/cRLMw/3/ - Christofer Vilander
4
抱歉 @Christofer - 我忘记保存我更新的小样式了,这是它的链接:http://jsfiddle.net/toddwprice/cRLMw/8/此外,这是我刚读到的一篇文章,其中有一些有趣的CSS动画:http://tympanus.net/Tutorials/LoadingAnimations/index4.html - Todd Price
使用Firefox时,如果我仅仅点击并拖动图像,它就无法被拖动。但是,如果我先点击图像,然后再点击并拖动,就可以顺利地进行拖动操作。 - Sam Rueby
2
我稍微调整了HTML和CSS,使用<i>标签... http://jsfiddle.net/DkcD4/77/ - Adam Youngers

18

简短的回答是“不太可能”。但是,你可以尝试使用动画宽度和溢出隐藏进行实验,或许可以获得足够接近的效果。(下面的代码仅适用于火狐浏览器,请根据需要添加供应商前缀)。

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

演示:http://jsfiddle.net/MDzsR/1/

编辑

Chrome似乎存在与伪元素动画的问题。一个简单的解决方法是将省略号包裹在自己的元素中。请查看http://jsfiddle.net/MDzsR/4/


在Chromium中无法工作(是的,我将供应商前缀从“-moz”更改为“-webkit”)。 - David Thomas
@DavidThomas 你说得对 - 现在在Chrome中测试,似乎它与伪元素存在问题。您可以将省略号包装在自己的元素中,然后对其进行动画处理(在Firefox中也可以工作)http://jsfiddle.net/MDzsR/4/ - xec
1
非常棒的解决方案,非常适合我正在开发的Firefox OS应用程序。稍微调整了一下:http://jsfiddle.net/feklee/x69uN/ - feklee
1
这是一个改进版本,可以在Chrome上运行,并且可以正确处理非左对齐元素(不会改变宽度)。此外,它连续显示每个点,没有滑动揭示的痕迹:http://jsfiddle.net/fze2qxsv/ - Aayla Secura
@AaylaSecura 我根据你的想法解决了这个问题:https://dev59.com/H2cs5IYBdhLWcg3wPxnN#75179539 - nh2
显示剩余2条评论

9
一个晚期的补充,但我找到了一种方法来支持居中文本。
<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: '...';
    }
}

我会将百分比均匀地分开,0%,25%,50%,75%,然后将缓动函数设置为“linear”。更容易理解。 - Victor Zamanian

4

如果您不需要支持IE浏览器,可以使用clip-path代替clip进行动画效果。

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

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

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


3

实际上,有一种使用纯CSS的方法来做到这一点。

我从CSS Tricks获取了这个例子,但也使其在Internet Explorer中得到支持(我已在10+中测试过)。

点击查看演示: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;
}

你在 Mozilla 和 Webkit 的特定关键帧中添加专有的 IE-only 过滤器。这种做法怎样改进已经被接受的解决方案呢?它甚至存在相同的问题(第 4 和第 5 帧仅显示最后两个点和最后一个点,与问题中的概述不同,后者具有 3 个重复状态而不是 5 个)。 - xec
问题是关于创建加载点,仅有一个接近的示例,不是必须的。我所添加的是前缀,这样IE可以更好地识别它并显示它。 - MRadev
4
“-webkit-keyframes” 只适用于 Webkit,并且在其中您有一个仅适用于 IE 的代码。这段代码除了浪费空间之外没有任何作用。 - xec

1
我发现clip-path最清晰,具有以下好处:

不使用width,因此:

  • 不受所使用字体中省略号的宽度影响(无论宽度如何都能工作)。
  • 不会改变布局(对于性能好,允许更多的文本隐藏在其后,而不会移动或重新排列)。

.loading-ellipsis:after {
    overflow: hidden;
    display: inline-block;
    vertical-align: bottom;
    animation: ellipsis-animation steps(1,end) 2s infinite;
    content: "\2026"; /* ascii code for the ellipsis character */
    /* Enable this to see what is going on: */
    /* background-color: red; */
}

@keyframes ellipsis-animation {
    0%  { clip-path: inset(0 100% 0 0); }
    25% { clip-path: inset(0 66.6% 0 0); }
    50% { clip-path: inset(0 33.3% 0 0); }
    75% { clip-path: inset(0 0 0 0); }
}
<span class="loading-ellipsis">Loading</span> More text behind it that does not move

荣誉归功于@AaylaSecura的评论,我改进了它以使用steps(1,end)。这是有效的,因为我将动画结束时设置为75%,这样最后一步就显示了省略号(第三个点)的完全展开。
(其中有一个隐含的100% { clip-path: inset(0 0 0 0); },不需要写出来。)

0

我完全按照{{link1:@CodeBrauer}所做的那样,但因为我的文本是text-align:center(这也适用于right),而且我不想让文本每次添加句号时都移动,所以我添加了“标点空格”:

<style>
    .loading::after {
      display: inline-block;
      animation: dotty steps(1,end) 1s infinite;
      content: '';
    }
    
    @keyframes dotty {
      0%   { content: '\2008\2008\2008'; }
      25%  { content: '.\2008\2008'; }
      50%  { content: '..\2008'; }
      75%  { content: '...'; }
      100% { content: '\2008\2008\2008'; }
    }
</style>
<div class="loading">Loading</div>

0
这是我的纯CSS解决方案https://jsfiddle.net/pduc6jx5/1/,并且有解释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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接