我有一个闪烁的光标动画,其中设置了两行文本。
我希望光标随着文本的出现而出现,并在第一行的结尾处消失-但在 second 行的结尾处闪烁。
有人问了一个非常类似的问题,但是解决方案使光标完全不可见:
Stopping a blinking cursor at end of css animation
(在多个浏览器上)测试了此答案代码,但它不起作用。
这就是我所拥有的:
代码:
.typewriter1 p {
overflow: hidden;
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
@keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
@keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
@keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent;
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>
答案 0 :(得分:2)
目前仅对示例2进行了详细说明。示例3与问题的HTML和CSS完全相同,只是做了些微改动。
首先,我们可以清理HTML。这是一个段落,所以让我们将其包装在一个段落元素中:
<p class="typewriter">
A well defined plan will identify problems,
address challenges, and help restore confidence.
</p>
第二,我们需要单独显示每行,因此我们将每行包裹在一个嵌套的span元素中,并使用换行符手动将其折断:
<p class="typewriter">
<span class="slide">
<span class="inner-slide">A well defined plan will identify problems,
</span>
</span><br>
<span class="slide">
<span class="inner-slide">address challenges, and help restore confidence. </span>
</span>
</p>
当前限制:我们必须为left
设置固定的像素宽度。
.typewriter {
position: relative;
height: 500px;
margin: 0 auto;
width: 310px;
overflow: hidden;
}
.typewriter .slide,
.inner-slide {
display: inline-block;
overflow: hidden;
height: 1.1em;
}
.typewriter .slide {
position: relative;
animation: typing 2s steps(30, end) forwards, blink-caret .75s step-end infinite;
left: -310px;
border-right: .15em solid transparent;
}
.typewriter .slide:nth-of-type(1) {
animation: typing 2s steps(30, end) forwards, blink-caret .75s step-end 2.6;
}
.inner-slide {
position: relative;
animation: typing2 2s steps(30, end) forwards;
white-space: nowrap;
left: 310px;
}
.typewriter .slide:nth-of-type(2),
.typewriter .slide:nth-of-type(2) .inner-slide {
animation-delay: 2s;
}
@keyframes typing {
from {
left: -310px;
}
to {
left: 0;
}
}
@keyframes typing2 {
from {
left: 310px;
}
to {
left: 0;
}
}
/*The typewriter cursor effect */
@keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
body {
background: linear-gradient(to bottom right, #CCC 0, #F00 100%) no-repeat;
}
<p class="typewriter">
<span class="slide">
<span class="inner-slide">A well defined plan will identify problems,
</span>
</span><br>
<span class="slide">
<span class="inner-slide">address challenges, and help restore confidence.</span>
</span>
</p>
首先,我们可以清理HTML。这是一个段落,所以让我们将其包装在一个段落元素中:
<p class="typewriter">
A well defined plan will identify problems,
address challenges, and help restore confidence.
</p>
第二,我们需要单独显示每行,因此将每行包装在span元素中,并使用换行符手动将其折断:
<p class="typewriter">
<span>A well defined plan will identify problems,</span><br>
<span> address challenges, and help restore confidence.</span>
</p>
现在,我们需要一个元素来覆盖我们的文本并充当动画光标。我们可以使用从100%宽度开始并具有左边框的伪元素,如下所示:
.typewriter > span::before {
content: '';
border-left: .15em solid #00aeff;
position: absolute;
background: white;
height: 1.1em;
right: -5px;
width: 100%;
}
overflow-hidden
,光标不会显示在第一行。 为了使光标停留在最后一行,我们需要给它一个0右值:
.typewriter > span:last-of-type::before {
right: 0;
}
现在它将不再被拉到父级之外。
第二行需要延迟与动画运行时间相同的时间:
.typewriter > span:nth-of-type(2)::before {
animation-delay: 2s;
}
因为我们希望段落的宽度由文本的宽度和跨度来确定,所以我们需要将它们设置为内联块:
.typewriter,
.typewriter > span {
display: inline-block;
}
最后,我们将打字动画从100%变为0:
@keyframes typing {
from {
width: 100%
}
to {
width: 0
}
}
.typewriter,
.typewriter > span {
display: inline-block;
}
.typewriter > span {
position: relative;
overflow: hidden;
padding-right: 4px;
}
.typewriter > span::before {
content: '';
position: absolute;
border-left: .15em solid #00aeff;
background: white;
height: 1.1em;
right: -5px;
width: 100%;
animation: blink-caret .75s step-end infinite, typing 2s steps(30, end) forwards;
}
.typewriter > span:nth-of-type(2)::before {
animation-delay: 2s;
}
.typewriter > span:last-of-type::before {
right: 0;
}
/* The typing effect*/
@keyframes typing {
from {
width: 100%
}
to {
width: 0
}
}
/*The typewriter cursor effect */
@keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent
}
}
<p class="typewriter">
<span>A well defined plan will identify problems,</span><br>
<span> address challenges, and help restore confidence.</span>
</p>
根据第一行插入符更改迭代计数。在此示例中,值为4.1。此动画将迭代4.1次,然后停止:
animation: blink-caret .75s step-end 4.1
创建插入符号的边框已更改为透明:
border-right: .15em solid transparent
动画被翻转:
@keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
现在,停止状态是透明的,第一行将在第一行消失。
body {
width: 330px;
}
.typewriter1 p {
overflow: hidden;
border-right: .15em solid transparent;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end 4.1;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid transparent;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
@keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
@keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
@keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>
答案 1 :(得分:0)
我刚刚将.typewriter1 p {
从.typewriter1 p {
overflow: hidden;
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end 5;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
@keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
@keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
@keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent;
}
}
更改为5。
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>
{{1}}
答案 2 :(得分:0)
如果您不一定要为此编写自己的动画,那么TypeIt(https://typeitjs.com)API可以使自定义代码更少:
https://codepen.io/alexmacarthur/pen/MWWEPxa
const secondInstance = new TypeIt('.typewriter2 p');
const firstInstance = new TypeIt('.typewriter1 p', {
afterComplete: function (instance) {
document.querySelector('.typewriter1 p .ti-cursor').remove();
secondInstance.go();
}
}).go();
此方法的唯一缺点是您对动画本身的控制较少(您需要覆盖库提供的CSS动画)。