CSS Animated Modal Window

By | October 27, 2018

In this tutorial show how to make Animated CSS Dialog Box using HTML, JavaScript, SVG and CSS. It’s very helpful for all developers who need to create awesome project using this animation dialog box framework.

Demo / Download

Author Ashwin Saxena
Created MARCH 25, 2015
License Open
Compatible browsers Chrome, Firefox, Safari

HTML Code


 <div class="button-wrap"><button data-dialog="somedialog" class="trigger">Open Dialog</button></div>

<div id="somedialog" class="dialog dialog--close">
					<div class="dialog__overlay"></div>
					<div class="dialog__content">
						<div class="morph-shape">
							<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 560 280" preserveAspectRatio="none">
								<rect x="3" y="3" fill="none" width="556" height="276"></rect>
							</svg>
						</div>
						<div class="dialog-inner">
							<h2><strong>Howdy</strong>, I'm a dialog box</h2>
							<div><button class="action" data-dialog-close="a">Close</button></div>
						</div>
					</div>
				</div> 

CSS Code

button {
	padding: 1em 2em;
	outline: none;
	font-weight: 600;
	border: none;
	color: #fff;
	background: #c94e50;
}

.dialog,
.dialog__overlay {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
}

.dialog {
	position: fixed;
	display: -webkit-flex;
	display: flex;
	-webkit-align-items: center;
	align-items: center;
	-webkit-justify-content: center;
	justify-content: center;
	pointer-events: none;
}

.dialog__overlay {
	position: absolute;
	z-index: 1;
	background: rgba(55, 58, 71, 0.9);
	opacity: 0;
	-webkit-transition: opacity 0.3s;
	transition: opacity 0.3s;
	-webkit-backface-visibility: hidden;
}

.dialog--open .dialog__overlay {
	opacity: 1;
	pointer-events: auto;
}

.dialog__content {
	width: 50%;
	max-width: 560px;
	min-width: 290px;
	background: #fff;
	padding: 4em;
	text-align: center;
	position: relative;
	z-index: 5;
	opacity: 0;
}

.dialog--open .dialog__content {
	pointer-events: auto;
}


;
(function(window) {

    'use strict';

    var support = {
            animations: Modernizr.cssanimations
        },
        animEndEventNames = {
            'WebkitAnimation': 'webkitAnimationEnd',
            'OAnimation': 'oAnimationEnd',
            'msAnimation': 'MSAnimationEnd',
            'animation': 'animationend'
        },
        animEndEventName = animEndEventNames[Modernizr.prefixed('animation')],
        onEndAnimation = function(el, callback) {
            var onEndCallbackFn = function(ev) {
                if (support.animations) {
                    if (ev.target != this) return;
                    this.removeEventListener(animEndEventName, onEndCallbackFn);
                }
                if (callback && typeof callback === 'function') {
                    callback.call();
                }
            };
            if (support.animations) {
                el.addEventListener(animEndEventName, onEndCallbackFn);
            } else {
                onEndCallbackFn();
            }
        };

    function extend(a, b) {
        for (var key in b) {
            if (b.hasOwnProperty(key)) {
                a[key] = b[key];
            }
        }
        return a;
    }

    function DialogFx(el, options) {
        this.el = el;
        this.options = extend({}, this.options);
        extend(this.options, options);
        this.ctrlClose = this.el.querySelector('[data-dialog-close]');
        this.isOpen = false;
        this._initEvents();
    }

    DialogFx.prototype.options = {
        // callbacks
        onOpenDialog: function() {
            return false;
        },
        onCloseDialog: function() {
            return false;
        }
    }

    DialogFx.prototype._initEvents = function() {
        var self = this;

        // close action
        this.ctrlClose.addEventListener('click', this.toggle.bind(this));

        // esc key closes dialog
        document.addEventListener('keydown', function(ev) {
            var keyCode = ev.keyCode || ev.which;
            if (keyCode === 27 && self.isOpen) {
                self.toggle();
            }
        });

        this.el.querySelector('.dialog__overlay').addEventListener('click', this.toggle.bind(this));
    }

    DialogFx.prototype.toggle = function() {
        var self = this;
        if (this.isOpen) {
            classie.remove(this.el, 'dialog--open');
            classie.add(self.el, 'dialog--close');

            onEndAnimation(this.el.querySelector('.dialog__content'), function() {
                classie.remove(self.el, 'dialog--close');
            });

            // callback on close
            this.options.onCloseDialog(this);
        } else {
            classie.add(this.el, 'dialog--open');

            // callback on open
            this.options.onOpenDialog(this);
        }
        this.isOpen = !this.isOpen;
    };

    // add to global namespace
    window.DialogFx = DialogFx;

})(window);




(function() {

    var dlgtrigger = document.querySelector('[data-dialog]'),
        somedialog = document.getElementById(dlgtrigger.getAttribute('data-dialog')),
        dlg = new DialogFx(somedialog);

    dlgtrigger.addEventListener('click', dlg.toggle.bind(dlg));

})();

Preview

CSS Animated Modal Window 1