npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gifa11y

v2.0.4

Published

Gifa11y is a customizable vanilla javascript plugin that easily adds accessible play/pause buttons to animated GIFs.

Downloads

24

Readme

Gifa11y

Easily add pause buttons to your GIFs. This script is intended for shorter GIFs that loop indefinitely. It only generates a still of the first frame.

npm version GitHub file size in bytes GitHub jsDelivr stats

  • Automatic
    • Generates a still using <canvas> element
    • No need to upload png/jpeg "still" of GIF
  • Accessible
    • Keyboard accessible
    • Unique accessible names for buttons based on alt text
    • Large target size (50px by 50px)
    • Respects prefers-reduced-motion media query
  • Vanilla JavaScript
  • Customizable
    • Customize colours and icons via props.
    • Leverages web components to avoid style conflicts.
  • Size: 8 KB

▶️ View Gifa11y demo

Alternatively check out Gifa11y demo on CodePen to view HTML before Gifa11y does its magic. Experiment with different props and settings.

Install

CDN (regular script/UMD):

https://cdn.jsdelivr.net/gh/adamchaboryk/[email protected]/dist/js/gifa11y.umd.min.js

NPM

npm i gifa11y

Example install as regular script

Refer to Props to easily customize. CSS styles for buttons are bundled with JavaScript.

<script src="dist/js/gifa11y.umd.min.js"></script>
<script>
var gifa11y = new Gifa11y({
    container: 'main',
    buttonBackground: '#000000',
    buttonBackgroundHover: '#404040',
    buttonIconColor: 'white'
});
</script>

Example install via modules

Refer to Props to easily customize.

<script type="module">
import Gifa11y from "../dist/js/gifa11y.esm.js";
const gifa11y = new Gifa11y({
  container: 'main',
  buttonBackground: '#000000',
  buttonBackgroundHover: '#404040',
  buttonIconColor: 'white'
});
</script>

Example install for Eleventy (11ty)

Here's an example recipe for selectively adding Gifa11y to web pages that contain .gif images. This approach helps minimize HTTP requests and provides the flexibility to easily remove the library if necessary. For advanced usage, you can also install Gifa11y via npm and replace the CDN link to have Gifa11y inline on your page.

eleventyConfig.addTransform("gifa11y", async function (content) {
    if (this.page.outputPath && this.page.outputPath.endsWith(".html")) {
      if (content.includes("<img") && content.includes(".gif")) {
        const gifa11y =
          `<script src="https://cdn.jsdelivr.net/gh/adamchaboryk/[email protected]/dist/js/gifa11y.umd.min.js"></script>
          <script>
          // Customize props.
          const gifa11y = new Gifa11y({
            showGifText: true,
            buttonBackground: 'var(--background-secondary)',
            buttonBackgroundHover: 'var(--background)',
            buttonIconColor: 'var(--text)',
          });
        </script>`;
        content = content.replace("</body>", `${gifa11y}</body>`);
      }
    }
    return content;
  });

Props

Colours, exclusions, and other features

|Property|Default|Description| |---|---|---| |buttonBackground|'indigo'|String: Any hexcode, rgb value, CSS colour keyword.| |buttonBackgroundHover|'rebeccapurple'|String: Any hexcode, rgb value, CSS colour keyword.| |buttonBorder|'2px solid #fff'|String: Specify the style, width, and color of an element's border.| |buttonIconColor|'white'|String: Any hexcode, rgb value, CSS colour keyword.| |buttonFocusColor|'#00e7ffad'|String: Any hexcode, rgb value, CSS colour keyword.| |buttonIconSize|'1.5rem'|String: Adjust height and width of SVG.| |buttonIconFontSize|'1rem'|String: Adjust font-size of an icon font (if passing an icon font via prop). E.g. <i class="fas fa-play"></i>| |buttonPlayIconID|' '|String: Supply your own play icon with an existing element on the page via it's unique id. | |buttonPauseIconID|' '|String: Supply your own pause icon with an existing element on the page via it's unique id| |buttonPlayIconHTML|' '|String: Supply your own play icon using an icon font or SVG. e.g. <i class="fas fa-play"></i>| |buttonPauseIconHTML|' ',|String: Supply your own pause icon using an icon font or SVG. e.g. <i class="fas fa-pause"></i>| |container|'body'|String: Add a pause button to GIFs within a specific area only. E.g. pass main for main content area.| |exclusions|' '|String: Ignore specific GIFs or regions. Use commas to separate. E.g. .jumbotron| |gifa11yOff|'.gifa11y-off'|String: Don't run Gifa11y if page contains class/selector. For example, turn off in development environments. E.g. .authorMode| |inheritClasses|'true'|Boolean: If canvas element should inherit the same classes as the GIF.| |initiallyPaused|'false'|Boolean: If you want all GIFs to be paused at first.| |missingAltWarning|'true'|Boolean: warn content author if they are missing an alt attribute on GIF. Appended to GIF.| |showButtons|true|Boolean: Show or hide Play/Pause buttons.| |showGifText|false|Boolean: Show or hide GIF text within buttons.| |target|''|String: Using CSS selectors, target other images like .webp (that don't end with .gif), for example target: 'img[src$=".webp"]'| |useDevicePixelRatio|false|Boolean: Use window.devicePixelRatio property to help with scaling for high resolution displays.|

Language / i18n

|Property|Default|Description| |---|---|---| |langPause|'Pause animation:'|String: Start of aria-label for each button.| |langPlay|'Play animation:'|String: Start of aria-label for each button.| |langPauseAllButton|'Pause all animations'|String: toggle all button.| |langPlayAllButton|'Play all animations'|String: toggle all button.| |langMissingAlt|'Missing image description.'|String: If alt is missing on GIF, this string populates the aria-label for the corresponding pause button.| |langAltWarning|'⚠ Please add alternative text to GIF.'|String: If GIF is missing alt text.|

Optional features

Ignore specific GIFs

To prevent certain GIFs from getting a pause button. You can either:

  • Add gifa11y-ignore as a CSS class to your image. E.g. <img src="gandalf.gif" class="gifa11y-ignore" ...
  • Rename your GIF and include the text gifa11y-ignored in the file name. E.g. <img src="gandalf-gifa11y-ignored.gif" ...
  • Use exclusions prop.

Pause GIFs initially

For those who prefer reduced motion via system prefs, GIFs will automatically be paused on page load. Although if you'd like specific gifs to be paused initially on page load (without reduced motion enabled), you can either:

  • Add gifa11y-paused as a CSS class to your image. E.g. <img src="gandalf.gif" class="gifa11y-paused" ...
  • Rename your GIF and include the text gifa11y-paused in the file name. E.g. <img src="gandalf-gifa11y-paused.gif" ...
  • Set initiallyPaused prop to true

Toggle all GIFs button

A button to toggle all GIFs. Add <button id="gifa11y-all"></button> within your HTML.

Please note:

  • The "toggle all animations" button has no CSS styling. BYO-CSS (Bring your own CSS).
  • Button becomes clickable only after GIFs have fully loaded. Uses disabled attribute while page is loading.

Development

NPM: npm i gifa11y

A light server for development is included. Any change inside /src folder files will trigger the build process for the files and will reload the page with the new changes. To use this environment:

  1. Clone this repo.
  2. Be sure you have node installed and up to date.
  3. Execute npm install
  4. In a terminal execute: npm run start. Then open http://localhost:8080/docs/index.html in your browser.

Colophon

I was looking for a simple solution to automatically add pause buttons to GIFs, although I could not find anything that was 100% automatic, accessible, and considered loading time of images. I came across a few clever methods which involve swapping a .jpg still - although ain't nobody got time for that. This script uses the <canvas> method to generate a still. I learned a few things developing this:

  • Canvas element: I came across the canvas method in a couple CodePens like this one by hoanghals. This specific pen is a bit more fancy as it relies on another library by Buzzfeed called libgif-js to generate stills at various frames.
  • Timing: Timing is very important... Images must load completely before you can determine height/width. If image is not completely done loading, then clientWidth will return 0. Image dimensions are needed to generate a still using <canvas>. For this reason, pause buttons are generated after each image is done loading. If you have multiple images on a page, you'll notice that this process takes time. GIFs won't be instantly paused if you have prefers-reduced-motion enabled or use the initiallyPaused prop - you may notice a slight delay depending on your internet speed.
  • To help make gifa11y easily customizable, I referenced this great tutorial: How to create a framework-agnostic Javascript plugin by Sodeeq Elusoji.

If you need a more comprehensive solution to deal with various types of animations, I recommend checking out Scott Vinkle's Togglific!