JSFiddle - React, Tailwind, and code Playground

HTML

<br/><br/><br/><br/><br/><br/><br/><br/>
<ul id="demo-links">
    <li><a href="#">Notification upper-left</a></li>
    <li><a href="#">Notification upper-right</a></li>
    <li><a href="#">Notification lower-left</a></li>
    <li><a href="#">Notification lower-right</a></li>
</ul>

CSS

.roar-body
{
    position:                absolute;
    font:                    12px/14px "Lucida Grande", Arial, Helvetica, Verdana, sans-serif;
    color:                    #fff;
    text-align:                left;
    z-index:                999;
}

.roar
{
    position:                absolute;
    width:                    300px;
    cursor:                    pointer;
}
.roar-bg
{
    position:                absolute;
    z-index:                1000;
    width:                    100%;
    height:                    100%;
    left:                    0;
    top:                    0;
    background-color:        #000;
    -moz-border-radius:        10px;
    -webkit-border-radius:    5px;
    -webkit-box-shadow:        0 0 5px rgba(0, 0, 0, 0.5);
}
.roar-body-ugly .roar
{
    background-color:        #333;
}
.roar-body-ugly .roar-bg
{
    display:                none;
}
.roar h3
{
    position:                relative;
    padding:                15px 10px 0;
    margin:                    0;
    border:                    0;
    font-size:                13px;
    color:                    #fff;
    z-index:                1002;
}
.roar p
{
    position:                relative;
    padding:                10px 10px 15px;
    margin:                    0;
    font-size:                12px;
    color:                    #fff;
    z-index:                1002;
}

JavaScript

/**
 * Roar - Notifications
 *
 * Inspired by Growl
 *
 * @version        1.0.1
 *
 * @license        MIT-style license
 * @author        Harald Kirschner <mail [at] digitarald.de>
 * @copyright    Author
 */

var Roar = new Class({

    Implements: [Options, Events, Chain],

    options: {
        duration: 3000,
        position: 'upperLeft',
        container: null,
        bodyFx: null,
        itemFx: null,
        margin: {x: 10, y: 10},
        offset: 10,
        className: 'roar',
        onShow: function(){},
        onHide: function(){},
        onRender: function(){}
    },

    initialize: function(options) {
        this.setOptions(options);
        this.items = [];
        this.container = $(this.options.container) || document;
    },

    alert: function(title, message, options) {
        var params = Array.link(arguments, {title: Type.isString, message: Type.isString, options: Type.isObject});
        var items = [new Element('h3', {'html': [params.title, ''].pick()})];
        if (params.message) items.push(new Element('p', {'html': params.message}));
        return this.inject(items, params.options);
    },

    inject: function(elements, options) {
        if (!this.body) this.render();
        options = options || {};

        var offset = [-this.options.offset, 0];
        var last = this.items.getLast();
        if (last) {
            offset[0] = last.retrieve('roar:offset');
            offset[1] = offset[0] + last.offsetHeight + this.options.offset;
        }
        var to = {'opacity': 1};
        to[this.align.y] = offset;

        var item = new Element('div', {
            'class': this.options.className,
            'opacity': 0
        }).adopt(
            new Element('div', {
                'class': 'roar-bg',
                'opacity': 0.7
            }),
            elements
        );

        item.setStyle(this.align.x, 0).store('roar:offset', offset[1]).set('morph', Object.merge({
            unit: 'px',
            link:...