<div class="notify bar-top do-show" data-notification-status="success">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure, reprehenderit obcaecati itaque. Officiis libero provident perspiciatis eum fugiat laudantium sequi.</div>

<main>
  <div class="wrapper">
    <h1>CSS-only Notifications Component</h1>

    <p>
      This is a Sass mixin that provides notifications functionality using little-to-none Javascript.<br> It makes use of CSS transitions and animations to display notifications as popups or bars on different locations of the viewport.<br> The best thing
      is that it is fully customizable and easy to use. :)
    </p>

    <nav>
      <a href="#" class="button" data-type="top-left" data-status="success">Top Left</a>
      <a href="#" class="button" data-type="top-right" data-status="warning">Top Right</a>
      <a href="#" class="button" data-type="bottom-right" data-status="error">Bottom Right</a>
      <a href="#" class="button" data-type="bottom-left" data-status="notice">Bottom Left</a>
      <a href="#" class="button" data-type="bar-top" data-status="plain">Top bar</a>
      <a href="#" class="button" data-type="bar-bottom" data-status="plain">Bottom bar</a>
    </nav>
  </div>
</main>
////
/// Notifications
/// @group components
/// @author Damián Muti
////

@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro');

///
$notification-status: (
  'notice': (
    color: #29B6F6,
    icon: 'M11.016,6.984V9h1.968V6.984H11.016z M11.016,17.016h1.968v-6h-1.968V17.016z'
  ),
  'warning': (
    color: #FFCA28,
    icon: 'M11.016,17.016h1.968V15h-1.968V17.016z M11.016,6.983v6.001h1.968V6.983H11.016z'
  ),
  'error': (
    color: #EF5350,
    icon: 'M13.406,12l2.578,2.578l-1.406,1.406L12,13.406l-2.578,2.578l-1.406-1.406L10.594,12L8.016,9.421l1.406-1.405L12,10.593 l2.578-2.577l1.406,1.405L13.406,12z'
  ),
  'success': (
    color: #66BB6A,
    icon: 'M10.477,13.136l5.085-5.085l1.406,1.406l-6.492,6.492l-3.446-3.445l1.406-1.406L10.477,13.136z'
  ),
  'question': (
    color: #8D6E63,
    icon: 'M12.001,6.314h-0.002c-1.996,0-3.609,1.614-3.609,3.609h1.784c0-0.977,0.85-1.784,1.826-1.784  c0.977,0,1.827,0.807,1.827,1.784c0,1.826-2.718,1.614-2.718,4.544h1.784c0-2.038,2.717-2.294,2.717-4.544  C15.609,7.928,13.997,6.314,12.001,6.314z M11.109,17.186h1.784v-1.826h-1.784V17.186z'
  ),
  'plain': (
    color: #333
  )
);
///
$notification-toast-positions: (
  'top left': (
    top: 0,
    left: 0
  ),
  'top right': (
    top: 0,
    right: 0
  ),
  'bottom right': (
    bottom: 0,
    right: 0
  ),
  'bottom left': (
    bottom: 0,
    left: 0
  )
);
///
$notification-icon-size: 30px !default;
///
$notification-box-shadow: true !default;
///
$notification-show-icon: true !default;
///
$notification-toast-margin: 20px !default;
///
$notification-toast-max-width: 350px !default;
///
$notification-toast-total-width: $notification-icon-size + ($notification-toast-margin * 2) + $notification-toast-max-width;

@keyframes fade-in {
  from {
    visibility: hidden;
    opacity: 0;
  }

  to {
    visibility: visible;
    opacity: 1;
  }
}

@keyframes slide-show {
  to {
    transform: translateY(0);
  }
}

/// URL-encode color SASS function / convert color to hex SASS function.
/// @param {color} $color - Hex color value to convert.
/// @return {string} URL-encode color value.
@function encode-color($color) {
  @if type-of($color) == 'color' {
    $hex: str-slice(ie-hex-str($color), 4);
    $color: unquote("#{$hex}");
  }
  
  $color: '%23' + $color;
  
  @return $color;
}

/// Generates an SVG with a given fill color depending on the type of icon passed as parameter. The SVG string is scaped for cross-browser support.
/// @param {string} $icon - Type of icon. Accepted values: `quarter`, `half`, `three-quarters` or `full`.
/// @param {color} $color - Passes the fill color of the SVG icon that is being generated. Note: Hexa color values must be escaped for cross-browser support.
/// @return {string} background value.
@function get-icon($status, $icon, $color) {
  @return url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.984c4.407 0 8.016 3.609 8.016 8.016 0 4.406-3.608 8.016-8.016 8.016S3.984 16.407 3.984 12 7.593 3.984 12 3.984m0-2C6.478 1.984 1.984 6.477 1.984 12c0 5.521 4.493 10.016 10.016 10.016S22.016 17.522 22.016 12c0-5.523-4.495-10.016-10.016-10.016zm0 2c4.407 0 8.016 3.609 8.016' fill='" + encode-color($color) + "'/%3E%3Cpath d='" + map-get(map-get($notification-status, $status), $icon) + "' fill='" + encode-color($color) + "'/%3E%3C/svg%3E") center / cover no-repeat;
}

/// Component that shows two different types of notification boxes: toast and bar.
/// @param {string} $position ['bottom right'] - Positioning for each notification box. Accepted values: `top left`, `top right`, `bottom right` or `bottom left`.
/// @param {string} $type [toast] - Type of notification. Accepted values: `toast` or `bar`.
/// @param {string} $animation [slide] - Animation style to show the notification. Accepted values: `slide` or `fade`.
/// @param {number} $duration [1s] - Duration of the show/hide animation.
/// @param {number} $persistance [3s] - Visibility duration.
@mixin c-notification($position: 'bottom right', $type: toast, $animation: slide, $duration: 1s, $persistance: 3s) { 
    position: fixed;
    z-index: 1000;
    display: flex;
    align-items: center;
    padding: 20px;
    color: #fff;
    line-height: 1.3;
  
    @if($notification-box-shadow) {
      box-shadow: 0 0 15px 0 rgba(#000, 0.35);
    }
  
    @if $animation == fade {
      visibility: hidden;
      opacity: 0;
      
      &.do-show {
        animation: 
          fade-in $duration ease-in-out forwards, 
          fade-in $duration ease-in-out reverse forwards $persistance;
      }
    }

    // Toast type
    @if $type == toast {
      max-width: $notification-toast-max-width;
      margin: $notification-toast-margin;
      
      // Iterate through $notification-toast-positions map and generate the proper styling
      @each $pos, $coords in $notification-toast-positions {
        @if $pos == $position {
          $separator: str-index($position, ' ');
          $y: str-slice($position, 0, ($separator - 1));
          $x: str-slice($position, ($separator + 1));
          
          #{$y}: map-get($coords, $y);
          #{$x}: map-get($coords, $x); 
             
          @if $animation == slide {
            @at-root {
              @keyframes slide-in-#{$x} {
                to {
                  transform: translateX(0);
                }
              }
            }
            
            transform: translateX(if($x == left, #{'-'}, #{''})#{$notification-toast-total-width + map-get($coords, $x)});
            
            &.do-show {
              animation: 
                slide-in-#{$x} $duration ease-in-out forwards, 
                slide-in-#{$x} $duration ease-in-out reverse forwards $persistance;
            }
          }
        }
      }
    }
    @elseif $type == bar {
      #{$position}: 0;
      right: 0;
      left: 0;
      width: 100%;
      
      @if $animation == slide {
        transform: translateY(if($position == top, '-', '')100%); 
      
        &.do-show {
          animation: 
            slide-show $duration forwards, 
            slide-show $duration reverse forwards $persistance;
        }
      }
    }

    // Iterate through $notification-status-color map and create the proper classes
    @each $status-type, $status-data in $notification-status {   
      &[data-notification-status="#{$status-type}"] {
        background-color: map-get($status-data, color);
        
        @if($notification-show-icon) and map-get($status-data, icon) {
          &:before {
            content: '';
            display: block;
            width: $notification-icon-size;
            height: $notification-icon-size;
            min-width: $notification-icon-size;
            margin-right: $notification-toast-margin;
            background: get-icon($status-type, icon, darken(map-get($status-data, color), 20%));
          }
        }
      }
    }
}


// Other styles related to this specific pen
body { 
  width: 100%;
  height: 100vh;
  background: linear-gradient(to bottom, #be93c5, #7bc6cc);
  font-family: 'Source Sans Pro', sans-serif;
  text-rendering: optimizeLegibility;
}

main {
  width: 100vw; 
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

h1 {
  color: #fff;
  font-size: 55px;
}

p {
  line-height: 1.5
}

nav {
  margin-top: 50px;
}

.button {
  padding: 15px 20px;
  border: 2px solid white;
  border-radius: 5px;
  font-size: 13px;
  font-weight: 700; 
  text-transform: uppercase;
  text-decoration: none;
  color: white;
  
  &:hover,
  &.is-active {
    color: #be93c5;
    background-color: white;
  }
}

// Types of notifications
.top-left { 
  @include c-notification($position: 'top left', $type: toast, $animation: slide, $duration: 1s, $persistance: 5s)
}

.top-right {
  @include c-notification($position: 'top right', $type: toast, $animation: fade, $duration: 1s, $persistance: 3s)
}

.bottom-right {
  @include c-notification($position: 'bottom right', $type: toast, $animation: slide, $duration: 1s, $persistance: 3s)
}

.bottom-left {
  @include c-notification($position: 'bottom left', $type: toast, $animation: fade, $duration: 1s, $persistance: 3s)
}

.bar-top {
  @include c-notification($position: 'top', $type: bar, $animation: slide, $duration: 1s, $persistance: 3s)
}

.bar-bottom {
  @include c-notification($position: 'bottom', $type: bar, $animation: fade, $duration: 1s, $persistance: 3s)
}
View Compiled
$('.button').on('click', function(event){
  var type = $(this).data('type');
  var status = $(this).data('status');
  
  $('.button').removeClass('is-active');
  $(this).addClass('is-active');
  
  $('.notify')
    .removeClass()
    .attr('data-notification-status', status)
    .addClass(type + ' notify')
    .addClass('do-show'); 
  
  event.preventDefault();
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js