Search code examples
javascripthtmltoastbootstrap-5

Show toast at bottom-right after scroll down (bootstrap 5)


Using classes bottom-0 end-0 (at least the way I use them) does not achieve the results I expect. I suppose I don't understand something very basic about css and positioning.

Here is a minimal self-contained example of the code:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">

    <!-- Bootstrap -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>

    <script type="text/javascript">

      /** 
       * Usage: showToast('hey!', 'success'); 
       */
      function showToast(toastBody, color) {

        var delay = 3000;

        var html = 
`<div class="toast align-items-center text-white bg-${color} border-0" role="alert" aria-live="assertive" aria-atomic="true">
  <div class="d-flex">
    <div class="toast-body">
      ${toastBody}
    </div>
    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
  </div>
</div>`;
        var toastElement = htmlToElement(html);
        var toastConainerElement = document.getElementById("toast-container");
        toastConainerElement.appendChild(toastElement);       
        var toast = new bootstrap.Toast(toastElement, {delay:delay, animation:true}); 
        toast.show();

        setTimeout(() => toastElement.remove(), delay+3000); // let a certain margin to allow the "hiding toast animation"
      }

      /**
       * @param {String} HTML representing a single element
       * @return {Element}
       */
      function htmlToElement(html) {
          var template = document.createElement('template');
          html = html.trim(); // Never return a text node of whitespace as the result
          template.innerHTML = html;
          return template.content.firstChild;
      }      

    </script>    

  </head>
  <body>

    <h1>Toast test</h1>

    <p style="margin-bottom:1200px;">
      Scroll down to click the test button ...
    </p>

    <button onclick="showToast('If I am not at the bottom, then something went wrong...', 'danger')" class="btn btn-primary">
      Click me and the toast should appear at my right
    </button>

    <div aria-live="polite" aria-atomic="true">
      <div class="toast-container position-absolute bottom-0 end-0 p-3" id="toast-container">
        <!-- toasts are created dynamically -->
      </div>
    </div>

  </body>
</html>


Solution

  • I have found what seems to be the answer:

    <div class="toast-container position-absolute needs to be changed to <div class="toast-container position-fixed

    That is: I was using absolute instead of fixed, because I was just blindly copy-pasting the example from the documentation.