JSFiddle - React, Tailwind, and code Playground

by achudars

HTML

<div class="wrapper">
    	<h1>Maintaining CSS Style States using "Infinite" Transition Delays</h1>

    <div class="device">
        <button class="up"></button>
        <button class="down"></button>
        <button class="left">
            </buton>
            <button class="right"></button>
            <div class="screen">
                <div class="char"></div>
                <div class="overlay"></div>
            </div>
    </div>
    <section>
        <p>This demo is <strong>completely JavaScript-free</strong>. Feel free to
            move the character around with the D-pad, and notice how it always keeps
            its position after you stop moving.</p>
        <p>This is made possible by using a virtually infinite transition delay,
            so that the CSS rules never return to their default state. The character
            will always be stuck in a transition and only moves when you hold down
            a button.</p>
        <p>I've written a	<a target="_blank" href="http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/"> blog post </a> explanining
            how this all works, but please keep in mind that things like this should
            ideally be handled with Javascript. After all, this is a dirty hack, not
            a CSS feature.</p>
    </section>	<small>Credit goes to to <a target="_blank" href="http://www.tekepon.net/fsm/">First Seed Material</a> for the 
	character sprite, and <a target="_blank" href="http://vxresource.wordpress.com/2010/03/17/the-real-macks-tileset/">
	Mack</a> for the map tileset.
	 </small>

</div>

CSS

/* CSS States */
 body {
    background: url(http://dabblet.com/img/noise.png);
    background-color: #F5F2F0;
    font-family: Georgia, serif;
    font-size: 18px;
    line-height: 1.6em;
    text-shadow: 0 2px 0 white;
    color: #222;
}
.wrapper {
    width: 900px;
    margin: 70px auto;
}
h1 {
    font-family: Helvetica, Arial, sans-serif;
    text-align: center;
    font-size: 1.6em;
}
a {
    text-decoration: none;
    color: #B46919;
}
a:visited {
    color: #834B0F;
}
a:hover {
    color: #E9A051;
}
.device {
    display: inline-block;
    position: relative;
    background:#AD0F0F;
    width: 230px;
    height: 450px;
    padding: 20px 15px;
    margin: 20px;
    border-radius: 20px;
    border: 1px solid #410707;
    border-bottom-width: 8px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.7), inset 0 0 10px rgba(255, 255, 255, 0.5), inset 0 2px 2px rgba(255, 255, 255, 0.25);
}
section {
    display: inline-block;
    vertical-align: top;
    padding: 30px;
    width: 500px;
}
small {
    display: block;
    margin-top: 20px;
    opacity: 0.3;
    text-align: center;
    padding: 20px;
    transition: opacity 0.5s;
}
small:hover {
    opacity: 1;
}
.up, .down, .left, .right {
    position: absolute;
    z-index: 1001;
    margin-left: 50%;
    font-size: 40px;
    width: 50px;
    height: 50px;
    background: #FFA03A;
    border: 1px solid #915515;
    box-shadow: 0 3px 0 #52300E, inset 0 0 10px rgba(255, 255, 255, 0.3);
    appearance: none;
    border-radius: 50px;
    cursor: pointer;
}
.up:active, .down:active, .left:active, .right:active {
    margin-top: 3px;
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.3);
}
.up:before, .down:before, .left:before, .right:before {
    display: block;
    position: absolute;
    content:"";
    width: 15px;
    height: 15px;
    border-radius: 15px;
    background: #E4923D;
    box-shadow: 0 2px 2px rgba(255, 255, 255, 0.25), inset 0 1px 0 rgba(0, 0, 0, 0.5);
}
.up:after, .down:after, .left:after, .right:after {
   ...

JavaScript

var style = document.querySelector('style');

var domLoaded = false;

document.addEventListener('DOMContentLoaded', function () {
    domLoaded = true;
});

onmessage = function (evt) {
    if (true || evt.origin === 'http://localhost' || evt.origin === 'http://dabblet.com') {
        var info = JSON.parse(evt.data),
            data = info.data;

        switch (info.action) {
            case 'title':
                document.title = data;
                break;

            case 'css':
                style.textContent = data;
                break;

            case 'html':
                document.body.innerHTML = data;
                break;

            case 'javascript':
                if (domLoaded) {
                    try {
                        document.body.innerHTML = document.body.innerHTML;
                        eval(data);
                    } catch (e) {
                        var lineNumber = e.lineNumber - 30 + 1 || (e.stack.match(/<anonymous>:(\d+):\d+/) || [, ])[1];

                        parent.postMessage(JSON.stringify({
                            action: 'jserror',
                            data: {
                                name: e.name,
                                message: e.message,
                                lineNumber: lineNumber
                            }
                        }), '*');
                    }
                } else {
                    document.addEventListener('DOMContentLoaded', function () {
                        onmessage(evt);
                    });
                }
        }
    }
};