JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://rawgithub.com/Rich-Harris/Ractive/master/build/Ractive.min.js"></script>
<div id='container'></div>

<script id='tpl' type='text/ractive'>
    <h1>HTTP Status Dogs</h1>
    <p><a href='http://httpstatusdogs.com/'>http://httpstatusdogs.com/</a></p>
    
    {{# statusDogs }}
        <div class='status-dog'>
            <a href='http://httpstatusdogs.com/{{code}}-{{slug}}'>
                <img data-src='http://httpstatusdogs.com/wp-content/uploads/{{thumb}}' intro='lazyload'>
                <span>{{status}}</span>
            </a>
        </div>
    {{/ statusDogs }}
</script>

CSS

body {
    font-family: 'Helvetica Neue', 'Arial';
    font-size: 16px;
    color: #353535;
}

.status-dog {
    display: inline;
    float: left;
    margin: 0 1em 1em 0;
    text-align: center;
    background-color: #f4f4f4;
}

.status-dog img {
    width: 300px;
    height: 230px;
    opacity: 0;
    -webkit-transition: opacity 1s;
    -moz-transition: opacity 1s;
    transition: opacity 1s;
}

.status-dog img.loaded {
    opacity: 1;
}

.status-dog span {
    display: block;
    padding: 0.5em 0;
}

.status-dog a {
    text-decoration: none;
}

.status-dog a:hover {
    text-decoration: underline;
}

JavaScript

var ractive;

// Define a `lazyload` transition and make it globally available
(function () {
    
    var scrollHandler, lazyloaders, Lazyloader;
    
    Lazyloader = function ( node, src ) {
        this.node = node;
        this.src = src;
    };
    
    Lazyloader.prototype = {
        visible: function () {
            var boundingClientRect = this.node.getBoundingClientRect();
            
            return (
                ( boundingClientRect.top    < window.innerHeight ) &&
                ( boundingClientRect.bottom > 0 ) &&
                ( boundingClientRect.left   < window.innerWidth  ) &&
                ( boundingClientRect.right  > 0 )
            );
        },
        
        load: function () {
            var node = this.node, src = this.src, img = new Image();					
            
            img.addEventListener( 'load', loadHandler = function () {
                node.src = src;
                node.classList.add( 'loaded' );
                img.removeEventListener( 'load', loadHandler );
            });
            
            img.src = src;
        }
    };
    
    scrollHandler = function ( event ) {
        var i = lazyloaders.length;
        
        while ( i-- ) {
            lazyloader = lazyloaders[i];
            
            if ( lazyloader.visible() ) {
                lazyloader.load();
                lazyloaders.splice( i, 1 );
            }
        }
        
        if ( !lazyloaders.length ) {
            window.removeEventListener( 'scroll', scrollHandler );
        }
    };
    
    lazyloaders = [];
    
    
    Ractive.transitions.lazyload = function ( node, complete, params, isIntro ) {
        if ( isIntro ) {
            setTimeout( function () { // wait until next repaint, otherwise layout is wrong
                var lazyloader;
                
                if ( !lazyloaders.length ) {
                    window.addEventListener( 'scroll', scrollHandler );
                }
                
              ...