Create a polished effect by smoothly shrinking the size of a button while simultaneously reducing the maximum width

Background : Utilizing Bootstrap 4, I have numerous buttons incorporating SVG + span for the button text, as illustrated below :

<button class="btn--color-success">
    <span>Button label</span>
    <svg><svg>
</button>

The objective is to hide the span when clicking on the button and replace the SVG with a loading icon, essentially transforming it into a "loading" button. While changing the SVG is not an issue, the main concern lies in smoothly transitioning the span and maintaining the button width.

I've managed to achieve this by setting a max-width for the button's span, but encounter difficulties when dealing with two buttons within a standard BS4 row/col configuration with justify-content-end alignment, making the shrink effect somewhat abrupt. I'm striving to enhance the transition for a smoother output.

Here's a fiddle showcasing the problem within a 400px wide container:

body {
  max-width: 400px;
}
.row [class*='col-'] {
    transition: all .3s;
}
button {
  display: inline-flex;
  align-items: center;
  justify-content : center;
  overflow: hidden;
  max-width: 100%;
  transition: all .3s;
}
button span {
  overflow: hidden;
  white-space: nowrap;
  max-width: 100%;
  transition: max-width .3s;
}
button.btn--shrink span {
  max-width: 0;
}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" integrity="sha384-PDle/QlgIONtM1aqA2Qemk5gPOE7wFq8+Em+G/hmo5Iq0CCmYZLv3fVRDJ4MMwEA" crossorigin="anonymous">

    <title>Hello, world!</title;
  </head>
  <body>
    <div class="row justify-content-end">
        <div class="col-auto">
            <button>
                <span>A button</span>
            </button>
        </div>
        <div class="col-auto">
            <button onclick="this.classList.toggle('btn--shrink')">
                <span>A shrinkable button</span>
            </button>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js" integrity="sha384-7aThvCh9TypR7fIc2HV4O/nFMVCBwyIUKL8XCtKE+8xgCgl/PQGuFsvShjr74PBp" crossorigin="anonymous"></script>
  </body>
</html>

I've explored various solutions on Stack Overflow without success in resolving my specific issue. Though seemingly straightforward, I remain stuck and seek assistance in tackling this matter.

Your help is greatly appreciated.

Answer №1

To create a fading effect for the span inside the button, utilizing flexbox properties can be helpful. By setting each button to flex: 1;, their width will remain consistent regardless of content. Additionally, in this example, I have included min-height and min-width values. Hopefully, this solution addresses your issue accurately.

Update: Upon further consideration, I have refined my answer with additional code to ensure that the buttons shrink uniformly.

$(".shrinker").on("click", function() {
      $(this).addClass("shrank").siblings().addClass("shrank");
    $(this).children("span").fadeToggle(600);
});
main {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  width: 100%;
}

.button {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 1rem;
  padding: 0 30px;
  background: goldenrod;
  color: #1a1a1a;
  font-weight: bold;
  font-family: sans-serif;
  text-align: center;
  min-height: 50px;
  flex: 1;
  transition: .6s min-width ease-in-out, .6s flex ease-in-out;
}

.shrinker {
  position: relative;
}

.shrinker img {
  position: absolute;
  opacity: 0;
  max-width: 30px;
  display: inline-block;
  transition: .2s opacity ease-in-out;
}

.button span {
  display: flex;
}

.shrank {
  flex: 0;
}

.shrank > img {
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main>
  <div class="button">
    <span>button one</span>
  </div>
  <div class="button shrinker">
    <span>shrinking btn</span>
    <img src="https://c.tenor.com/I6kN-6X7nhAAAAAj/loading-buffering.gif" />
  </div>
</main>

Answer №2

Implement smooth transitions:

function minimize(element) {
  element.innerHTML = "vanished";
  element.style.minHeight = "10px";
}
#minimizable {
  min-height: 100px;
  transition: 3s;
}
<button id='regular'>Regular</button>
<button id='minimizable' onclick='minimize(this)'>A Minimizable Button</button>

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

Find the maximum width of an element within a Div that is larger than the widths of the other three elements using jQuery

After implementing a Dialog using JqueryUI, I noticed that inside the dialog there is a <div>. Within this <div>, there are three <button> elements labeled "Delete", "Cancel", and "Ok". Interestingly, the widths of these elements are auto ...

Adaptable triple-column design

After completing the layout of my website, everything seems to be functioning well. However, I would like to ensure that I haven't overcomplicated it or used poor techniques. The structure involves a main DIV with a nested table DIV, inside of which ...

Button to close CSS overlay scrolls to the top of the page

I have managed to create a CSS-only solution where clicking on an anchor displays an overlay image on top of a div. Everything works smoothly except for one issue: when the close button is clicked, it scrolls to the top of the page instead of closing and s ...

Adjust the size of the Vimeo video to fit the container dimensions and eliminate any black bars

Is there a way to eliminate the black bars that are present in the vimeo video which has been embedded? Below is the link to the code snippet. JSFiddle Link <div class="embed-container"> <iframe src="https://player.vimeo.com/video/86019637?title= ...

What is the method for creating a variable that is dynamic in nature?

I have encountered a small issue that I am struggling to resolve. There is one div that should execute a jQuery code on onTouchEnd, and it does so perfectly. The function sends the ID of the specific div. <div id="tapme1" class="subject hold" onTouchE ...

Spacing Between Bootstrap Columns

Is there a way to add a gap between each column while still maintaining 4 columns per row? When I try using the margin property, the columns do not align properly. Can you suggest a solution? <style> .test { border: 5px solid red; } </style&g ...

choose the <li> element with no <a> tag

Hello there, I am looking for a way to keep the padding consistent in <li> elements, but have it applied to the <a> tag instead when it's a link (to create a larger selection area). li a { padding: 1rem; } li:not(a) { padding: 1rem ...

`trouble encountered when utilizing the border shorthand attribute`

I can't seem to get the border shorthand property (border: 10px 2px 3px 4px solid black;) to work properly. Any ideas why? I attempted to use the border shorthand property (border: 10px 2px 3px 4px solid black;) on my element, but it's not displ ...

What is the best way to position the tooltip text so it doesn't affect the layout when hidden?

Explore this link for the code snippet Here's the code that indicates when a tooltip is not displayed, it still occupies space. What methods can be implemented to position tooltip divs in a way that they don't take up space when hidden and avoi ...

Every popover I open displays the same content as the first one

I want to create a table of products with an edit and delete button in each row. Clicking the edit button will trigger a popover containing a form to update the product, while the delete button is for confirmation. Each row in the table corresponds to a p ...

Tips for showcasing a full body height background

I'm currently working on a project where I need to display random background images when the body loads. To achieve this, I've created a function. However, I'm facing an issue where the images are filling up the entire page, making it very l ...

What steps can be taken to address issues with the counting system in a lootbox opening

I am currently developing a virtual loot box simulator and have encountered a challenging issue. My goal is to track the quantity of Normals, Legendaries, Epics, and Rares obtained by the user. However, I am facing a problem where instead of updating the c ...

Issues with table nesting functionality

I'm attempting to organize tables in a nested manner, instead of placing a table within each cell. My engineers have advised against simply styling the table to appear nested, and suggested that it would be more effective to wrap each header around th ...

What makes the nav class different from the navbar class in Bootstrap?

Recently, I delved into learning about bootstrap and web development. To my surprise, I stumbled upon the nav and navbar classes in bootstrap 4. I'm curious to know what sets them apart from each other and when it's best to use one over the other ...

Angular 2's solution for a persistent footer at the bottom of the page

I'm currently working on a project using Angular 2, and I'm looking to implement a sticky footer that always stays at the bottom of the page without being fixed. For reference, you can check out an example here: http://codepen.io/chriscoyier/pen/ ...

What might be causing the sticky footer to malfunction on the Samsung Galaxy Note 2's default browser?

I recently implemented a sticky footer design on my website, following the guidance of Ben Frain's book "Responsive Web Design with HTML5 and CSS3" (second edition). While it works flawlessly on most modern browsers, I encountered an issue with the Sa ...

Changing the Background Color of the Toolbar in Ionic

I am having trouble making the background color of my footer dynamic. I have tried binding the element to a class or applying dynamic styling, but it doesn't seem to work. Even when I have this in my HTML: <ion-footer align="center" style="height: ...

What is the best way to emphasize a div depending on a query outcome?

A new application is in the works for a gaming project. This app is designed to display the location of a specific monster, utilizing a database containing information about monsters and their corresponding maps. Currently, the application functions almos ...

Update the CSS styling in Angular when the mouse enters

I have a unique dart and event with their own ids created in separate controllers. My goal is to create a functionality where hovering over the dart highlights the corresponding event with the same id, and vice versa. The events are displayed on the image& ...

Is there a way to align a threejs object in the middle of a div container

My attempt at centering an object inside a div on my website using JS code has hit a roadblock. Despite trying various posted solutions, I haven't been successful. Any assistance would be greatly appreciated. import * as THREE from 'three'; ...