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

pixx

v0.0.32

Published

Create web friendly images and code snippets

Downloads

1,264

Readme

pixx

What and Why

  • Responsive images can be complex and error prone. This module tries to simplify the image creation and html code to match.
  • Using the sharp image library, quickly create responsive images, and the HTML code to match.
  • This package only runs in a NodeJS environment.
  • Pixx does not increase image size. Start with the largest input image.
  • Pixx is designed to use in project development.
  • Sharp error on Windows: Could not load the "sharp" module using the win32-x64 runtime.
    • Solution: npm install --include=optional sharp

Simple Start

// download
npm i -D pixx;


// commonjs
const { pixx } = require('pixx');
pixx('compass.jpg').then((HTML) => {});
// esm -package.json "type": "module",
import { pixx } from 'pixx';
const HTML = await pixx('compass.jpg'); // size is 2560w x 1920h.

// returns
<picture>
  <source
    type="image/avif"
    sizes="100vw"
    srcset="
      pixx_images/compass/compass-400w300h.avif    400w,
      pixx_images/compass/compass-800w600h.avif    800w,
      pixx_images/compass/compass-1200w900h.avif  1200w,
      pixx_images/compass/compass-1600w1200h.avif 1600w,
      pixx_images/compass/compass-2000w1500h.avif 2000w,
      pixx_images/compass/compass-2400w1800h.avif 2400w,
      pixx_images/compass/compass-2560w1920h.avif 2560w
    "
  />
  <source
    type="image/webp"
    sizes="100vw"
    srcset="
      pixx_images/compass/compass-400w300h.webp    400w,
      pixx_images/compass/compass-800w600h.webp    800w,
      pixx_images/compass/compass-1200w900h.webp  1200w,
      pixx_images/compass/compass-1600w1200h.webp 1600w,
      pixx_images/compass/compass-2000w1500h.webp 2000w,
      pixx_images/compass/compass-2400w1800h.webp 2400w,
      pixx_images/compass/compass-2560w1920h.webp 2560w
    "
  />
  <source
    type="image/jpg"
    sizes="100vw"
    srcset="
      pixx_images/compass/compass-400w300h.jpg    400w,
      pixx_images/compass/compass-800w600h.jpg    800w,
      pixx_images/compass/compass-1200w900h.jpg  1200w,
      pixx_images/compass/compass-1600w1200h.jpg 1600w,
      pixx_images/compass/compass-2000w1500h.jpg 2000w,
      pixx_images/compass/compass-2400w1800h.jpg 2400w,
      pixx_images/compass/compass-2560w1920h.jpg 2560w
    "
  />
  <img
    src="pixx_images/compass/compass-2560w1920h.jpg"
    alt="image"
    width="2560"
    height="1920"
    loading="eager"
    decoding="async"
  />
</picture>;

Understanding Responsive Images: Resolutions Switching, Multiple Types, and Art Direction

  • All 'responsive image methods' must have <meta name="viewport" content="width=device-width"> added to the head section of html, for mobile browsers to use the actual device viewport in decision making.
  • Responsive Image Advantages
    • When mobile or desktop browsers download and parse the HTML, the sizes, srcset and media attribute give clues to the browser about the best images to download.
    • Using these attributes, the browser decides the best image to download based on its viewport size and pixel density.
    • srcset: inform the browser of the available image widths.
    • sizes: inform the browser about how much of the viewport the image will fill.
    • media: completely different images can be offered depending on matching media condition.

Responsive Images

  • Three main ways to use responsive images.
    1. Single image in multiple sizes. (e.g. img-100.jpg, img-200.jpg, img-300.jpg).
    2. Single image in multiple sizes and types. (e.g. img.avif, img.webp, img.jpg).
    3. Multiple different images the browser will choose depending on viewport width.
      1. (e.g. img-full.jpg, img-crop.jpg).

Resolution Switching

  • Uses the img element with the srcset and sizes attributes.
  • Single image type. Browsers can choose what image size to download based on the device viewport.
  • Fallback is the img src attribute.
  • Pros
    • The least complex. Default sizes attribute is 100vw.
    • Can offer multiple image size options.
  • Cons
    • Only single image type can be used at a time.
// Single image type, multiple sizes.
// e.g. Device viewport has a width of 700px.
// The 'media condition' tells browser image will take 350px (50vw) of viewport.
// If viewport pixel density is 2x. Browser will choose >= 700px image. (compass-800w600h.webp)
await pixx('./compass.jpg', {
  picTypes: ['webp'],
  sizes: ['(max-width: 450px) 75vw', '(max-width: 800px) 50vw', '25vw'],
});

// returns
<img
  srcset="
    pixx_images/compass/compass-400w300h.webp    400w,
    pixx_images/compass/compass-800w600h.webp    800w,
    pixx_images/compass/compass-1200w900h.webp  1200w,
    pixx_images/compass/compass-1600w1200h.webp 1600w,
    pixx_images/compass/compass-2000w1500h.webp 2000w,
    pixx_images/compass/compass-2400w1800h.webp 2400w,
    pixx_images/compass/compass-2560w1920h.webp 2560w
  "
  sizes="(max-width: 450px) 75vw, (max-width: 800px) 50vw, 25vw"
  src="pixx_images/compass/compass-2560w1920h.jpg"
  alt="image"
  width="2560"
  height="1920"
  loading="eager"
  decoding="async"
/>;

Multiple Types

  • Uses the picture and source element with the srcset and sizes attributes.
  • Same advantages as Resolution Switching, with the added benefit of multiple formats.
  • Fallback is img element.
  • Pros
    • Use new and highly optimized image formats, with fallback formats for browsers that don't support them.
  • Cons
    • Code can be complex.
    • Order matters. Browser takes the first truthy value.
let pending = true;
await pixx('./src/compass.jpg', {
  title: 'Antique compass',
  alt: 'Image of an old compass',
  withBlur: true,
  classes: ['my-special-class', 'border-blue-200', { 'border-red-200': pending }],
});

// console.log blur image path and blurDataURL.
compass.jpg: 'pixx_images/compass/compass-placeholder-10w8h.jpg'
compass.jpg blurDataURL: 'data:image/jpg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBw...'

// returns
<picture>
  <source
    type="image/avif"
    sizes="100vw"
    srcset="
      pixx_images/compass/compass-400w300h.avif    400w,
      pixx_images/compass/compass-800w600h.avif    800w,
      pixx_images/compass/compass-1200w900h.avif  1200w,
      pixx_images/compass/compass-1600w1200h.avif 1600w,
      pixx_images/compass/compass-2000w1500h.avif 2000w,
      pixx_images/compass/compass-2400w1800h.avif 2400w,
      pixx_images/compass/compass-2560w1920h.avif 2560w
    "
  />
  <source
    type="image/webp"
    sizes="100vw"
    srcset="
      pixx_images/compass/compass-400w300h.webp    400w,
      pixx_images/compass/compass-800w600h.webp    800w,
      pixx_images/compass/compass-1200w900h.webp  1200w,
      pixx_images/compass/compass-1600w1200h.webp 1600w,
      pixx_images/compass/compass-2000w1500h.webp 2000w,
      pixx_images/compass/compass-2400w1800h.webp 2400w,
      pixx_images/compass/compass-2560w1920h.webp 2560w
    "
  />
  <source
    type="image/jpg"
    sizes="100vw"
    srcset="
      pixx_images/compass/compass-400w300h.jpg    400w,
      pixx_images/compass/compass-800w600h.jpg    800w,
      pixx_images/compass/compass-1200w900h.jpg  1200w,
      pixx_images/compass/compass-1600w1200h.jpg 1600w,
      pixx_images/compass/compass-2000w1500h.jpg 2000w,
      pixx_images/compass/compass-2400w1800h.jpg 2400w,
      pixx_images/compass/compass-2560w1920h.jpg 2560w
    "
  />
  <img
    className="my-special-class border-red-200"
    src="pixx_images/compass/compass-2560w1920h.jpg"
    alt="Image of an old compass"
    width="2560"
    height="1920"
    title="Antique compass"
    loading="eager"
    decoding="async"
  />
</picture>

Art Direction

  • Uses the picture and source element with the srcset, sizes and media attributes.
  • Switch different image formats based on first truthy media condition.
  • Fallback is img element.
  • Pros
    • Switch image based viewport size.
  • Cons
    • Code can be complex.
    • Order matters. Browser takes the first truthy value.
// Art Direction -multiple images: Compass.jpg 2560x1920, Happy face.jpg 720x360
await pixx(['./src/compass.jpg', './src/happy face.jpg'], {
  clean: true,
  omit: { remove: 'pixx_images', add: './my-special-folder' },
  media: ['(min-width: 401px) compass.jpg', '(max-width: 400px) happy face.jpg'],
  sizes: ['(min-width: 401px) 50vw', '(max-width: 400px) 100vw', '100vw'],
  styles: ['color: blue', 'border-color: red'], // html
});

// returns
<picture>
  <source
    type="image/avif"
    media="(min-width: 401px)"
    sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
    srcset="
          ./my-special-folder/compass/compass-400w300h.avif    400w,
          ./my-special-folder/compass/compass-800w600h.avif    800w,
          ./my-special-folder/compass/compass-1200w900h.avif  1200w,
          ./my-special-folder/compass/compass-1600w1200h.avif 1600w,
          ./my-special-folder/compass/compass-2000w1500h.avif 2000w,
          ./my-special-folder/compass/compass-2400w1800h.avif 2400w,
          ./my-special-folder/compass/compass-2560w1920h.avif 2560w
        "
  />
  <source
    type="image/webp"
    media="(min-width: 401px)"
    sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
    srcset="
          ./my-special-folder/compass/compass-400w300h.webp    400w,
          ./my-special-folder/compass/compass-800w600h.webp    800w,
          ./my-special-folder/compass/compass-1200w900h.webp  1200w,
          ./my-special-folder/compass/compass-1600w1200h.webp 1600w,
          ./my-special-folder/compass/compass-2000w1500h.webp 2000w,
          ./my-special-folder/compass/compass-2400w1800h.webp 2400w,
          ./my-special-folder/compass/compass-2560w1920h.webp 2560w
        "
  />
  <source
    type="image/jpg"
    media="(min-width: 401px)"
    sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
    srcset="
          ./my-special-folder/compass/compass-400w300h.jpg    400w,
          ./my-special-folder/compass/compass-800w600h.jpg    800w,
          ./my-special-folder/compass/compass-1200w900h.jpg  1200w,
          ./my-special-folder/compass/compass-1600w1200h.jpg 1600w,
          ./my-special-folder/compass/compass-2000w1500h.jpg 2000w,
          ./my-special-folder/compass/compass-2400w1800h.jpg 2400w,
          ./my-special-folder/compass/compass-2560w1920h.jpg 2560w
        "
  />
  <source
    type="image/avif"
    media="(max-width: 400px)"
    sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
    srcset="
          ./my-special-folder/happy_face/happy_face-600w300h.avif 600w,
          ./my-special-folder/happy_face/happy_face-720w360h.avif 720w
        "
  />
  <source
    type="image/webp"
    media="(max-width: 400px)"
    sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
    srcset="
          ./my-special-folder/happy_face/happy_face-600w300h.webp 600w,
          ./my-special-folder/happy_face/happy_face-720w360h.webp 720w
        "
  />
  <source
    type="image/jpg"
    media="(max-width: 400px)"
    sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
    srcset="
          ./my-special-folder/happy_face/happy_face-600w300h.jpg 600w,
          ./my-special-folder/happy_face/happy_face-720w360h.jpg 720w
        "
  />
  <img
    style="color: blue; border-color: red"
    src="./my-special-folder/happy_face/happy_face-720w360h.jpg"
    alt="image"
    width="720"
    height="360"
    loading="eager"
    decoding="auto"
  />
</picture>;

React

  • By default, html element is returned as a string. You can return a 'React' component by setting the option returnReact: true.

Pixx Options

  • alt: string. default image. The img alt attribute.
  • blurSize: number. default 10. Number of pixels wide the placeholder image is resized to.
    • Bigger blurSize, bigger base64DataURL.
  • classes: string[]. Array of class names. Tailwindcss can be used, and optional object syntax.
    • e.g. ['my-special-class', 'border-blue-200', { 'border-red-200': pending }].
  • clean: boolean. Default false. Delete image folder and create new.
  • decoding: enum('auto', 'async', 'sync'). default auto. Image download priority.
  • fallbackWidth: number . Default image width. Custom fallback image width in pixels.
    • Older browsers fallback to this image. Image will always be type jpg.
    • fallbackWidth must be <= image width. Image size is not increased.
    • (e.g. 1500. The fallback img src will be an image 1500px wide with height same aspect ratio as original).
  • heights: number[]. Array of numbers representing height in pixels.
    • heights numbers must be <= image size. Image size is not increased.
    • widths have priority over heights. Both have priority over defaultSizes.
    • (e.g. [300, 500, 650, 900, 1200]).
  • incrementSize: number. Default 300. Customize increment size creation.
    • The increment pixel size defaultSizes uses to create images.
    • Only valid if widths or heights are empty.
    • (e.g. Find the smaller image side (width or height), then create img every 300px until image size is reached).
  • linuxPaths: boolean. Default true. Development on Windows, convert image paths to linux style.
  • loading: enum('eager', 'lazy'). Default eager. Image loading priority.
  • log: boolean. Default false. Output build details to console.log.
    • Includes state and hidden image details: EXIF, XMP, ICC, and GPS metadata.
  • media: string[]. Array of media conditions and image names.
    • Tells browser what image to display based on viewport size.
    • This is solely used for Art Direction.
    • (e.g. ['(max-width: 400px) img1-crop.jpg', '(min-width: 401px) img1.jpg']).
  • outDir: string. Default pic_images. Custom directory name to create images.
  • omit: { remove: string, add: string }. Object with remove and add properties.
    • Customize any part of the image path on the img or picture elements.
    • Does not change the outDir. Images will still be created in the outDir.
    • (e.g. { remove: 'pixx_images', add: './my-special-path' }).
  • picTypes: enums('avif', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'webp'). Array of strings.
    • Default ['avif', 'webp', 'jpg'].
    • (e.g. ['webp']. Create only webp image types).
  • preload: boolean. Defaultfalse. Create the image link tag for HTML head element.
    • Preloading images can optimize load times for critical images.
    • Print the link tag to console.log.
  • preloadFetchPriority: enum('auto', 'async', 'sync'). Default auto.
  • returnReact: boolean. Default false. Return results as React component or string.
  • sizes: default string[] ['100vw']. Array of media conditions and the viewport fill width.
    • MDN sizes. Informs the browser how much of viewport the image will fill based on the media condition.
    • The descriptor can be any CSS media condition.
    • The value can be any CSS length except percentage. (e.g. 100rem; 75vw; 500px).
    • The last item in the array is the 'default' size if media conditions do not match.
    • (e.g. ['((min-width: 50em) and (max-width: 60em)) 500px', '75vw']).
  • styles: string[] | { [key: string]: string }. Array(HTML) or Object(React) of inline styles.
    • React: { color: "blue", backgroundColor: "red" }
    • HTML: ['color: blue', 'background-color: red']
  • title: string. Text to display as tooltip when hover over image.
  • widths: number[]. Array of widths to create images.
    • widths numbers must be <= image size. Image size is not increased.
    • widths have priority over heights. Both have priority over defaultSizes.
    • (e.g. [300, 500, 650, 900, 1200]).
  • withAnimation: boolean. Default false. Sharp image library will retain the image animation.
  • withBlur: boolean. Default false. Create placeholder image and base64DataURL.
    • Print to console.log.
  • withClassName: boolean. Default true. Image class attribute.
    • Options: false = class | true = className.
    • Also changes: false = srcset | true = srcSet.
  • withMetadata: boolean. Default false. Copy original image metadata to new images.

pixxFlow

  • Pixx was designed to run in an JSX/TSX environment. To use with HTML files, pixxFlow will read your 'static' files and replace the pixx function with the returned html code. The code is statically run.
  • In HTML, place a single pixx function in a script tag.
  • run file with: node file.js
  • Caution: pixxFlow uses eval() to convert the pixx options 'string' to an 'object'. Only use this function in development.

PixxFlow Options

  • include: string[]. Files to include. PixxFlow uses glob to search for files.
  • ignore?: string[]. Files to ignore.
  • log?: boolean. default false. Console.log important results for debugging.
  • debug?: boolean. default false. Console.log everything for debugging.
  • overwrite?: boolean. default false. Create a new starting with pixx, or overwrite the file.
// NEXTJS Example
// -npm i -D pixx
// 1. Create run file: file.js
import { pixx, pixxFlow } from 'pixx';
pixxFlow(pixx, {
  log: true,
  include: ['src/**/*.tsx', 'src/**/*.jsx'],
  ignore: ['node_modules', '**/pixx*'],
  overwrite: true,
});

// page.tsx
import { pixx } from 'pixx';
export default function Home() {
  return (
    <div className="grid grid-rows-[20px_1fr_20px]">
      <main className="flex flex-col sm:items-start">
        {/* Create pixx function. Run dev server. Stop server to build. */}
        {pixx('./images/happy face.jpg', {
          returnReact: true,
          outDir: 'public',
          omit: { remove: 'public/' },
        })}
      </main>
    </div>
  );
}

// 3. run with:
node file.js

// Returns -------------------------------------
// import { pixx } from 'pixx';
export default function Home() {
  return (
    <div className="grid grid-rows-[20px_1fr_20px]">
      <main className="flex flex-col sm:items-start">
        {/* Create pixx function. Run dev server. Stop server to build. */}
        {/* pixx('./images/happy face.jpg', {
          returnReact: true,
          outDir: 'public',
          omit: { remove: 'public/' },
        }) */}
        <picture>
          <source
            type="image/avif"
            sizes="100vw"
            srcSet="happy_face/happy_face-600w300h.avif 600w, happy_face/happy_face-720w360h.avif 720w"
          />
          <source
            type="image/webp"
            sizes="100vw"
            srcSet="happy_face/happy_face-600w300h.webp 600w, happy_face/happy_face-720w360h.webp 720w"
          />
          <source
            type="image/jpg"
            sizes="100vw"
            srcSet="happy_face/happy_face-600w300h.jpg 600w, happy_face/happy_face-720w360h.jpg 720w"
          />
          <img
            src="happy_face/happy_face-720w360h.jpg"
            alt="image"
            width="720"
            height="360"
            loading="eager"
            decoding="auto"
          />
        </picture>
      </main>
    </div>
  );
}
<!-- HTML Example  -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <p>Example 1</p>
    <script>
      pixx('./images/img1.webp');
    </script>
    <p>Example 2</p>
    <script>
      pixx(['./images/compass.jpg', './images/happy face.jpg'], {
        omit: { remove: 'pixx_images', add: './my-special-folder' },
        media: ['(min-width: 401px) compass.jpg', '(max-width: 400px) happy face.jpg'],
        sizes: ['(min-width: 401px) 50vw', '(max-width: 400px) 100vw', '100vw'],
        styles: ['color:    blue', 'border-color: red'],
      });
    </script>
  </body>
</html>

<!-- Returns ----------------------------------------------->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <p>Example 1</p>
    <!-- <script>
      pixx('./images/img1.webp');
    </script> -->
    <picture>
      <source
        type="image/avif"
        sizes="100vw"
        srcset="
          pixx_images/img1/img1-300w346h.avif 300w,
          pixx_images/img1/img1-600w691h.avif 600w,
          pixx_images/img1/img1-750w864h.avif 750w
        "
      />
      <source
        type="image/webp"
        sizes="100vw"
        srcset="
          pixx_images/img1/img1-300w346h.webp 300w,
          pixx_images/img1/img1-600w691h.webp 600w,
          pixx_images/img1/img1-750w864h.webp 750w
        "
      />
      <source
        type="image/jpg"
        sizes="100vw"
        srcset="
          pixx_images/img1/img1-300w346h.jpg 300w,
          pixx_images/img1/img1-600w691h.jpg 600w,
          pixx_images/img1/img1-750w864h.jpg 750w
        "
      />
      <img
        src="pixx_images/img1/img1-750w864h.jpg"
        alt="image"
        width="750"
        height="864"
        loading="eager"
        decoding="auto"
      />
    </picture>

    <p>Example 2</p>
    <!-- <script>
      pixx(['./images/compass.jpg', './images/happy face.jpg'], {
        omit: { remove: 'pixx_images', add: './my-special-folder' },
        media: ['(min-width: 401px) compass.jpg', '(max-width: 400px) happy face.jpg'],
        sizes: ['(min-width: 401px) 50vw', '(max-width: 400px) 100vw', '100vw'],
        styles: ['color:    blue', 'border-color: red'],
      });
    </script> -->
    <picture>
      <source
        type="image/avif"
        media="(min-width: 401px)"
        sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
        srcset="
          ./my-special-folder/compass/compass-400w300h.avif    400w,
          ./my-special-folder/compass/compass-800w600h.avif    800w,
          ./my-special-folder/compass/compass-1200w900h.avif  1200w,
          ./my-special-folder/compass/compass-1600w1200h.avif 1600w,
          ./my-special-folder/compass/compass-2000w1500h.avif 2000w,
          ./my-special-folder/compass/compass-2400w1800h.avif 2400w,
          ./my-special-folder/compass/compass-2560w1920h.avif 2560w
        "
      />
      <source
        type="image/webp"
        media="(min-width: 401px)"
        sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
        srcset="
          ./my-special-folder/compass/compass-400w300h.webp    400w,
          ./my-special-folder/compass/compass-800w600h.webp    800w,
          ./my-special-folder/compass/compass-1200w900h.webp  1200w,
          ./my-special-folder/compass/compass-1600w1200h.webp 1600w,
          ./my-special-folder/compass/compass-2000w1500h.webp 2000w,
          ./my-special-folder/compass/compass-2400w1800h.webp 2400w,
          ./my-special-folder/compass/compass-2560w1920h.webp 2560w
        "
      />
      <source
        type="image/jpg"
        media="(min-width: 401px)"
        sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
        srcset="
          ./my-special-folder/compass/compass-400w300h.jpg    400w,
          ./my-special-folder/compass/compass-800w600h.jpg    800w,
          ./my-special-folder/compass/compass-1200w900h.jpg  1200w,
          ./my-special-folder/compass/compass-1600w1200h.jpg 1600w,
          ./my-special-folder/compass/compass-2000w1500h.jpg 2000w,
          ./my-special-folder/compass/compass-2400w1800h.jpg 2400w,
          ./my-special-folder/compass/compass-2560w1920h.jpg 2560w
        "
      />
      <source
        type="image/avif"
        media="(max-width: 400px)"
        sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
        srcset="
          ./my-special-folder/happy_face/happy_face-600w300h.avif 600w,
          ./my-special-folder/happy_face/happy_face-720w360h.avif 720w
        "
      />
      <source
        type="image/webp"
        media="(max-width: 400px)"
        sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
        srcset="
          ./my-special-folder/happy_face/happy_face-600w300h.webp 600w,
          ./my-special-folder/happy_face/happy_face-720w360h.webp 720w
        "
      />
      <source
        type="image/jpg"
        media="(max-width: 400px)"
        sizes="(min-width: 401px) 50vw, (max-width: 400px) 100vw, 100vw"
        srcset="
          ./my-special-folder/happy_face/happy_face-600w300h.jpg 600w,
          ./my-special-folder/happy_face/happy_face-720w360h.jpg 720w
        "
      />
      <img
        style="color: blue; border-color: red"
        src="./my-special-folder/happy_face/happy_face-720w360h.jpg"
        alt="image"
        width="720"
        height="360"
        loading="eager"
        decoding="auto"
      />
    </picture>
  </body>
</html>

License

Published under the Apache-2.0 license. © Bryon Smith 2024.