Creating the illusion of a typewriter effect while adjusting container sizing

I created a unique typing animation that displays text as if it's being typed on the screen, erased, and replaced with new text. While this effect works well, it's causing an issue where the width of containers below it also adjust based on the size of the typewriter text container.

      document.addEventListener("DOMContentLoaded", function () {
        var phrases = [
          "phrase 1",
          "phrase 2",
          "phrase 3",
          "phrase 4",
        ];

        var speed = 50;
        var flickerSpeed = 600;
        var pauseBetweenPhrases = 2000;

        var container = document.querySelector(".typewriter");
        var bar = document.querySelector(".typewriter-bar");
        var currentPhraseIndex = 0;
        var charIndex = 0;

        function typeWriter() {
          if (charIndex < phrases[currentPhraseIndex].length) {
            container.innerHTML +=
              phrases[currentPhraseIndex].charAt(charIndex);
            charIndex++;
            setTimeout(typeWriter, speed);
          } else {
            setTimeout(function () {
              backspace();
            }, pauseBetweenPhrases);
          }
        }

        function backspace() {
          if (charIndex >= 0) {
            container.innerHTML = phrases[currentPhraseIndex].substring(
              0,
              charIndex
            );
            charIndex--;
            setTimeout(backspace, speed);
          } else {
            currentPhraseIndex = (currentPhraseIndex + 1) % phrases.length;
            setTimeout(typeWriter, speed);
          }
        }

        function flicker() {
          bar.style.visibility =
            bar.style.visibility === "visible" ? "hidden" : "visible";
          setTimeout(flicker, flickerSpeed);
        }

        flicker();
        typeWriter(); // Start the typewriter effect
      });
    
html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding: 0;
  font-family: 'Hind Madurai', Arial, Helvetica, sans-serif;
}

h1 {
  font-family: 'Poppins', Arial, Helvetica, sans-serif;
  font-size: 10vh;
  line-height: 1;
}

h2 {
  font-family: 'Signika', Arial, Helvetica, sans-serif;
}

header {
  background-color: white;
  color: #222;
  padding: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

header h2 {
  margin: 0;
  font-weight: 300;
}

nav ul {
  list-style: none;
  padding: 0;
  margin: 0;
  text-align: right;
}

nav li {
  display: inline-block;
  margin-right: 20px;
}

nav a {
  text-decoration: none;
  color: #222;
  transition: color 0.3s ease;
}

nav a:hover {
  color: #3ca6a6;
  text-decoration: underline;
}

@media only screen and (max-width: 600px) {
  header {
    flex-direction: column;
    text-align: center;
  }
  nav {
    margin-top: 10px;
  }
  nav ul {
    flex-direction: column;
    text-align: center;
  }
  nav li {
    display: block;
    margin: 10px 0;
  }
}

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  position: relative;
  margin: 0;
  padding: 0;
}

.content {
  flex: 1;
}

footer {
  background-color: #026773;
  color: white;
  text-align: center;
  padding: 10px;
  position: relative;
  z-index: 1;
  margin-top: auto;
}

footer::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  height: 400px;
  background: url(imgs/layered-peaks-haikei.svg) repeat-x;
  z-index: 2;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  background: #fff;
  padding: 10px;
  z-index: 999;
}

.typewriter {
  overflow: hidden;
  max-width: 800px;
  margin: 0 auto;
}

.typewriter-bar {
  border-right: 1px solid #222;
}
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Hind+Madurai:wght@300&family=Poppins:ital,wght@0,600;1,600&family=Signika:wght@300;400&display=swap"
      rel="stylesheet"
    />
    <div class="skip-link">
      <a class="visually-hidden" href="#main-content">Skip to Main Content</a>
    </div>
    <header>
      <h2>Name</h2>
      <nav>
        <ul>
          <li><a href="#">Welcome</a></li>
          <li><a href="#">Selected Work</a></li>
          <li><a href="#">Resume</a></li>
        </ul>
      </nav>
    </header>
    <main id="main-content" class="container">
      <div class="content">
        <div class="typewriter-container">
          <h1>
            I'm a <span class="typewriter"></span
            ><span class="typewriter-bar"></span>
          </h1>
        </div>
        <h2>Hi there!</h2>
      </div>
    </main>
    <footer></footer>
    

To address this issue, I have attempted enclosing the typewriter section within its own container/div and setting a specific width for it. However, subsequent containers still respond to the resizing caused by the typewriter effect.

Answer №1

One method to accomplish this is by specifying the width for .typewriter-container:

.typewriter-container {width: 90vw; text-align:center;}

document.addEventListener("DOMContentLoaded", function() {
          var phrases = [
            "phrase 1",
            "phrase 2",
            "phrase 3",
            "phrase 4",
          ];
  
          var speed = 50;
          var flickerSpeed = 600;
          var pauseBetweenPhrases = 2000;
  
          var container = document.querySelector(".typewriter");
          var bar = document.querySelector(".typewriter-bar");
          var currentPhraseIndex = 0;
          var charIndex = 0;
  
          function typeWriter() {
            if (charIndex < phrases[currentPhraseIndex].length) {
              container.innerHTML +=
                phrases[currentPhraseIndex].charAt(charIndex);
              charIndex++;
              setTimeout(typeWriter, speed);
            } else {
              setTimeout(function() {
                backspace();
              }, pauseBetweenPhrases);
            }
          }
  
          function backspace() {
            if (charIndex >= 0) {
              container.innerHTML = phrases[currentPhraseIndex].substring(
                0,
                charIndex
              );
              charIndex--;
              setTimeout(backspace, speed);
            } else {
              currentPhraseIndex = (currentPhraseIndex + 1) % phrases.length;
              setTimeout(typeWriter, speed);
            }
          }
  
          function flicker() {
            bar.style.visibility =
              bar.style.visibility === "visible" ? "hidden" : "visible";
            setTimeout(flicker, flickerSpeed);
          }
  
          flicker();
          typeWriter(); // Start the typewriter effect
        });
      
html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding: 0;
  font-family: 'Hind Madurai', Arial, Helvetica, sans-serif;
}

h1 {
  font-family: 'Poppins', Arial, Helvetica, sans-serif;
  font-size: 10vh;
  line-height: 1;
}

h2 {
  font-family: 'Signika', Arial, Helvetica, sans-serif;
}
/* Additional CSS code */

header {
  background-color: white;
  color: #222;
  padding: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

header h2 {
  margin: 0;
  font-weight: 300;
}

nav ul {
  list-style: none;

...
...
      

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

Facing a dilemma: Javascript not updating HTML image source

I am facing an issue while attempting to modify the source of my HTML image element. Despite using document.getElementId('image') in my code, I am unable to make it work as intended. Surprisingly, there are no errors displayed. Interestingly, whe ...

Flexbox Alignment Problem with Mixed Text and Image Elements

Struggling to achieve a layout like the one in this image using Flexbox. Take a look: https://i.sstatic.net/EGsAN.png After some difficulty with floats, I've decided to experiment with flexbox. My CSS is set up to display the image correctly. The ...

Button with embedded Bootstrap dropdown

I need help with centering a dropdown menu on my webpage. I followed the instructions, but it's still appearing next to the button instead of in the center. Below is the code snippet: <div class="btn-group"> <button type=" ...

The icon representing a clock from the font-awesome library is not displaying properly on my website

I've been tasked with creating the webpage below However, when I try to use the font-awesome class to include the clock icon as shown in the image, it's not displaying correctly. Here is the code I'm using. Can anyone point out my mistake? ...

Convert an array of objects into an object where the keys are determined by the value of a specific

I'm working with an array that looks like this: const inventory = [ { fruit: 'apple', quality: 'good', quantity: 10 }, { fruit: 'banana', quality: 'average', quantity: 5 }, { fruit: 'orange', qua ...

Upgrade the JavaScript source code from the backbean JSF

In my XHTML file, I have included Javascript like this: <script src="test1.js"></script> Additionally, I have a few other Javascript files which are actually themes. I want to provide users with the option to change the theme (Javascript nam ...

Is there an issue with CSS animation glitches in Chrome? Specifically referring to the width transition effect on a centrally

I recently encountered a strange issue with my centered div layer that transitions from a fixed width to 100% when scrolling down. The problem arises in Chrome and Edge on Windows 10, where certain elements like images shake and jitter during the transitio ...

Extract data from a multidimensional array using a one-dimensional array as a filter

A series of checkboxes are present on a webpage where clicking them generates an array of values called allVals. This array is dynamically updated as checkboxes are toggled on and off. Additionally, there is a multidimensional array named recordSet that ne ...

What is the process of unmounting the next/script on page change within a next.js application?

Is there a way to load a script only on specific pages? Next.js suggests using next/script tag for this purpose. However, I noticed that even when navigating to different pages, the script remains visible at the end of the HTML body. https://i.sstatic.net ...

Node.js powered file uploading on the Heroku platform

After attempting to upload a file to Heroku using https://www.npmjs.com/package/express-fileupload, I encountered an error. It worked fine on my PC, but on Heroku, I received the following error message: {"errno":-2,"code":"ENOENT","syscall":"open","path" ...

Slanted lower edge - entire width

Can anyone provide guidance on how to design a div that is 100% width and 300px wide, with a slightly angled bottom border that spans the entire width of the box? https://i.sstatic.net/QSvoQ.png I am open to using either CSS or JavaScript for this task, ...

What is the proper way to send an AJAX request with the data type set to

I am currently working on creating my own POST request. Below is the function I have written: function sendPost(o) { var h = new XMLHttpRequest(); h.onreadystatechange = requestComplete; function requestComplete() { if (h.readyState = ...

What is the process for incorporating a Bootstrap link into a specific ReactJS file?

In my current project using React JS, I found the need to incorporate Bootstrap in certain pages. To do this, I initially placed the following code snippet in the Public folder within index.html: <link rel="stylesheet" href="https://netdna.bootstrapc ...

jQuery: Implementing smooth horizontal scrolling functionality

Here is the code I am working with: // General Function $("li a").click(function() { $("li a").removeClass("active"); $(this).addClass("active"); }); // Horizontal Scroll-to Function $("li a").click(function() { var offset = this.getBounding ...

Optimal methods for refreshing website lists

I've designed an ASP.NET MVC application with a list that displays all the current items from a database. There is also a button that triggers a popup-dialog to create a new entry. The goal is to automatically add the new item to the list once it is c ...

How come the data from the Firebase real-time database is only displaying in the console and not on the page when using Vue.js?

I am encountering an issue while trying to display a value stored in my Firebase Realtime Database using the {{ exams.name }} syntax in Vue. Although I can see the value when I console.log it, it does not render on the page. However, when I attempted the s ...

The collapsing z-index menu in Bootstrap 4 is experiencing CSS issues and is not functioning correctly

I have a bootstrap 4 menu with a slide effect that is functioning correctly, but there seems to be an issue with the z-index value I have set for it. Specifically, there is some content within a parallax jumbotron that is overlapping the menu links. I need ...

When Using TypeScript with Serverless, 'this' Becomes Undefined When Private Methods are Called from Public Methods

Currently, I am working on constructing an AWS Serverless function using TypeScript. My focus is on creating an abstract class with a single public method that invokes some private methods. Below is the simplified version of my TypeScript class: export ...

When accessing a page from a link, JavaScript sometimes does not immediately execute on the first attempt

I'm encountering a strange issue in my rails application, where a template fails to execute the Javascript code the first time it is loaded via a link on my home page. This problem only occurs when accessed through the link for the first time. I' ...

What is the best method for displaying an image using CSS and accessing that image using document.getElementById?

#maze{ position: absolute; top: 25%; right: 1%; width: 730px; background-image: url("maze.jpg");} //CSS styles for maze. var maze = document.getElementById('maze'); //JavaScript code to get element with ID 'maze' ...