Display the percentage text behind a filling Bootstrap progress bar

I'm working on a bootstrap progress bar that displays a percentage along with the numerical value. Currently, the text fits next to the progress bar up until around 85%, after which it blocks the bar from growing further. You can see the issue in the screenshot below (the top bar should be fully filled).

https://i.stack.imgur.com/t2QIt.png

My goal is to have the text aligned next to the bar but allow the bar to continue growing behind the text when it reaches the right side. For instance, at 95%, about half of the text's background should be filled, and at 100%, the entire progress bar should be filled with the text overlaying it.

The code I currently have for one bar is as follows:

<td class="occurrence fw-normal text-light small pe-4">
  <div class="progress d-flex">
    <div class="progress-bar occurrence" 
      role="progressbar" 
      aria-valuemin="0" 
      aria-valuemax="100" 
      aria-valuenow="100" 
      data-bs-toggle="tooltip" 
      data-bs-placement="top" 
      title="" 
      style="width: 100%;" 
      data-bs-original-title="Appears in 10 comments" 
      aria-label="Appears in 10 comments">
    </div>
    <span class="occurrence percentage mx-2 fw-bold">
      100&nbsp;%
    </span>
  </div>
</td>

I've attempted adjusting the position and display properties of both the progress bar and text without success. How can I achieve the desired layout?

Answer №1

To achieve this effect, JavaScript is necessary.

In order for the label to be displayed in front of the progress bar, you must set the label's position to absolute.

Then, using JavaScript, retrieve the bar, label, and container widths for later use.

After that, set the width of the bar, add the label width to it, check if it fits the container, move it from the right by calculating the gap if needed, or place it at the far right if it doesn't fit properly, thus displaying it in front of the bar.

Here is the essential code snippet:

if ((bar + label) < container) {

  labelEl.style.setProperty('right', `${container-(bar+label)}px`);

} else {

  labelEl.style.right = `0`;
}

Furthermore, manual animation of the label is required, so include the following transition style for the bar:

style="transition:right .6s ease;"

Below is a demonstration snippet (note that it may have some bugs but should offer a general understanding of how it can be done, depending on how you set the widths):

addEventListener("DOMContentLoaded", (event) => {

    let iteration = 1;

    const interval = setInterval(function() {

      const barEl = document.querySelector('.progress-bar');

      barEl.style.setProperty('width', iteration * 5 + '%');

      const labelEl = document.querySelector('.progress-label');

      const container = parseFloat(getComputedStyle(document.querySelector('.progress')).width);

      let bar = parseFloat(getComputedStyle(barEl).width);


      const labelData = getComputedStyle(labelEl);
      
      // calc margins
      const labelMargins = parseFloat(labelData.marginLeft) + parseFloat(labelData.marginRight);

      const label = parseFloat(labelData.width) + labelMargins * 2;

      // check spacing, move label accordingly
      // else, fix to right
      if ((bar + label) < container) {

        labelEl.style.setProperty('right', `${container-(bar+label)}px`);

      } else {

        labelEl.style.right = `0`;
      }

      labelEl.textContent = iteration * 5 + '%';

      if (++iteration > 20) {
        clearInterval(interval);
      }


    }, 300);


})
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="25474a4a51565157445565100b140b">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8fece0fdeacfbda1bebfa1bd">[email protected]</a>/dist/umd/popper.min.js" ></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="27454848535453554657671209160914">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col"></th>
      <th scope="col"></th>
      <th scope="col"></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td></td>
      <td></td>
<td class="occurrence fw-normal text-light small pe-4">
<div class="progress  position-relative">
    <div class="progress-bar occurrence"
         role="progressbar"
         aria-valuemin="0"
         aria-valuemax="100"
         aria-valuenow="100"
         data-bs-toggle="tooltip"
         data-bs-placement="top"
         title=""
 
         data-bs-original-title="Appears in 10 comments"
         aria-label="Appears in 10 comments">
    </div>
    <span class="occurrence percentage mx-2 fw-bold progress-label position-absolute" style="transition:right .6s ease;"></span>
  </div>
</td>
    </tr>

  </tbody>
</table>

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

What is the best way to modify the colors of two specific elements using a combination of CSS and JavaScript

I am currently developing a browser-based game and have encountered an issue. Here is the relevant line of my HTML/PHP code: echo '<div id="div'.$n.'" class="d'.$rand.'" onclick="swapit(this.id, this.className)"></di ...

ConnectionError: 404 Page Not Located

Why am I receiving downvotes? This is the second time I've been downvoted. Please, at least tell me the reason so that I can improve. I am currently using the jQuery get method to send data from HTML to PHP (both are hosted on localhost/Site1). Edit ...

Generating a business card example using node-html-pdf on an Ubuntu operating system

I am currently attempting to utilize the node-html-pdf module on Ubuntu 16.04 by following the businesscard example provided at https://github.com/marcbachmann/node-html-pdf. Regrettably, I encountered difficulties in generating the PDF file. To begin wi ...

Included adaptable background-images in the upload

Recently, I developed a RoR based app/website that allows clients to upload their own background image to the cover page. Although the current setup works well with a single image, I am aiming to enhance the site's responsiveness by enabling clients t ...

Pattern to filter out numeric values from a collection

I want to apply a regex pattern to the <input> form element. The pattern should specify a range of numbers that are not permitted as input. For example, let's say I have a list of numbers like {1,4,10}, and any number other than these should be a ...

Issues with centering background-position while using clip-path functionality

Struggling to center a background image? I initially suspected conflicting CSS rules, so I created a simplified demo to troubleshoot. After reviewing examples on SO and beyond, it seems like my approach is correct. Can anyone help identify what I might be ...

Display a fresh <p> tag when the condition in the if-statement is met

If you are looking for a questionnaire, check out this one. Now, I am interested in creating if-statements using HTML/CSS/jQuery to achieve the following scenario: Initially, only Question 1 will be visible. When the input matches a certain value like X, ...

What are the steps to create a CSS 'shell' design?

How can I create an image displayed as a circle with border-radius:50%, along with some text on the same line that has a set width and background color? I want to achieve this without hard coding values. What is the best approach to do this? Check out the ...

Simple HTML files on a local server are having trouble loading images and JavaScript, yet the CSS is loading

Having worked in web design for quite some time, I recently began working on a basic Angular app that is meant to be very simple. For this project, I am only using the angular files and a single html file as the foundation. As I started setting up the bas ...

Click to add a card

Attempting to incorporate a new row with the click of a button dynamically has proven to be challenging for me. As someone who is relatively new to JavaScript, I am struggling to figure it out. In the demonstration provided below, you will notice that noth ...

Ways to adjust image placement and size post-rotation with CSS/JS to ensure it stays within the containing div and avoids being cut off

Check out this jsfiddle I've been experimenting with. The jsfiddle is designed to rotate an image by 90 degrees in either clockwise or anti-clockwise direction upon button click. However, the rotated image currently appears outside of its parent div. ...

The MDL layout spacer is pushing the content to the following line

Here's an interesting approach to Material Design Lite. In this example from the MDL site, notice how the 'mdl-layout-spacer' class positions elements to the right of the containing div, giving a clean layout: Check it out <!-- Event ca ...

Div blur event for editing content

Utilizing a content editable div as an input control has presented some challenges for me. Unlike a textarea or input element, the div does not send information to the server automatically. To work around this issue, I have implemented a solution where I u ...

Establishing the focal point and emphasis within a textarea input field

I am presenting a textarea input through PHP with the following command : print " '<textarea rows='16' cols='30'>$flist'</textarea><BR>"; I want the textarea to receive focus and automatically select the co ...

How to center align a <p> element along with a <select> element

Having some trouble while redesigning a simple survey page. I want to center-align the p tag with the select tag without using display:flex inside the .combobox class. The goal is to have them on the same line and still be centered. The current layout loo ...

Showing the computation outcome on the identical page

I have implemented a table within my PHP code. In the second column of this table, it typically displays "---". However, once I click the submit button, the same page should now display the calculated result. Here is an example: <table> <tr>& ...

Inject $scope into ng-click to access its properties and methods efficiently

While I know this question has been asked before, my situation is a bit unique. <div ng-repeat="hello in hello track by $index"> <div ng-click="data($index)"> {{data}} </div> </div> $scope.data = function($index) { $scope.sweet ...

Tips for reversing a sketch: Creating a timer where the text continuously refreshes causing it to intersect

Currently, I am working on developing a stopwatch that is functional. However, I am facing an issue where the text overlaps itself when it changes due to repetitive drawing. Removing the strokeText and fillText from the interval prevents it from changing a ...

The database powered by Postgresql performs flawlessly when it comes to updating data with accurate code execution. However, there seems to be an

Imagine a zoo with a postgresql database. To enable web access to this database, I am using php and javascript. Most of the web pages are working fine, but I am currently working on a page where clients can add or remove animals from existing exhibits. T ...

Sneaky footer paired with a side panel

Trying to incorporate a sticky footer within the content area of a page that includes a full-height sidebar. Here is a preview of the page I'm currently working on: I have experience using in the past with success, utilizing methods involving percen ...