-- online Search!

Social Images

Filed under ROFL Design System

ROFL Design System sections

10 / SOCIAL IMAGES

Open Graph images for every article: canvas, pixel orange, safe area, palette, choosing the visual, treatment, metadata, the generator, and QA.

Agent Instructions / social-images

Create or review a kirupa.com social (Open Graph) image. Read /design/sections/social-images.md and look at its hand-made examples first. Use a 1200x630 canvas (1.905:1) filled with one color from the documented palette, the 13x16 pixel orange painted cell by cell at (45, 30) with 6.1875px cells, and no title text. Choose the visual in the documented priority order: retrofit an old solid-background share image, else the most representative article diagram, a video frame, the article's code in an editor card, then a topic pixel icon. Keep content inside (170, 70)-(1110, 560), centered and filling one dimension. Reject chrome, placeholders, near-empty screenshots, and anything containing the old round orange. Scale pixel art by whole numbers with nearest-neighbor sampling, other art smoothly up to 3x; use white rounded cards with soft shadows for screenshots. Follow the Illustrations arrow and spacing rules. Use tools/build_og_images.py: --plan --only PAGE, edit tools/og_images.json if needed, --render --only PAGE, --apply, --check. Use a fresh filename under images/og/, absolute URLs, and matching og:image, twitter:image, itemprop image, image_src, and JSON-LD image. Review a --sheet contact sheet, then verify the live page and a forum onebox after publishing. Follow WCAG 2.2 AA for new or changed content: semantic HTML, keyboard access, visible focus, readable contrast in every theme, text alternatives, labeled controls, and explicit errors. Support zoom/reflow, respect reduced motion, and keep sound optional. Read /design/sections/accessibility.md for acceptance checks. Report unresolved barriers; automated checks alone do not establish conformance.

A social image is the picture people see before they ever open an article: the forum onebox, a post on X or LinkedIn, a chat link preview, a search card. Every kirupa.com article uses one format for it, the format of the hand-made data structures and sorting images: one solid background color, the pixel-art KIRUPA orange in the top-left corner, no title text, and a visual from the article filling the middle. This page records that format exactly, the order for choosing the visual, the metadata that publishes it, and the checks that keep generated images at the same quality as the hand-made ones. The generator is tools/build_og_images.py, and its per-article plan is tools/og_images.json. Start from these three hand-made originals:

Anatomy

Use a 1.905:1 canvas. The hand-made originals are 2400x1260; generated images are 1200x630, the size Open Graph consumers expect. A few older originals are 2000x1050, the same ratio. Fill the whole canvas with one flat color: no gradient, texture, border, or vignette. Put no title, byline, or caption on the image. The page title already arrives as og:title beside the image, and lettering inside the image repeats it, shrinks to unreadable sizes in small previews, and gets cut off by square crops.

The pixel orange

The orange is a 13x16-cell sprite, not the older round orange logo. At 2400 wide each cell is 12.375px and the sprite's top-left corner sits at (90, 60), so it covers (90, 60) to (251, 258). Scale both the cells and the position with the canvas width: at 1200 wide the cells are 6.1875px and the corner is at (45, 30); at 2000 wide the corner is at (75, 50). Paint it cell by cell with hard edges, never by resizing a bitmap with smoothing. The exact rows and 27 colors are LOGO_ROWS and LOGO_COLORS in the generator; has_logo() samples every cell center and accepts an image only when more than 80% match. Never place the round orange with the dark ring and green leaf on a new image; it is the retired logo, shown here as the thing to replace:

Safe content area

Keep the main content in the safe area. On the 2400-wide originals it is roughly x 300-2300 and y 150-1100. The generator uses (170, 70) to (1110, 560) at 1200 wide, which keeps at least 40px of clear space to the right of the logo and room to breathe on every side. Center the content in that box and let it fill the box in at least one direction: the full width for wide art, the full height for tall art. Content that would end up smaller than 40% of the box in both directions is not a usable visual; choose something else rather than floating a small thumbnail in empty color.

Background palette

Choose the background from the colors sampled from the hand-made images: #fdffbc, #cefdff, #ffe000, #fcf5ff, #fffdd1, #edffa5, #ffeda5, #e4ffc1, #d6fdff, #f6efff, and #ffee00. They are mostly pastels, with saturated yellow for punch. A white card needs a background with enough presence to read as a card, so cards skip the near-white #fcf5ff and #fffdd1. Transparent art needs a background at least 90 in summed RGB distance from the art's average color so it never disappears. When the art has its own light, tinted, uniform border, that border can become the background so the art sits seamlessly on it. The generator picks deterministically from a hash of the page path, so a re-render keeps the same color. Retrofitted originals keep the background they were drawn on.

Choosing the visual

Choose the visual in this order and stop at the first that works:

  • An existing article-specific share image that has a solid background and the old round logo in the corner: retrofit it. Erase the old logo, crop to the art, re-center it in the safe area, and add the pixel orange.
  • The most representative diagram or illustration in the article body. The generator scores each candidate by size, aspect ratio (0.9 to 2.6 is best), position (earlier is slightly better), and visible detail.
  • The article's YouTube video frame (maxresdefault, else sddefault or hqdefault, cropped to 16:9) when the article has no usable figure.
  • An article-specific share image without a solid background, shown on a card.
  • The article's best code sample in an editor card: 3 or more lines, ideally 4-14, and not HTML boilerplate.
  • Smaller in-article art, if it can still reach 40% of the safe area.
  • As a last resort, a KIRUPAicons pixel icon chosen from the title's subject.

What to avoid

Never use these as the main visual:

  • Site chrome: SSI assets, author photos, header icons, mini_icons and large_icons, spacers, previous and next buttons, hit counters, forum smilies.
  • Generic placeholders such as images/s/1.png and images/s/blue.png, and any image shared by more than three articles.
  • Near-empty screenshots: an empty browser window, a blank artboard, or a bare stage. The generator rejects art whose middle is featureless (standard deviation under 4) and down-ranks art that is one flat color (88% or more) or has little edge detail (under 3.5% of pixels).
  • Art containing the old round orange anywhere. Next to the pixel orange it reads as a second logo.
  • Title cards and thumbnails full of lettering when the article has a real diagram.
  • Art smaller than 200x120, or anything that only becomes readable at full size.

Treatment and spacing

Scale flat pixel art (GIFs, or images with 64 colors or fewer and no side over 400px) only by whole numbers with nearest-neighbor sampling, and only when that reaches at least 2x. Otherwise use smooth Lanczos scaling, up to 3x. Never stretch art unevenly or crop away what the article is explaining. Put screenshots and photos on a white card with 18px rounded corners and a soft shadow (18px blur, 10px drop, 20% black). Place transparent art directly on the background, trimmed to its painted pixels. Code cards use a dark #161b22 editor with a darker title bar and three window dots, Departure Mono at the largest size from 34px down to 14px that fits, at most 10 lines of 48 characters, and the same light syntax colors as the site's code blocks. A video frame is a card too, with no play button over it. Anything you draw or redraw follows the Illustrations rules: the arrow rules, consistent gaps, and nothing nearly touching. Examples of each treatment from the published set:

Metadata

Publishing the image is part of the format:

  • Give every new or replaced image a fresh filename. The generator writes images/og/<page slug>.png, or .jpg for photos and video frames. kirupa.com sends a 31-day max-age on images and Cloudflare caches them, and forums and social sites cache previews by URL, so overwriting a published file in place can leave old previews up for weeks.
  • Use absolute https://www.kirupa.com/ URLs.
  • Make every image reference agree: og:image, twitter:image or twitter:image:src, itemprop="image", rel="image_src", and the JSON-LD Article image. tools/site_metadata.py regenerates its managed JSON-LD block from og:image.
  • When a page already has og:image:width, og:image:height, or og:image:type, keep them true: 1200, 630, and image/png or image/jpeg.
  • Save flat art as optimized PNG and photos or video frames as JPEG at quality 90. Most images land between 30 and 150 KB.
  • Upload the image before the page that refers to it, with the guarded publisher.

One new article

For one new article, add the article's images first, then run python3 tools/build_og_images.py --plan --only <page>. Check the new entry in tools/og_images.json, and change its source, mode, or crop if the pick is not the most representative visual. Render it with --render --only <page>, look at the image itself, then run --apply to point the page's metadata at it. --check validates every planned image and its metadata, and tools/test_og_images.py runs it in CI. An article without a modern image is reported as a note, not a failure, so drafts can land first. Podcast pages get theirs automatically: the podcast renderer uses images/og/podcast-<slug>.jpg or .png once it exists.

Bulk regeneration

For bulk work, --plan adds entries only for articles that are not planned yet and do not already have an image with the pixel orange. Deleting the plan and running --plan again replans everything from the current heuristics; keep any hand edits in a separate overrides script and reapply them after replanning. --render redraws every planned image in about a minute. Images from YouTube and the few published images missing from the repository are cached under ~/.cache/kirupa-og. --apply then updates every page. Commit the images before running node tools/build_design_system.mjs, because the design catalog lists only tracked files. Publish all images first, then all pages.

Plan entries

Each plan entry is keyed by page path:

  • image: the output path under images/og/.
  • mode: retrofit, image, video, code, or icons.
  • source: an image path for retrofit and image, a YouTube ID for video, the index of the article's code block for code, or a list of icon names from icon/pixel-twemoji-16/png for icons (the first is drawn largest).
  • background: the solid color. Retrofit uses the original art's color.
  • treatment: image only. card, plain (transparent art), or seamless (the art's border becomes the background).
  • scaling: image only. smooth or pixel.
  • crop: optional [left, top, right, bottom] in source pixels.
  • lines: code only. An optional [first, last] range of 1-based lines.
  • alt: optional text written to og:image:alt and twitter:image:alt.

QA checklist

Check before you publish:

  • Run --sheet <folder> and look at every contact sheet, 30 images at a time. Read each one the way a scroller would: does it say what the article is about without its title?
  • Make sure the pixel orange is the only logo. The generator finds the old round orange by its orange body, dark ring, and green leaf; video frames lose the band that holds it, and art that contains it elsewhere is skipped. Look for small copies the detector can miss.
  • Look for near-empty screenshots, unreadable thumbnails, and cards with large empty margins.
  • Run --check, python3 tools/site_metadata.py --check, and the og image tests.
  • After publishing, fetch a sample of live pages, confirm og:image names the new file, and confirm that file is 1200x630 with the pixel orange.
  • Paste one link into a forum draft and check the onebox. Run a fresh URL through a link preview tool if a cached preview still shows the old image.

Known weak spots

Known weak spots, kept here as guidance rather than fixed silently:

  • The topic icon fallback can miss. The if/else article matched the broad web rule and got a globe; a fork in the road or a decision diagram would teach more. About 30 pages fell all the way back to a light bulb, mostly old Flash index pages.
  • Long lines in code cards are cut with an ellipsis. Prefer a block with short lines, or set lines to a tighter range.
  • A small old logo inside a video frame can survive the crop, as in the Setting CSS Styles frame. Video frames and title cards also keep their lettering, so prefer an article diagram when there is one.
  • Use a 1.905:1 canvas with one solid background color, the pixel orange top-left at the documented position and scale, and no title text.
  • Fill the safe area with the most representative visual from the article; never use site chrome, placeholders, near-empty screenshots, or art carrying the old round orange.
  • Scale pixel art only by whole numbers with nearest-neighbor sampling, smooth art up to 3x, and follow the illustration arrow and spacing rules for anything drawn.
  • Give every new image a fresh filename and make og:image, twitter:image, itemprop image, image_src, and JSON-LD agree on one absolute URL.
  • Review contact sheets and live previews before reporting an image as done.
Source maptools/build_og_images.pytools/og_images.jsontools/test_og_images.pytools/site_metadata.pydata_structures_algorithms/understanding_merkle_trees.htmdata_structures_algorithms/introduction_to_grids.htmsorts/timsort.htm

The KIRUPA Newsletter

Thought provoking content that lives at the intersection of design 🎨, development 🤖, and business 💰 - delivered weekly to over a bazillion subscribers!

SUBSCRIBE NOW

Creating engaging and entertaining content for designers and developers since 1998.

Follow:

Popular

Loose Ends

:: Copyright KIRUPA 2026 //--