Slick Lazy Load Photo Grid Using Webpack 3

How to layout and lazy load images in a flexible grid similar to how facebook displays them in a post. Selected images open a lightbox for previewing within a carousel. Image alt text is converted into a caption below the image.

Features

  • Lazy image loading
  • ES6 transpiler
  • JavaScript source maps
  • Sass CSS preprocessor
  • PostCSS Autoprefixer
  • CSSnano
  • Webpack 3
uiCookbook Photogrid
Demo
Source Code

Getting Started

If you don’t already have Node.js installed, then that needs to be the first order of business. Head on over to Node.js and get that taken care of.

Navigate to the project root in your CLI, such as Terminal, Cygwin or PowerShell.

Enter npm init to interactively create a package.json file. Accepting the default options is okay for now. The metadata in this file can be updated later as needed.

npm init

A package.json file should now exist in the root of the project. This file will be used later with the npm command when installing modules and running scripts.

Create an index.html file in the root of the project. Add an unordered list of images to the body with the .photogrid style class. For lazy image loading, instead of using a src attribute, put the image path in a data attribute named data-src. Also include the dist/style.css link in the document head and dist/app.js link before the closing body tag.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" media="all" href="dist/style.css">
</head>
<body>
    <ul class="photogrid">
        <li>
            <img data-src="https://images.unsplash.com/reserve/unsplash_528b27288f41f_1.JPG?auto=format&fit=crop&w=2700&q=80&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="Sea breeze and splashing waves. A photo by @dankapeter on Unsplash"/>
        </li>
        <li>
            <img data-src="https://images.unsplash.com/photo-1494633114655-819eb91fde40?auto=format&fit=crop&w=2550&q=80&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="Above it All. A photo by @anthonyintraversato on Unsplash" />
        </li>
        <li>
            <img data-src="https://images.unsplash.com/photo-1511125357779-27038c647d9d?auto=format&fit=crop&w=2551&q=80&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="Found this beauty while being lost in the streets of CancĂșn, Mexico. A photo by @odiin on Unsplash" />
        </li>
        <li>
            <img data-src="https://images.unsplash.com/photo-1483919283443-8db97e2bcd81?auto=format&fit=crop&w=2550&q=80&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="Touring NYC. A photo by @freddymarschall on Unsplash" />
        </li>
        <li>
            <img data-src="https://images.unsplash.com/photo-1487357298028-b07e960d15a9?auto=format&fit=crop&w=2550&q=80&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="Wind turbines, Greece. A photo by @jeisblack on Unsplash" />
        </li>
    </ul>
    <script async src="dist/app.js"></script>
</body>
</html>
  • Using Emmet, which is built into VS Code, you can create the index.html content by entering an exclamation mark on the first line then select the tab key.

Lazy Image Loading

This is accomplished using David Walsh’s Simple Image Lazy Load and Fade method.

Create a folder named src. In that folder, create both a js folder and a sass folder.

Within the js folder, create an index.js app entry point file and a lazyimage.js module file.

Within the sass folder, create a style.scss file that will be used as the entry point for Sass processing. Add three Sass partials, _base.scss, _photogrid.scss and _lazyimage.scss. The leading underscore in the filename denotes that the file is a Sass partial and therefore will only be processed if imported.

  • photogrid
    • index.html
    • package.json
    • src
      • js
        • index.js
        • lazyimage.jsc
      • sass
        • style.scss
        • _base.scss
        • _lazyimage.scss

In the lazyimage.js module, export this Lazyimage ES6 class.

lazyimage.js
export default class Lazyimage {
  constructor(options) {

    this.init();
  }

  init() {

    [].forEach.call(document.querySelectorAll('img[data-src]'), function(img) {
      img.setAttribute('src', img.getAttribute('data-src'));
      img.onload = function() {
        img.removeAttribute('data-src');
      };
    });
  }
}

Import the lazyimage module in the app entry point.

index.js
import Lazyimage from './lazyimage'

new Lazyimage();

Add this Sass to the base partial for the unordered list and image element default style.

_base.scss
ul {
  padding: 0;
}

img {
  border-style: none;
  height: auto;
  max-width: 100%;
}

Add this Sass to the photogrid partial to apply the photogrid styling with flexbox to the list of images.

_photogrid.scss
ul.photogrid {
  margin: 0.5vw 0.5vw 0.5vw -0.5vw;
  font-size: 0;
  flex-flow: row wrap;
  display: flex;

  li {
    flex: auto;
    width: 200px;
    margin: 0.5vw;
  }
}

Add this Sass to the lazyimage partial to fade the image in when the image has loaded and the data-src attribute has been removed.

_lazyimage.scss
img {
  opacity: 1;
  transition: opacity 0.3s;
}

img[data-src] {
  opacity: 0;
}

Import the three partials into the style Sass file.

style.scss
@import "base";
@import "photogrid";
@import "lazyimage";

The next page covers adding Webpack and the build configurations, installing dependencies, running the first build and verifying the application output.


Published by

Jim Frenette

Web Developer - views here are my own except those taken from people more clever than me.

Loading Disqus Comments ...
Loading Facebook Comments ...