Adjust the positioning of an HTML element in relation to another to prevent elements from moving erratically

Currently, I am working on a website where I have implemented some javascript to achieve a 'typewriter' effect for the prominent middle-centered text displayed below. The script is designed to animate the text by typing it letter by letter in a forward motion and then erasing the text before moving on to the next word. However, I have encountered an issue where, upon deletion of the text, the paragraph element containing the text becomes empty and as a result, the button below 'jumps' to fill the space vacated by the removed text. I am seeking advice on the best approach to resolve this problem, either through modifying the javascript code or by implementing a simple CSS positioning solution. Is there a way to position the button relative to the top text "we create digital products" to address this issue?

https://i.sstatic.net/9yADS.jpg

https://i.sstatic.net/O2qV5.jpg

Here is my HTML:

<div class="agency-hero">
    <section class="container">
      <div class="hero-text customFadeInUp">
        <h1 class="tagLine">
          We create digital products
        </h1>
        <p><span class="txt-type " data-wait="2000" data-words='[" "," Websites "," Web Applications "]'></span></p>
        <a href="agency-portfolio-4.html" class="stayPut">
          See our work
        </a>
      </div>
    </section>
  </div>

And this is the javascript code used to animate the text:

const TypeWriter = function(txtElement, words, wait = 3000){
    this.txtElement = txtElement;
    this.words = words;
    this.txt='';
    this.wordIndex=0;
    this.wait=parseInt(wait,10);
    this.type();
    this.isDeleting = false;
}

// Type Method
TypeWriter.prototype.type = function() {

    //current index of word
    const current = this.wordIndex % this.words.length;
    //get Full text
    const fullTxt = this.words[current];
    //check for if currently in the deleting state or not
    if(this.isDeleting){
        this.txt = fullTxt.substring(0,this.txt.length -1);
    }else{
        //add a character
        this.txt = fullTxt.substring(0,this.txt.length +1);
    }

    //insert txt into element
    this.txtElement.innerHTML = `<span class="txt">${this.txt}</span>`;

    // Initial Type Speed
    let typeSpeed = 300;

    if(this.isDeleting){
        typeSpeed /= 2;
    }

    // If word is complete then move on to next word
    if(!this.isDeleting && this.txt == fullTxt){
        //make pause at the end
        typeSpeed = this.wait;
        //set Delete to True
        this.isDeleting = true;
    } else if(this.isDeleting && this.txt == ''){
        this.isDeleting=false;
        //move to next word
        this.wordIndex ++;
        // Pause before start typing
        typeSpeed = 500;
    }
    setTimeout(() => this.type(),typeSpeed);
}
// Init on DOM Load

document.addEventListener('DOMContentLoaded',init);

//Init App

function init(){
    const txtElement = document.querySelector('.txt-type');
    const words = JSON.parse(txtElement.getAttribute('data-words'));
    const wait = txtElement.getAttribute('data-wait');

    new TypeWriter(txtElement, words, wait);
}

Answer №1

To maintain the desired space between texts, you can utilize the CSS property min-height. The following code snippets demonstrate how to achieve this:

With Text-

body {
  background-color: lightblue;
}

h1 {
  color:black;
  text-align: center;
}

p {
  font-family: verdana;
  font-size: 40px;
  background-color:red;
  min-height:20px;
}
p+p {
  font-size: 20px;
   background-color:orange;
}
<h1>We create Digital Products</h1>
<p>Type Writer</p>
<p>See my work</p>

Without Text

body {
  background-color: lightblue;
}

h1 {
  color:black;
  text-align: center;
}

p {
  font-family: verdana;
  font-size: 40px;
  background-color:red;
  min-height:20px;
}
p+p {
  font-size: 20px;
   background-color:orange;
}
<h1>We create Digital Products</h1>
<p></p>
<p>See my work</p>

The height of the block element p is determined by its content. Implementing min-height in CSS can help control the gap between texts effectively. Hope this explanation is useful to you.

Answer №2

To achieve relative positioning in CSS, you can utilize the position property with a value of relative and adjust the top and left properties as needed. Alternatively, you can also employ the transform property to manipulate the positions.

Here is an example:

button {
  position: relative;
  top: 50vh;
}
//Or
button {
  transform: translate(0, 50vh);
}

You have the flexibility to customize these values based on your requirements. Based on my interpretation, if you intend to maintain the current position, it is recommended to utilize absolute positioning.

For instance:

button {
  position: absolute;
  left: 50%;
  top: 90vh;
  //This will remain fixed in its position
}

Answer №3

To give your <p> a specific height, you can do the following:

.hero-text p {
    height: 20px;
}

const TextAnimator = function(txtElement, words, wait = 3000){
    this.txtElement = txtElement;
    this.words = words;
    this.txt='';
    this.wordIndex=0;
    this.wait=parseInt(wait,10);
    this.animate();
    this.isDeleting = false;
}

// Animation Method
TextAnimator.prototype.animate = function() {

    //current index of word
    const current = this.wordIndex % this.words.length;
    //get Full text
    const fullTxt = this.words[current];
    //check if currently in the deleting state
    if(this.isDeleting){
        this.txt = fullTxt.substring(0,this.txt.length -1);
    }else{
        //add a character
        this.txt = fullTxt.substring(0,this.txt.length +1);
    }

    //insert txt into element
    this.txtElement.innerHTML = `<span class="txt">${this.txt}</span>`;

    // Initial Animation Speed
    let animationSpeed = 300;

    if(this.isDeleting){
        animationSpeed /= 2;
    }

    // If word is complete then move on to next word
    if(!this.isDeleting && this.txt == fullTxt){
        //make pause at the end
        animationSpeed = this.wait;
        //set Delete to True
        this.isDeleting = true;
    } else if(this.isDeleting && this.txt == ''){
        this.isDeleting=false;
        //move to next word
        this.wordIndex ++;
        // Pause before start typing
        animationSpeed = 500;
    }
    setTimeout(() => this.animate(),animationSpeed);
}
// Initialize on DOM Load

document.addEventListener('DOMContentLoaded',initialize);

//Initialization function

function initialize(){
    const txtElement = document.querySelector('.txt-type');
    const words = JSON.parse(txtElement.getAttribute('data-words'));
    const wait = txtElement.getAttribute('data-wait');

    new TextAnimator(txtElement, words, wait);
}
.hero-text p {
    height: 20px;
}
<div class="agency-hero">
    <section class="container">
      <div class="hero-text customFadeInUp">
        <h1 class="tagLine">
          We develop innovative solutions
        </h1>
        <p><span class="txt-type " data-wait="2000" data-words='[" "," Apps "," Mobile Applications "]'></span></p>
        <a href="agency-portfolio-4.html" class="stayPut">
          View our projects
        </a>
      </div>
    </section>
  </div>

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 on sending a function's return value to an object in Node.js

I'm currently exploring Node.js and working on a REST API for a project. One of the functionalities I am implementing is a post request to store form data in a database. Some values will be retrieved from the form data while others will be generated ...

Learn how to swap out the traditional "back to top" button with a customized image and make it slide onto or off the page instead of simply fading in and out

As a newcomer, I am trying to replicate a unique "back to top" effect that caught my eye on another website. Instead of the traditional fade-in approach when scrolling down, the "back to top" image in question elegantly slides out from the bottom right c ...

The EJS template in an Express.js (Node.js) application is not updating to show recent modifications

I'm currently developing a node.js application that serves an index.ejs page through a route named index.js. var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) ...

Issue occurring while trying to select an item from the dynamically generated options using AJAX

A JavaScript function is used in this code to select a specific option, with the option value being specified within a hidden element: $("select").each(function() { var id = $(this).attr('id'); var source = 'input:hidden[na ...

What is the best way to attach every sibling element to its adjacent sibling using jQuery?

I've been working with divs in Wordpress, where each div contains a ul element. <div class="list-item"> <div class="elimore_trim"> Lorem ipsum </div> <ul class="hyrra-forrad-size-list"> <li>Rent 1< ...

Tips for validating Angular form group input depending on the value of another input within the form?

I am facing an issue with form validation in my Angular version 8 application. I need to validate a form based on the following rules: If a file is uploaded (even if just clicking the button without selecting a file), then the Reason input is not required ...

Avoid re-running the onScroll function until completion

I have a unique idea for a slideshow where the slides fade in and out as the user scrolls up or down. The process involves detecting scroll movements and showing the next slide based on the direction of the scroll. The user scrolls using the scrollwheel ...

submit the JSON formatted data to the server

I am attempting to extract data from a form and transmit it to a remote server: Below is the code snippet: <html> <head> <script src="http://code.jquery.com/jquery-latest.min.js"></script> </head> ...

Incorporating a background image into a mat-dialog

After spending some time on the mat-dialog documentation, I discovered that I can add a background image to the mat-dialog using panelClass: 'my-class' to customize its appearance. This applies the class my-class to the div with the class cdk-ove ...

Creating a CSS layout that eliminates the need for a vertical scroll bar

Currently, I am experimenting with creating an HTML CSS Layout using the div tag. You can view the code here Currently, the layout displays a vertical bar that I would like to eliminate. Ideally, I only want it to display if the content is lengthy. ...

What is the best way to align the logo image to the left side of the Material UI app bar without any gaps?

Currently, I am working on a material UI app bar to serve as my navigation bar. The issue I am encountering involves the logo image on the left side of the page having excessive spacing from the edge, as shown in the image below. I've tried adjusting ...

Center-aligning images in Bootstrap Carousel

I've implemented the Bootstrap 4 Carousel on my website and it's functioning properly. However, I'm facing an issue where I need to align the slider image in the center of the carousel. Currently, the image is aligned to the left side, caus ...

React Issue: Footer not staying attached at the bottom of the page

I'm currently developing a website with react, but I'm struggling to keep the footer at the bottom. When there isn't enough content, the footer ends up right after the content instead of staying at the bottom. I've tried various solutio ...

Grab the SVG and resize it to a smaller scale

I have a small application built using Raphael.js that creates a node network with SVG and reorganizes it based on user selections. My goal is to capture the SVG image I've created and display it in a "mini-map" format at the bottom of the screen. Si ...

The Vue.js development server compiler is hitting a roadblock at 49% progress

My Vue JS project keeps getting stuck at 49% or sometimes 62% when I run npm run serve. No matter how long I wait, it never seems to move past that point. I have searched online many times for a solution to this issue, but it appears that no one else is e ...

Trouble with component not refreshing upon store modification in Vuex

Summary: If you prefer, I have a video detailing my issue: https://youtu.be/Qf9Q4zIaox8 Concern with Navbar Component Not Updating on Store Change. The issue I'm facing involves the Navbar component not updating when there is a change in the store. ...

Implementing model synchronization on server initialization with Next.js and sequelize

When it comes to using Express with React on the backend, I'm accustomed to working in a server.js file to synchronize the database. However, I've recently started working with Next.js and noticed that there's no server.js file to sync the m ...

Uncovering Secret Information with Beautiful Soup 4

I've hit a roadblock with my current project. I'm attempting to extract player names and projections from this website: The plan involves running a script that loops through various PID values, but that part is not causing any issues. The real c ...

Maintaining text in a straight line

My design includes an image floated to the left with text aligned to the right of the image. Unfortunately, the text is too long, causing a line from a paragraph to drop below the image. How can I ensure that the text stays in line with the paragraph and ...

What is the best way to make a scrollable div with top and bottom padding without adding extra elements inside?

I have created a fiddle to demonstrate my question. Essentially, I am looking to create a scrollable container with padding at the top and bottom that remains visible during scrolling, ensuring there is always a consistent distance from the edge to the con ...