.typewriter h1 {
overflow: hidden; /* Ensures the content is not revealed until the animation */
border-right: .15em solid orange; /* The typwriter cursor */
white-space: nowrap; /* Keeps the content on a single line */
margin: 0 auto; /* Gives that scrolling effect as the typing happens */
letter-spacing: .15em; /* Adjust as needed */
animation:
typing 3.5s steps(40, end),
blink-caret .75s step-end infinite;
}
/* The typing effect */
@keyframes typing {
from { width: 0 }
to { width: 100% }
}
/* The typewriter cursor effect */
@keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: orange; }
}
Notes:
- Demo relies on flexbox, so that could affect the layout in testing
- Assumes the use of Autoprefixer
- The width of the text container will be determined by the length of the text being used
- Adding more steps to the
typing
animation will increase the smoothness of the typing - Adjust the
letter-spacing
based on the font-family and font-size being used
More!
Some use JavaScript, which may sometimes be preferable (literally adding a character at a time feels more like a real typewriter) and sometimes not be (potential accessibility concerns).
Typed.css
Came across this SCSS @mixin from Brandon McConnell with powerful options that can identify multiple strings, speed, caret configurations, pauses, and all kinds of other things.
Very clever way to do this with pure CSS.
I actually wrote a jQuery plugin a while back (http://macarthur.me/typeit) that does this same thing with a few more features for customization, but it’s obviously dependent on jQuery. I might pull a few tips from your JS examples if I ever want to make a vanilla JS version — particularly the CSS injection idea. Some of it relies on jQuery to do what CSS animations could do natively, and I’d like to see that changed.
Wow this is awesome! Thanks for sharing!
Is this still available somewhere? I’d love to see it and the page is no longer available.
Sorry, I moved the site to a dedicated URL and it looks like the redirect was down for a while.
The new location is https://typeitjs.com, but that redirect should also be working now.
// Love dynamically typed text? You’re gonna love this
// Edit these strings to see them typed on the screen:
$strings: (
“CSS typed this string!”
“It typed this one too ”
“Enjoy ☕”
);
// now for some timing (all in seconds)
$durCharFwd: 0.10; // character typed
$durFullGap: 5.00; // time between typed/delete
$durCharBwd: 0.08; // character deleted
$durDoneGap: 5.20; // time between strings
// initializing some variables and functions ✊
$charCount: 0; $durTotal: 0;
@each $string in $strings {
$charCount: $charCount + str-length($string);
$durTotal: $durTotal
+ (str-length($string) * ($durCharFwd + $durCharBwd))
+ $durFullGap + $durDoneGap;
}
@function percent($string, $letter) {
$stringsPast: $string – 1; $time: 0;
@while $stringsPast > 0 {
$time: $time
+ (($durCharFwd + $durCharBwd) * (str-length(nth($strings, $stringsPast))))
+ $durFullGap + $durDoneGap;
$stringsPast: $stringsPast – 1;
}
@if $letter <= str-length(nth($strings, $string)) {
$time: $time
+ ($durCharFwd * ($letter – 1));
} @else {
$time: $time
+ ($durCharFwd * str-length(nth($strings, $string)))
+ $durFullGap
+ ($durCharBwd * ($letter – str-length(nth($strings, $string))));
}
@return $time / $durTotal * 100 + “%”;
}
$currentPercentage: 0;
// now THIS is where the magic happens… ✨
@keyframes typed {
@for $i from 1 through length($strings) {
// @for $j from 1 through (str-length(nth($strings, $i)) * 2 – 1) {
@for $j from 1 through (str-length(nth($strings, $i)) * 2) {
/* string #{$i}, char #{$j} */
@if $j < str-length(nth($strings, $i)) * 2 { // not last character deleted
#{percent($i, $j)}, #{percent($i, $j+1)} {
@if $j <= str-length(nth($strings, $i)) {
content: quote(#{str_slice(nth($strings, $i), 1, $j)});
} @else {
content: quote(#{str_slice(nth($strings, $i), 1, str-length(nth($strings, $i)) – ($j – str-length(nth($strings, $i))))});
}
}
} @else {
@if $i < length($strings) { // not last string
#{percent($i, $j)}, #{percent($i+1, 1)} {
content: “​”;
}
} @else { // last string
#{percent($i, $j)}, 100% {
content: “​”;
}
}
}
}
}
}
@keyframes beam-blink {
75% { border-color: transparent; }
}
* { backface-visibility: hidden; }
html, body { height: 100%; }
body {
display: flex;
align-items: center;
justify-content: center;
background-color: #000;
background-image: // skeuomorphism anyone?
radial-gradient(rgba(#fff, 0.125), rgba(#fff, 0)),
linear-gradient(to bottom, #000, #000 2px, #111 3px);
background-repeat: repeat-y;
background-position: center center;
background-size: cover, 100% 3px;
font-size: calc(10px + 2vw);
font-family: ‘VT323’, monospace, sans-serif;
color: #3f3; // hacker green
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
&::after {
content: “​”; // zero-width space to retain element height when empty
position: relative;
top: -13px;
@media (max-width: 575px) { top: -33px; }
display: inline-block;
padding-right: 3px;
padding-right: calc(3px + 0.1vw);
border-right: 10px solid rgba(#3f3, 0.75);
border-right: calc(1.1vw + 4px) solid rgba(#3f3, 0.75);
text-shadow: 0 0 5px rgba(51, 255, 51, 0.75);
white-space: nowrap;
animation: typed #{$durTotal + “s”} linear 1s infinite, beam-blink 1s infinite;
}
&::before { // just generating some useful stats here
content: “#{length($strings)} strings / #{$charCount} chars / #{$durTotal}s duration”;
@media (max-width: 575px) {
content: “#{length($strings)} strings \A #{$charCount} chars \A #{$durTotal}s duration”;
}
display: block;
position: absolute;
bottom: 0;
width: 100%;
padding: 3px 0;
background: #00f; // aquaman blue
color: #fff; // Brandon-McConnell white
text-align: center;
font-size: 18px;
letter-spacing: 0.7px;
white-space: pre-wrap;
}
}
You’re a legend dude, thank you for laying this all out.
Love the CSS-only version! Ingenius.
I too created a typing library – with no jquery (or any other) dependency – https://github.com/qodesmith/typer
There is a link to a demo on the abive github page. It has a robust api that offers a lot of natural “typing” use-cases: back, continue, etc. I hope you guys find it useful!
Very cool trick! I’m working on a personal project right now and trying to accomplish a similar functionality to this (like typed.js) dynamically using only CSS/SCSS via ::before/::after and the content property. Because the property isn’t animatable, it will automatically reveal each character without having to do any width or overflow changes and hiding/showing text.
I have a few keyframe bugs I’m working through now but it’s pretty close. Check it out:
Thanks so much for this, I have on problem. I build alot of websites for clients using squarespace and for some reason when implementing this after typing whats in HTML, the cursor keeps on going. Someone care to help me out?
Hey Brandon! The CSS snippet relies on a fine balance between the length of the content and the number of steps in the animation. If you’re finding that the cursor continues past the container, then try adjusting the number of steps in the animation so that is corresponds with the length of the content using the effect.
Set the container to “display: inline-block;” ;)
I have this problem too. Change the length of what you want to type from 24em (in the typewriter animation) to the size you need
I loved this! Thankyou. Is there any way you could do this for multiple lines in CSS alone?
Hi guys, I am a self-learner and am wondering how I can tweak the second option (first option with js) to limit the number of times the loop is repeated.
Hi, please i really need your help… how can i apply different marquee behaviors in one page?
It depends on what method you choose based on the examples in the post, but I’d imagine using different class names for each instance is a good place to start. :)
Is there a way to implement this upon scrolling? Where it doesn’t load until the user scrolls down to that section of the page?
Try wow.js
maybe make that section on an event handler like on scroll, or on rollover, or something similar
i want effect of typing text with slider, when slide changed text will be retyped everytime with pencil or pen icons, than & than slide will be changed at that time text will be retyped(Reload) automatically without any image, only text slider, so please help
AMAZING! I love it. The text im working with is on two lines, only the first line is typing out the second just isn’t there. What can i do to resolve this?
thanks!
This is how I did it, give the .line2 class to your second line of text and so on.
This was very helpful, thank you!
I also found this Stack Overflow question to be helpful with typing on more than one line:
https://stackoverflow.com/questions/22805189/typing-effect-for-multiple-lines
In the second #more example (Javascript version that starts with ‘Hi Im Si.’, What is it that is causing this to loop infinitely, and how would you stop that to only loop through the list just once?
Did you find a solution to this yet?
THANKS SO MUCH FOR THIS THIS IS AWESOME
Hi,
I’d like to know how to remove the cursor, and how to make it type just until the text length?
Great work.
thank you!
Hey Manuel!
You can remove this property:
border-right: .15em solid orange; /* The typwriter cursor */
Hi
I know this is an old post but since my first ever typewriter solution without usage of JavaScript originated from here I thought it would be nice to provide my multiline typewriter solution.
This solution allows to:
1. use any font family, size and styles
2. typewrite effect over multiple lines
3. modify speed for each line separately
4. leave cursor blinking, or not, at the last typed letter of the last line
5. you could also modify the cursor color for each line or even change it from -> to -> to (and so on) on the same line.
Actually most tricks or effects added with JavaScript could eventually be added using pure CSS and nothing else needed.
See the Pen CSS Typing Multiple Lines with Blinking Caret by Joeri Boudewijns (@Bojoer) on CodePen.
https://production-assets.codepen.io/assets/embed/ei.js
There were some questions asked about this on Stack Exchange and on other forums and developer blogs so that’s also the main reason for posting it here.
Thanks, Joeri, and nice work! I went ahead and added your pen to the collection.
Hey Joeri! I’m wondering how to make the cursor only blink AT THE END of the last child line? Right now the blinking makes it blink the entire line and it’s distracting/not what I want :)
If you have advice on where to move the blinking prop I would really appreciate your guidance!
Love this !
How can I have it start when the section appears (it’s a the bottom of my page)
Thanks
Hi! Is it possible to type and delete using only CSS? I am using just the CSS editor in wordpress and have it working for one line, but would love to be able to do multiple different phrases on that same line using a similar type and delete that was done with JS.
nice ones there. i really like $.t.js ( https://github.com/mntn-dev/t.js ), which supports nested html tags as well.
So how to insert HTML/CSS the text in the third example?
// array with texts to type in typewriter
var dataText = [ “Amsterdam.”, “Full Service.”, “Webdevelopment.”, “Wij zijn Occhio!”];
Replace the top variable with:
Is there a way to loop this effect continuously so that it keeps replaying upon finishing?
Thank you!!! I’ve been looking for a good typewriter effect for a while! I threw it on https://welearntechnology.com
Thank’s for helping to us
Hi there! I’m using something similar, but how do I make sure it scales down when I’m on mobile or a smaller window size? It’s currently staying the same size and looking messy :(
Great article :), I am just wondering what do you mean by saying using JS might have an accessibility concern?
In the event that JS is blocked. :)
thanks for the reply :) this makes sense, but because I am new to all of this I wondered maybe there was another reason I didn’t think of xD
Hey – LOVE this. Has anyone figured out how to backspace the text as well?
same question
Hello,
I add This (https://codepen.io/hi-im-si/pen/DHoup) typing effect in my website but i want the cursor in the left.
Thank you very much!
Change line 54 to:
css.innerHTML = “.typewrite > .wrap { border-left: 0.08em solid #fff}”;
Is there a way to do this so it’s responsive and would push onto the next line? I have a little longer line of text (
var languages_i_speak =["HTML", "CSS", "Ruby on Rails", "JS", "WordPress", "Human"];
) and it won’t all fit on one line, my issue is that it’s either not showing up, or it’s spilling out of the box I want it in. I tried taking offwhitespace: no-wrap
, but that makes it initially display it all and looks crazy. I’m pretty new to all this and could use some help!Hello,
Thanks a lot!
Just one question: In the first example “The cat and the hat”, what properties do I need to add to have an erase effect?
Thanks for your help
React Version: https://codepen.io/AliKlein/pen/aPyKjy
Hi! Not sure if it’s just a glitch, but it always begins typing the first few words and then starts over again (actually finishing it the second time) I mean at least it eventually finishes typing but I’d like to know if there’s a common reason why that hiccup happens every time, and how to fix it?
Hey Mackenzie! Could be the number of steps in the animation. May need to adjust that and some of the other numbers depending on the length of the text.
How can I loop the typewriter effect?
Hi. I love the CSS typewriter effect. I’m working on a project now and would like to implement it, but I am having problems with the overflow hidden and white-space:no wrap on smaller screen sizes. I’m still relatively new to the coding game so perhaps there is a simple solution someone can guide me towards? Thank you!
the typewriter is functioning only when the page loads, but when the user click back arrow it is not functioning
Hi there! I’m a COMPLETE novice at this but this is exactly what I’d like to incorporate into my Squarespace site. I used the JS typewriter to customize the text and style.. how do I go about adding the various code (html, css, javascript) into Squarespace?
Thanks so much!
Hey there! Looks like Squarespace has some instructions on how to add custom HTML/CSS/JS to a page/site:
https://support.squarespace.com/hc/en-us/articles/205815928-Adding-custom-HTML-CSS-and-JavaScript
Hi. Thank you so much for this. I am using the first example, however, I am finding it hard to make it type on multiple lines. How should I approach that?
Hello,
The cursor goes to the right edge of the site, how do I fix this
Hey there! Do you padding to the container that the text is in?
I need help desperately. Im currently doing a website called SNOW. The company is a Marketing Solutions type company. I want a typewriting effect in which the word “SNOW” types out into Solutions Now. The S of “Solutions Now” starts typing out from the S of “SNOW”. Then goes back to the original word SNOW after Solutions Now has been typed out.
Any help on how to achieve this in all code formats.
Thank you in advance
How to write 1 paragraph using this
That it writes line by line?
Thanks brow for this post, i’am using in my projects. Thanks :)
How can I make this responsive? In a phone, my text extends beyond the width of the phone screen.
If the typewriter text goes on to a newline the next div gets pushed by the font height. Is there any solution to fix this?
I have created a (more sophisticated and easier to adjust) solution that does not rely on a monospaced font:
https://stackoverflow.com/a/57887588/2397550
It is really very helpful to use the typing effect and there are lots of examples.
Thanks, CSS Tricks.
Can we make this typewriting words as hyperlink?
Hi Guys,
my problem is this effect even if I set the container display to inline-block and adjust the steps, the orange cursor keeps going after the last character and at the end of the animation goes back to after the last character.
So I have 27 character in my text but it types around 30 (more than I need) and after goes back.
Any idea how can I fix this? I would like to use it, because it’s pretty cool :)
I refactored Simon Shahriveri’s TxtType constructor into a factory function that’s slightly easier to just pop in and turn on via the start method: https://codepen.io/maxxheth/pen/LYEaxPO
Here’s how you use it:
const TxtType = TxtTypeFactory({loopOnce: true}); // If you want to loop through the text array in the data-type attribute just once! =)
TxtType.start();
Hey, this is awesome, thank you so much. Is there a way to make the effect stop at the end of the array?
Thanks!
you saved me hours! thanks
Great work. But I have a loader. so I wanna to play it after 5 seconds. How can I do that?
Iam a rookie in CSS and , I wanted to use the the first animation given in more section but the animation is not infinite , plss tell me how can i set it t0 infinite
How to make an auto typed animation in the search input’s placeholder? Does anyone here have any idea? And after clicking on the search input the animation of the placeholder should pause. and after focusing outside the input, the animation should resume again. Hope someone here should be brilliant enough to find a solution!! Thanks
Hi there
I’m trying to implement this into WordPress CSS Editor.
It works, but the cursor always jumps to the end of the row. Does anyone know how to solve this? (In the example above, the cursor stops at the last letter.)
This looks amazing! How can I do this for vertical text?
Hello ! the second option with JS doesn’t work for me, when I paste the html code I don’t see any text, what could it be?