Bulma Notifications



Build Simple Dismissible Notifications With Bulma CSS & jQuery

Bulma CSS already contains notification blocks but let's build something better out of them. We can do that right?

First we'll add some CSS to define the position of the notification.

.notifications {
  position: fixed;
  z-index: 9999;
  top: 25px;
  right: 15px;
  width: auto;
}

.notification {
  position: relative;
  top: 0;
  min-width: 100px;
  padding: 1rem 1.25rem 1rem 1.25rem;
  transition: .3s;
  text-align: center;
  box-shadow: 0 2px 3px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .1);
}

.notification:hover {
  cursor: pointer;
  transition: .3s;
  box-shadow: 0 2px 3px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .2);
}

And some more CSS as we want them to slide in and out of the viewport. I nabbed these from animate.css and edited them a little.

@-webkit-keyframes slideInRight {
  from {
    visibility: visible;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }

  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

@keyframes slideInRight {
  from {
    visibility: visible;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }

  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

.slideInRight {
  -webkit-animation-name: slideInRight;
  animation-name: slideInRight;
  -webkit-animation-duration: .3s;
  animation-duration: .3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

@-webkit-keyframes slideOutRight {
  from {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  to {
    visibility: hidden;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }
}

@keyframes slideOutRight {
  from {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  to {
    visibility: hidden;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }
}

.slideOutRight {
  -webkit-animation-name: slideOutRight;
  animation-name: slideOutRight;
  -webkit-animation-duration: .3s;
  animation-duration: .3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

Now we'll write some jQuery. First we'll append a div to the page to house our notifications. This div is in a fixed position at the top right of the viewport. You can change the position as you like using CSS.

$(function() {
  $('body').append("<div class='notifications'></div>");
});

Next is a function to create a random string to use as the notifications id as they are dynamically generated.

function stringGen(len) {
  var text = "";
  var charset = "abcdefghijklmnopqrstuvwxyz0123456789";
  for (var i = 0; i < len; i++)
    text += charset.charAt(Math.floor(Math.random() * charset.length));
  return text;
}

Then another to append the actual notifications to the div.

function notify(msg, mode, duration) {
  var classy = stringGen(9);
  $('.notifications').append(`<div id='${classy}' class='notification is-${mode} slideInRight'>${msg}</div>`)
  $('.notification').click(function() {
    $(this).removeClass('slideInRight');
    $(this).addClass('slideOutRight');
    setTimeout(function() {
      $(this).remove();
    }, 350);
  });
  setTimeout(function() {
    $(`#${classy}`).removeClass('slideInRight');
    $(`#${classy}`).addClass('slideOutRight');
    setTimeout(function() {
      $(`#${classy}`).remove();
    }, 350);
  }, duration);
}

Now we can call up a notification by simply calling notify(message, colour, duration); with it's variables like so. The colours are just the Bulma colours e.g. is-light/is-dark/is-success but without the is- part. The duration is in milliseconds.

notify('Hello world', 'light', 5000);

So let's chuck all this together to create a basic page with notifications.

index.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Bulma Notifications</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css">
  <link rel="stylesheet" href="styles.css">
</head>

<body>

  <section class="hero is-fullheight">
    <div class="hero-body">
      <div class="container has-text-centered">
        <a class="button">PRESS ME</a>
      </div>
    </div>
  </section>

  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <script src="scripts.js"></script>
</body>

</html>
styles.css
.notifications {
  position: fixed;
  z-index: 9999;
  top: 25px;
  right: 15px;
  width: auto;
}

.notification {
  position: relative;
  top: 0;
  min-width: 100px;
  padding: 1rem 1.25rem 1rem 1.25rem;
  transition: .3s;
  text-align: center;
  box-shadow: 0 2px 3px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .1);
}

.notification:hover {
  cursor: pointer;
  transition: .3s;
  box-shadow: 0 2px 3px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .2);
}

@-webkit-keyframes slideInRight {
  from {
    visibility: visible;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }

  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

@keyframes slideInRight {
  from {
    visibility: visible;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }

  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

.slideInRight {
  -webkit-animation-name: slideInRight;
  animation-name: slideInRight;
  -webkit-animation-duration: .3s;
  animation-duration: .3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

@-webkit-keyframes slideOutRight {
  from {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  to {
    visibility: hidden;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }
}

@keyframes slideOutRight {
  from {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  to {
    visibility: hidden;
    -webkit-transform: translate3d(150%, 0, 0);
    transform: translate3d(150%, 0, 0);
  }
}

.slideOutRight {
  -webkit-animation-name: slideOutRight;
  animation-name: slideOutRight;
  -webkit-animation-duration: .3s;
  animation-duration: .3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
scripts.js
function stringGen(len) {
  var text = "";
  var charset = "abcdefghijklmnopqrstuvwxyz0123456789";
  for (var i = 0; i < len; i++)
    text += charset.charAt(Math.floor(Math.random() * charset.length));
  return text;
}

function notify(msg, mode, duration) {
  var classy = stringGen(9);
  $('.notifications').append(`<div id='${classy}' class='notification is-${mode} slideInRight'>${msg}</div>`)
  $('.notification').click(function() {
    $(this).removeClass('slideInRight');
    $(this).addClass('slideOutRight');
    setTimeout(function() {
      $(this).remove();
    }, 350);
  });
  setTimeout(function() {
    $(`#${classy}`).removeClass('slideInRight');
    $(`#${classy}`).addClass('slideOutRight');
    setTimeout(function() {
      $(`#${classy}`).remove();
    }, 350);
  }, duration);
}

$(function() {
  $('body').append("<div class='notifications'></div>");
  $('.button').click(function() {
    notify('Hello world', 'light', 5000);
  });
});

View the demo HERE

Thanks for reading. x

Resources