CSS magic: Text animation letter by letter

I have a <div> with text.

<div> to be revealed on the page one character at a time:

<div>, the animation should stop and display the full text instantly.

In summary, I aim to replicate an effect commonly seen in Japanese-style adventure games known as a typewriter or teletype effect. A good example can be viewed here:

http://www.youtube.com/watch?feature=player_detailpage&v=SasgN0lim7M#t=418

While I could achieve this animation using JavaScript by setting up a timer to append letters (or words) sequentially, I am curious if it's possible to accomplish the same effect with CSS in modern browsers. Modifying the element class in the onclick function with JavaScript would also be acceptable.

Update: To clarify the difference between characters and letters and address concerns about HTML entities:

The text contains several HTML elements, such as:

Lo&shy;rem <i>ip&shy;sum</i>.

A straightforward method of adding text character-by-character to the innerHTML wouldn't work as expected:

L

Lo

Lo&

...Oops!

Answer №1

To accomplish this task, jQuery can be utilized effectively.

Take a look at my interactive example: http://jsfiddle.net/kA8G8/7/

Below is the HTML code snippet:

<p class="typewriter">Nullam id dolor id nibh ultricies vehicula ut id elit. Maecenas faucibus mollis interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>

And here we have the corresponding JavaScript code:

var text = $('.typewriter').text();

var length = text.length;
var timeOut;
var character = 0;

(function typeWriter() { 
    timeOut = setTimeout(function() {
        character++;
        var type = text.substring(0, character);
        $('.typewriter').text(type);
        typeWriter();

        if (character == length) {
             clearTimeout(timeOut);
        }
    }, 150);
}());

Answer №2

Regrettably, accomplishing this with CSS is not possible, requiring a return to a pure JS approach.

Based on your comments, incorporating HTML markup into your text necessitates a word-by-word animation as the simplest solution. Consider implementing code similar to this:

var timer, fullText, currentOffset, onComplete, wordSet;

function Speak(person, text, callback) {
    $("#name").html(person);
    fullText = text;
    wordSet = text.split(" ");
    currentOffset = 0;
    onComplete = callback;
    timer = setInterval(onTick, 300);
}

function onTick() {
    currentOffset++;
    if (currentOffset == wordSet.length) {
        complete();
        return;
    }
    var text = "";
    for(var i = 0; i < currentOffset; i++){
     text += wordSet[i] + " ";   
    }
    text.trim();
    $("#message").html(text);
}

function complete() {
    clearInterval(timer);
    timer = null;
    $("#message").html(fullText);
    if (onComplete) onComplete();
}

$(".box").click(function () {
    complete();
});

Speak("Simon",
    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",

function () {
    setTimeout(function () {
        Speak("Javascript", "Simon has finished speaking!");
    }, 2000);
});

An interactive example can be found here

NOTE: While there may be room for optimization and streamlining in the code provided, it effectively illustrates the intended concept.


I have also developed a letter-by-letter demonstration. Though lacking support for HTML markup, it offers a visually appealing alternative that could potentially be adapted to suit your requirements.

Answer №3

Here's a clever CSS technique you can use.

Create a mask element, such as a pseudo-element like p:before or p:after, with a higher z-index than your text element. Make sure it has the same color as the text background and is the height of a line. Position it absolutely just above the text.

Then, animate the mask element to move to the right, revealing one letter at a time. This is a workaround solution, especially if there is a complex background under the text, such as an image, as reproducing this trick may be challenging due to having to align the background image with the masking element.

Answer №4

Although this may seem off-topic, I have a fondness for animations and decided to develop a tool for them:

Feel free to check it out!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for incorporating Javascript Object Literals into Python code

Using the Beautifulsoup module, I successfully extracted an HTML page and then proceeded to extract a Javascript script tag from that page. Within this script tag lies an object literal that I hope to manipulate. Here is what I am aiming for: <script&g ...

Verify the validity of the user's input

Using knockout.js and knockout.validation, I have created a book view model with properties for the author's name and book title: function BookViewModel(bookObj) { var self = this; self.AuthorName = ko.observable(bookObj.AuthorName) ...

The line-height property does not appear to have any effect when used within a table cell

I am struggling to format a table with fonts similar to the one shown in the image. I attempted to set the line-height for numbers to 33%, but so far, the line height has not been as expected. I have been unsuccessful in achieving the layout displayed belo ...

What is the best way to obtain a user's ID on the server side?

I'm currently working on a node.js application using express and I am in need of retrieving the user ID. I would like to have something similar to "req.userID" so that I can use it in the following way: var counter=0; var user = new Array(); router.g ...

Using JQuery to implement a date and time picker requires setting the default time based on the server's PHP settings

I have implemented a jQuery UI datetime picker in my project. As JavaScript runs on the client side, it collects date and time information from the user's machine. Below is the code snippet I am currently using: <script> // Function to set ...

Responsive columns and fluid Flex row implemented in Bootstrap 4

I am striving to optimize this section for responsiveness. It looks fantastic on larger viewports, but as we start shrinking down, for instance, on a viewport around 930px, I'm facing difficulty in keeping the image perfectly aligned as shown in the i ...

Tips for adding a button to the SB Admin 2 Card header without altering its height

I am currently utilizing the SB Admin 2 template for my project and encountering difficulty when trying to add a button in the card header without altering the default height. The goal is to maintain a consistent look across both cards, as illustrated in t ...

The variables $invalid and $valid in my AngularJS form have not been assigned any values

I came across a post on StackOverflow discussing the issue of both "myForm.$valid" and "myForm.$invalid" being undefined on an Angular form. However, my problem is slightly different. I have defined a form like this: <form name="EntityForm" role="form ...

The information from the form is not appearing in the req.body

Utilizing the mean.js framework, I have the bodyParser middleware configured as shown below: app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(methodOverride()); Additionally, I am using formidable to upload imag ...

How to stop the overflow scrollbar in a grandchild element with CSS grid

Encountered an unusual issue while using a combination of CSS grid and overflow auto. In the scenario where there are 3 elements, the outermost element has display: grid, the middle element has height: 100%, and the innermost element has both height: 100% ...

Expanding the input range slider to fill the entire available space

https://jsfiddle.net/a5gdhmfn/1/ <div> <i>O</i> <input type="range" /> <button/> <div>...</div> </div> Inside a div, there is a range slider along with other fixed-width elements. The issue ...

I'm having trouble finding a solution to remove the white space

I've been troubleshooting a website and noticed some unexpected whitespace on the page. Even though I have set my page wrapper div and other elements to width: 100%, the content in between is not utilizing the full width of the screen. I suspect this ...

The custom validator in Material2 Datepicker successfully returns a date object instead of a string

Im currently working on developing a unique custom validator for the datepicker feature within a reactive form group. Within my code file, specifically the .ts file: form: FormGroup; constructor( private fb: FormBuilder, ...

Dynamically and asynchronously loading numerous LinkedIn share buttons on a page

On my page, I have a grid of post thumbnails that are fetched via AJAX and can be filtered. When a user clicks on a thumbnail, a carousel opens with the selected post centered. In this carousel, each post has a LinkedIn share button integrated. The issue ...

Eliminate the flickering effect on the dropdown menu

Is there a way to eliminate the annoying 'flicker' effect on my menu? Whenever I click on 'Dropdown 1', I notice that Test 1 and Test 2 flicker. My assumption is that this is due to my use of the !important declaration. Any suggestion ...

The default choice vanishes once a non-empty option is chosen

Here is a simple example illustrating my issue: JSFiddle. Initially, I have an empty/default option, but when I select something else from the drop-down, this default option disappears. How can I keep this default option visible after making a selection? ...

Utilizing a specialized xyz tileLayer to specifically highlight a designated area on the map

I am looking to add the xyz tile layer from this link onto a leaflet map: http://weatheroo.net/radar/data/2019/07/15/18/40/{z}/{x}/{y}.png This particular weather radar composite is focused on Germany, hence why it only covers middle Europe. The specifie ...

Align button text vertically in the middle using Flexbox with Bootstrap 4

Why is the text in the button displaying at the top instead of the center when using internet explorer? button { height: 100px; } <div class="container"> <button class="w-100 f-default-f btn btn-primary d-flex justify-content-between px-3"& ...

Navigating the elements within R Shiny: A comprehensive guide

Can anyone help me figure out how to access specific elements in my Shiny app using their HTML tags? In this particular example, I need to retrieve all h1 elements along with their respective labels and IDs. library(shiny) ui <- fluidPage( h1("Get" ...

Implementing AngularJS within a standalone system devoid of internet connectivity

Hello there! I am interested in creating a single page web application for an embedded system that won't have access to the internet. This means I need to develop it without relying on external sources for functionality. Although I prefer AngularJS, ...