After going through the w3schools documentation and taking @AHaworth, @Yogi, and @alvinalvord's solutions, I have ended up with an answer myself. I would like to thank you all for your involvement.
The typewriter effect is a bit challenging when it comes to multiple elements with the conditions set by me:
By combining CSS properties like visibility
, nth-child(n)
, animation-fill-mode
I was able to achieve what I desired:
:root {
--typing-effect: typing 2s steps(24, end);
--blink-effect: blink 1s step-end;
}
.typewriter {
font-family: monospace;
display: flex;
justify-content: center;
font-size: 1.5rem;
}
.typewriter p {
overflow: hidden;
/* Ensures text doesn't overflow */
white-space: nowrap;
/* Prevents text from wrapping */
border-right: 2px solid black;
/* Simulates a typing cursor */
visibility: hidden;
width: fit-content;
}
/* Typing animation */
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink { 50% { border-color: transparent; }}
/* Hide the cursor at the end. */
@keyframes hide { to { border-color: transparent; }}
/* Shows only after the previous animation is complete */
@keyframes show {
from { visibility: hidden; }
to { visibility: visible; }
}
/* Applying the animation */
p:nth-child(1) {
visibility: visible;
animation: var(--typing-effect), var(--blink-effect), hide 2s step-end;
/* Adjust based on text length */
animation-fill-mode: forwards;
}
p:nth-child(2) {
animation: show 0s 2s, var(--typing-effect) 2s, var(--blink-effect), hide 4s step-end;
/* Adjust based on text length */
animation-fill-mode: forwards;
}
p:nth-child(3) {
animation: show 0s 4.2s forwards, var(--typing-effect) 4.2s, var(--blink-effect) infinite;
}
<div class="typewriter">
<div>
<p>Hello, Welcome to stack overflow!</p>
<p>Let's get started!</p>
<p>Good Morning Peers!</p>
</div>
</div>
The visibility:hidden
property ensures subsequent lines remain hidden until their animations start.
The nth-child(n)
selector synchronizes the animations for each line.
The animation-fill-mode:forwards
keeps the lines visible after typing.
Even though I have achieved what I wanted, there are still some issues with the spacing. If you run the snippet you can see that the cursor extends to the full-width of the element even though I have set width: fit-content
to all <p>
elements.
If anyone can solve this problem, it would be a great help.