JSFiddle - React, Tailwind, and code Playground

by secretgspot

HTML

<script src="http://leaverou.github.com/prefixfree/prefixfree.min.js"></script>
<hgroup>
    <h1><a href="#">Animatable</a></h1>
    <h2>One property, two values, endless possiblities</h2>
</hgroup>

<input type="radio" name="animate" id="on-hover" checked />
<label for="on-hover">Animate on hover</label>
<input type="radio" name="animate" id="all" />
<label for="all">Animate all</label>

<div role="main">
    <a data-property="background-color" data-from="slategray" data-to="black"></a>
    <a data-property="background-position" data-from="0 0" data-to="100% 100%" style="background-image: linear-gradient(-45deg, transparent 25%, black 25%, black 50%, transparent 50%, transparent 75%, black 75%, black); background-size:50px 50px"></a>
    <a data-property="background-position" data-from="3px 0, 3px 0, 15px -150px, 15px -150px" data-to="3px -70px, 3px -70px, 15px -80px, 15px -80px" style="background-color: #E04332; background-repeat: repeat-x; background-size: 24px 300px; background-image: linear-gradient(-45deg, slategray 25%, transparent 25%), linear-gradient(45deg, transparent 75%, slategray 75%), linear-gradient(45deg, slategray 25%, transparent 25%), linear-gradient(-45deg, transparent 75%, slategray 75%);" data-author="kizmarh"></a>
    <a data-property="background-size" data-from="5px 5px" data-to="150px 150px" style="background-image: repeating-radial-gradient(transparent, transparent 9px, black 11px, black 20px); background-position:center"></a>
    <a data-property="border-radius" data-from="0" data-to="50%"></a>
    <a data-property="border-radius" data-from="0 100%" data-to="100% 0"></a>
    <a data-property="border-width" data-from="0" data-to="75px" style="border-style:solid; border-color: black;"></a>
    <a data-property="border-width" data-from="0" data-to="35px" style="border-style:dashed; border-color: black;"></a>
    <a data-property="border-width" data-from="0" data-to="75px" style="border-style:double; border-color: black;"></a>
    <a...

CSS

* {
    margin: 0;
}

body {
    padding: 1em 5em;
    font: 1em/1.5em Futura, 'Century Gothic', sans-serif;
    text-align: center;
    overflow-x: hidden;
}

hgroup > h1 {
    font-size: 500%;
    line-height: 1;
    text-transform: lowercase;
}

hgroup > h2 {
    font-size: 120%;
}

a {
    text-decoration: none;
    color: slategray;
}

div[role="main"] {
    padding: 2em .5em;
    counter-reset: demo;
}

div[role="main"]:after {
    content: '';
    display: block;
    clear: both;
}

    a[data-property] {
        position: relative;
        float: left;
        width: 150px;
        height: 150px;
        box-sizing: border-box;
        margin: 0 15px 30px;
        background: slategray;
        color: white;
        font-size: 60px;
        line-height: 150px;
        text-align: center;
        counter-increment: demo;
    }
    
    body.in-page a[data-property]:not(:target) {
        opacity: .2 !important;
    }
    
    #on-hover:checked ~ div[role="main"] > a[data-property]:not(:hover):not(:target),
    body.in-page a[data-property]:not(:target) {
        animation: none !important;
    }
    
        a[data-property]:after {
            content: attr(data-property);
            position: absolute;
            right: 0;
            left: 0;
            bottom: -1.2em;
            z-index: 2;
            color: slategray;
            font-size: 14px;
            line-height: 1;
            text-indent: 0;
            text-shadow: none;
            letter-spacing: 0;
        }
    
        a[data-property]:before {
            content: counter(demo);
        }
    
input[type="radio"] {
    position: absolute;
    clip: rect(0,0,0,0);
}

input[type="radio"] + label {
    display: inline-block;
    padding: .3em .7em;
    border: 1px solid rgba(0,0,0,.3);
    margin-top: 1em;
    background: #809070;
    color: white;
    text-shadow: .05em .05em .2em rgba(0,0,0,.8);
    cursor: pointer;
    border-radius: .3em;
    box-shadow: 0 1px...

JavaScript

function $(expr, con) { return (con || document).querySelector(expr); }
function $$(expr, con) { return [].slice.call((con || document).querySelectorAll(expr)); }

var css = [];

$$('a[data-property]').forEach(function(el, i){
    var property = el.getAttribute('data-property'),
        from = el.getAttribute('data-from'),
        to = el.getAttribute('data-to');
    
    var id = property, i = 1;
    
    while(document.getElementById(id)) {
        id = property + '/' + ++i;
    }
    
    el.id = id;
    el.href = '#' + id;
    
    el.title = property + ' from ' + from + ' to ' + to;
    
    var selector = '#' + id.replace(/([^\w-])/g, '\\$1'),
        ident = id.replace(/([^\w-])/g, '-');
    
    css.push('@keyframes ' + ident + '{',
            'from{' + property + ':' + from + '}',
            'to{' + property + ':' + to + '}}',
            selector + ' { animation: ' + ident + ' 1s infinite alternate;' + property + ':' + from + '}');
});

var style = document.createElement('style');
style.textContent = css.join('\r\n');
StyleFix.styleElement(style);
document.head.appendChild(style);

setTimeout(onhashchange = function() {
    var target = location.hash? $(location.hash.replace(/([^\w-#])/g, '\\$1')) : null;
    
    if(!target) {
        document.body.className = 'home';
        return;
    }
    
    document.body.className = 'in-page';
    
    var info = $('#info'),
        previous = target.previousElementSibling,
        next = target.nextElementSibling,
        author = target.getAttribute('data-author') || 'leaverou';
    
    $('h1', info).innerHTML = target.getAttribute('data-property');
    $('dd:first-of-type', info).innerHTML = target.getAttribute('data-from');
    $('dd:nth-of-type(2)', info).innerHTML = target.getAttribute('data-to');
    $('dd:nth-of-type(3)', info).innerHTML = '<a href="http://twitter.com/' + author + '" target="_blank"><img src="http://twitter.com//api/users/profile_image?screen_name=' + author + '&size=mini"/>@' +...