Adjust the button's width as the text changes to create a dynamic animation

I'm trying to create an animation effect where the width of a button changes whenever the text inside it is updated. I've attempted using useRef on the button itself to grab its clientWidth and then applying that value to a CSS variable in order to adjust the width dynamically.

However, I'm encountering an issue where although the width is being set correctly, the animation isn't working as expected. Strangely, if I manually adjust the width in Chrome Developer Tools, the animation works fine. But when I revert back to using the CSS variable and update the inner text, the animation fails to trigger.

.button {
width: var(--buttonwidth);
transition: width 2s ease-in-out;
}
// Update css variable when button text changes
  useEffect(() => {
    const buttonInnerWidth = buttonRef.current.clientWidth;
    document.documentElement.style.setProperty(
      '--buttonWidth',
      `${buttonInnerWidth}px`
    );
    console.log(buttonInnerWidth);
  }, [children]);

Does anyone have a more effective solution to achieve this animation effect?

Answer №1

Here is a demonstration showcasing how the button width changes when clicked. You have the freedom to modify this event listener to suit your preferences.

Check out the sample code below:

$(document).ready(function(){
$("button").css({"width":$("button").text().length*10});
  $("button").click(function(){
    var str = " activated ";
    var strWidth = str.length*10;
    $(this).css({"width":strWidth}).text(str);
  });
});
button{
height: 40px;
transition: 0.4s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>press</button>

Answer №2

Here is an alternative method. It's very similar to what Hooman Namazi proposed, but with a slightly different approach. Take a look:

jQuery(function ($) {
$("button").css({"width":$("button").text().length*10});
    var text = ['first text', 'this is second text', 'and this one is third', 'Hi, I am forth'];
    //used to determine which is the next text to be displayed
    var counter = 0;
    var $button = $('button');
    //repeat the passed function at the specified interval - it is in milliseconds
    setInterval(function () {
        //display the text and increment the counter to point to next text item
        $changeText = $button.text(text[counter++]);
        $button.css({"width":$("button").text().length*10});
        //if it is the last text item in the array point back to the first item
        if (counter >= text.length) {
            counter = 0;
        }
    }, 2000);
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}
button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
  transition: 0.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>first text</button>

Answer №3

Avoiding the use of JS was important for me in this situation due to performance concerns. Constantly checking the width of text inside a button can be inefficient. Instead, I opted to set the width to auto and adjust the max-width when the text changes within the button.

While this solution is not ideal for lengthy text, it functions well for my particular needs! :)

Check out the CSS code below:

.button {
   width: auto;
   white-space: nowrap;
   max-width: 15rem;
   transition: max-width 0.3s cubic-bezier(0.445, 0.05, 0.55, 0.95);

   &.loading {
     max-width: 30rem;
    }
}

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 developing a nested array of objects using a JavaScript loop

Can someone help me with looping an AJAX response to create an array in this format? "2023-03-30": {"number": '', "url": ""}, "2023-03-30": {"number": '', "url": &quo ...

The contrast between FormData and jQuery's serialize() method: Exploring the distinctions

Recently I came across a situation where I needed to submit a form using AJAX. While researching the most efficient method, I discovered two popular approaches - some developers were utilizing jQuery#serialize() while others were opting for FormData. Here ...

Convert a form into plain text utilizing CSS with minimal usage of jQuery or Javascript

I am working on an HTML page which has a form with various tags such as checkboxes, dropdowns, and more. When a button is clicked, I want to display the same form as plain text in a popup using jQuery dialog. Currently, I have managed to show the form in ...

Determining the duration since generating a unique objectid in mongodb

I am currently developing an application that offers users the option to reset their passwords. The process is quite straightforward - after entering his email address, the user will receive a link containing the new objectid number. For example: /reset- ...

Transmit information from a comprehensive form using AJAX technology

I created a complex form with 30 fields, out of which 3 fields are repeated 10 times. Here's the code: <form id="artikelform" method="POST" name="controleartikelen" action=""> <table id="controle"> <tr><th>Maakartikel</ ...

Error: The jQuery TableSorter Plugin is unable to access property '1' as it is undefined

I've been attempting to utilize the jquery table sorter plugin, but I keep encountering an error when trying to sort the table. The error message I'm receiving is: cannot read property '1' of undefined This is the HTML code I have: ...

How can I generate a bounding box with CSS?

I am a newcomer to vue.js and I have a question about creating a bounding box for any element. This bounding box resembles a view box in svg. For example, I have created a checkbox like this one: checkbox Below is the code to style the checkbox: /* checkb ...

Is there a way to make the first Image Element within the div automatically clickable?

Is there a way to set the first image in a div as the default clicked element? I have a div with multiple images and I want the first one to be clicked by default. This is part of a React functional component that serves as a view. <div className=&quo ...

Guide to mocking the 'git-simple' branchLocal function using jest.mock

Utilizing the simple-git package, I have implemented the following function: import simpleGit from 'simple-git'; /** * The function returns the ticket Id if present in the branch name * @returns ticket Id */ export const getTicketIdFromBranch ...

Mastering the art of reading rows in ASP.NET using Java Script

Within the code snippet below, you'll find an image located in the second column. Clicking on this second column should allow me to access the data stored in the first column. Let's say we have a table with 10 rows. If the user clicks on the ico ...

Center and align pictures within a stationary container

I am working on a simple webpage that has a fixed footer. In this footer, I want to have 5 images centered with equal distances between them. Below is my HTML/CSS : Footer div : div.fixed { position: fixed; bottom: 0; right: 0; width: ...

Adding a CSV file to Mui-Datatables for data upload

Can someone guide me on the process of uploading a CSV file in Mui-Datatables and showcasing it in a table? I'm still learning about Mui-Datatable. ...

IE8 not displaying background-image in Zen Subtheme of Drupal 7

I've been struggling to get my website to display properly across all browsers. Everything looks great except for IE8 and below. I'm not sure if it's a problem with Drupal, Zen, IE, or CSS (although the CSS code seems correct). Here is the C ...

Align the center of a grid div that does not contain any items

Below are the code snippets provided: .grades_dashboard_m {} .three_separation { width: 100%; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 60px; } .grades_dashboard_box { height: 130px; width: 160px; background-color: #00 ...

Formulate a targeted search request according to the selected radio button option

I'm working on a form that looks like this: <form> <input type="text" id="searchedWord" class="form-control form-control-lg" value="words here"/> <button type="submit" id="f ...

Setting up a plan for executing Javascript server side scripts

Can JavaScript be executed server-side? If I attempt to access a script , can it be scheduled to run every four hours? Would most web hosts allow this, or is it considered poor webmaster practice? The main goal is to activate my website's webcrawler/ ...

What seems to be the issue with loading this particular file into my JavaScript code?

When attempting to import a file into my code, I encountered an issue where the folder could not be found. Interestingly, when manually typing out the folder name, it is recognized and suggested by the system. Even providing the full path did not yield dif ...

Preventing jQuery plugin from overriding default settings

I have created a jQuery plugin using the nested namespace pattern, inspired by the design template found in Addy Osmani's book. The plugin is a simple gallery and everything seems to be functioning correctly. However, I am facing an issue when attemp ...

How can one utilize Codemirror code folding while avoiding the use of "[ ]"?

I am looking forward to implementing Codemirror codefolding for folding only braces { and }, as well as comments. However, I am facing an issue where it also folds square brackets [ and ]. Since square brackets are usually part of one-line statements, I do ...

Tips on utilizing media queries to optimize website layout for mobile devices

I'm currently working on a responsive website and utilizing media queries for that purpose. However, I've encountered an issue where the media queries don't seem to apply when the browser window is set to mobile view. Below is the snippet of ...