Search code examples
progress-bartooltipbootstrap-5

Bootstrap progress bar with tooltip as legend


I have created a bootstrap toolbar with multiple sections in different styles. Now I want to add a tooltip that serves as a legend, explaining what the different styles stand for. But the styles do not appear inside the tooltip. Is this possible at all? How can I make this work?

Here a jsfiddle to demonstrate the issue: https://jsfiddle.net/xdg5b7ys/

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container mt-3">
  <div class="progress" style="width:300px" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" title="<div class='text-start'><div class='progress'><div class='progress-bar bg-success opacity-50' role='progressbar' style='width: 100%' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100'></div></div>Gebudgetteerd: 800<br><div class='text-start'><div class='progress'><div class='progress-bar bg-success' style='width: 100%' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100'></div></div>Definitief: 327.79<br><div class='text-start'><div class='progress'><div class='progress-bar-striped bg-success' style='width: 100%' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100'></div></div>Proef: 118.52</div>">
    <div class="progress-bar bg-success" role="progressbar" style="width: 40.97375%" aria-valuenow="40.97375" aria-valuemin="0" aria-valuemax="100"></div>
    <div class="progress-bar-striped bg-success" role="progressbar" style="width: 14.815000000000001%" aria-valuenow="14.815000000000001" aria-valuemin="0" aria-valuemax="100"></div>
    <div class="progress-bar bg-success opacity-50" role="progressbar" style="width: 44.21125%" aria-valuenow="44.21125" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
</div>

<script>
// Initialize tooltips
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
  return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>

</body>
</html>

Here's what I see: enter image description here

I would expect the progress bars in the tooltip to have the style I've set on them but they just appear gray.


Solution

  • It's because style attribute is not applied, because it's being removed by the sanitizer, so the bar element has no width, so no background is applied.

    Only these attributes are allowed for div:

    // Global attributes allowed on any supplied element below.
    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],

    So, use Bootstrap's size utility class w-100 to add width instead of style attribute:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Bootstrap Example</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    </head>
    <body>
    
    <div class="container mt-3">
      <div class="progress" style="width:300px" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" title="<div class='text-start'><div class='progress'><div class='progress-bar bg-success opacity-50 w-100' role='progressbar' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100'></div></div>Gebudgetteerd: 800<br><div class='text-start'><div class='progress'><div class='progress-bar bg-success w-100' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100'></div></div>Definitief: 327.79<br><div class='text-start'><div class='progress'><div class='progress-bar-striped bg-success w-100' aria-valuenow='100' aria-valuemin='0' aria-valuemax='100'></div></div>Proef: 118.52</div>">
        <div class="progress-bar bg-success" role="progressbar" style="width: 40.97375%" aria-valuenow="40.97375" aria-valuemin="0" aria-valuemax="100"></div>
        <div class="progress-bar-striped bg-success" role="progressbar" style="width: 14.815000000000001%" aria-valuenow="14.815000000000001" aria-valuemin="0" aria-valuemax="100"></div>
        <div class="progress-bar bg-success opacity-50" role="progressbar" style="width: 44.21125%" aria-valuenow="44.21125" aria-valuemin="0" aria-valuemax="100"></div>
      </div>
    </div>
    
    <script>
    // Initialize tooltips
    var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
    var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
      return new bootstrap.Tooltip(tooltipTriggerEl)
    })
    </script>
    
    </body>
    </html>

    Or you can disable sanitizer or add your custom sanitizer via sanitize and sanitizeFn options

    For example, your HTML will work if you disable sanitizer:

    return new bootstrap.Tooltip(tooltipTriggerEl, {sanitize:false})