Skip to main content

afrigov is an open-source project. It is not a government website and is not affiliated with any government.

Previewing neutral core Change

afrigov Accessible government design system

Images

Images are where most of a government page's weight comes from, and the reader pays for every megabyte. afrigov's CSS is 10 KB. One photograph sent at camera size can be three hundred times that.

How heavy each kind of image may be

Sizes are after compression, for the largest version a desktop downloads. Phones download less.

Image weight limits
Image Width At most
Hero or cover photograph 1600px 150 KB
Image beside text, or in a news article 800px 80 KB
Card picture, video poster 640px 40 KB
Portrait 480px 40 KB
List thumbnail 240px 15 KB
Logo or mark 112px tall 20 KB
Event flyer 800px 120 KB

A whole page, images included, should load in under 1 MB on a phone. Under 500 KB is better.

Which format

  • WebP for photographs and anything with many colours. It is a third to a half the size of JPEG at the same quality, and every current browser reads it.
  • SVG for logos, marks, icons and diagrams drawn with lines and shapes. It stays sharp at any size and is usually a few kilobytes.
  • PNG only for screenshots and flat graphics with text that WebP would blur.
  • Never a photograph saved as PNG. It is often ten times the size of the same photograph as WebP.

Send each screen the size it needs

Make the image at three widths and let the browser choose. A phone downloads the small one; a large screen the large one. The sizes attribute tells the browser how wide the image is shown, so it can choose before the page has laid itself out.

<img
  src="clinic-960.webp"
  srcset="clinic-480.webp 480w, clinic-960.webp 960w, clinic-1600.webp 1600w"
  sizes="(min-width: 64em) 50vw, 100vw"
  width="1600"
  height="900"
  alt="A nurse checks a child's temperature at the Tamale clinic."
  loading="lazy"
  decoding="async"
/>
  • width and height are the file's own size. The browser keeps the space from the start, so the page does not jump when the image arrives.
  • loading="lazy" on every image below the first screen, so it downloads only when someone scrolls to it. Not on the hero, which should arrive first.
  • Slides and hidden images download even when nobody sees them. afrigov has no carousel for that reason. If a page must show several, give the hidden ones loading="lazy".

Make them with afrigov-images

afrigov-images does all of this page in one command. Point it at a folder of photos and say what kind they are:

npx afrigov-images ./event-photos --out ./site/images --kind card

For each photo it:

  • makes the widths for that kind, from the table above, and never enlarges a small photo
  • saves them as WebP, and lowers the quality, within limits, until the largest copy is under the weight limit
  • turns the photo the right way up and removes the camera data, including where it was taken
  • prints the img element to paste, with srcset, sizes, width, height and lazy loading
cardiovascular-care.png  3.1 MB, 2384 × 1054
  3 copies as WebP: 15 KB, 37 KB, 66 KB  within the limit

The kinds are hero, wide, card, portrait, thumb, flyer and logo. You write the alt text yourself: only a person knows what the picture is there to say. It needs Node 20 or newer.

Other ways to make them

  • WordPress already makes resized copies of every upload and writes srcset for them, if the theme uses its image functions. A plugin can convert uploads to WebP. Check that the theme does not put the full-size original in the hero or the slider.
  • A site built from files: run afrigov-images before publishing, or use Squoosh in the browser for a single image.
  • Remove the camera data. A photograph straight from a phone carries where and when it was taken. afrigov-images removes it by default, as do the tools above when they convert to WebP.

Check a page

afrigov-audit reports a page's weight on a phone and names every image heavier than it needs to be, with the size the screen needs. afrigov-images is the fix.

npx afrigov-audit https://example.gov.gh/ --phone

Accessibility

  • An image that says something needs alt text that says it. A decorative image has alt="". See image and figure.
  • No words inside pictures. Text in an image cannot be resized, translated or read aloud.