Skip to content

Reserve image space site-wide; - #884

Open
richarddushime wants to merge 3 commits into
mainfrom
issue#869
Open

richarddushime wants to merge 3 commits into
mainfrom
issue#869

Conversation

@richarddushime

@richarddushime richarddushime commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Description

The alt half of #869 landed in #882 — no image on any of the 7,283 built pages is missing an alt attribute. The dimension half had not: only 25.7% of the site's 22,248 images carried both width and height, so the browser could not reserve their boxes before the files loaded.

  • Markdown images get width/height from the page bundle's resource, or from static/, via a new render-image hook. img { height: auto; max-width: 100% } in the stylesheet means the attributes fix the aspect ratio without freezing the rendered size.
  • The navbar logo carries its dimensions on every page. Hugo cannot measure an SVG, so functions/logo_dims reads the root viewBox; the stylesheet sizes the logo by height with width: auto, which previously left the brand's width unknown until the file arrived and shifted the menu sideways.
  • The chatbot launcher and the FORWARD SDG badges carry theirs too.
  • The UNESCO recognition image, floated at width 200 in two content files, gets the matching height.
  • teamwork.webp on the homepage described a megaphone, copy-pasted from the feature above it.
  • check_seo_html.py gains hard check 5 (every homepage image sized) and reports site-wide coverage; it fails on the pre-fix build and passes on this one.

Fixes # (issue)

Type of Change

  • Content/documentation update
  • Bug fix

Testing

Checklist

  • Self-reviewed my changes
  • Verified links and formatting are correct
  • No new warnings or errors

Notes

The alt half of #869 landed in #882 — no image on any of the 7,283 built pages
is missing an alt attribute. The intrinsic-dimension half had not: only 25.7% of
the site's 22,248 images carried both width and height, so the browser could not
reserve their boxes before the files loaded.

- Markdown images get width/height from the page bundle's resource, or from
  static/, via a new render-image hook. `img { height: auto; max-width: 100% }`
  in the stylesheet means the attributes fix the aspect ratio without freezing
  the rendered size.
- The navbar logo carries its dimensions on every page. Hugo cannot measure an
  SVG, so functions/logo_dims reads the root viewBox; the stylesheet sizes the
  logo by height with `width: auto`, which previously left the brand's width
  unknown until the file arrived and shifted the menu sideways.
- The chatbot launcher and the FORWARD SDG badges carry theirs too.
- The UNESCO recognition image, floated at width 200 in two content files, gets
  the matching height.
- `teamwork.webp` on the homepage described a megaphone, copy-pasted from the
  feature above it.
- check_seo_html.py gains hard check 5 (every homepage image sized) and reports
  site-wide coverage; it fails on the pre-fix build and passes on this one.

Coverage goes from 25.7% to 98.8%; the remainder are remote SVGs and avatars
already sized in CSS. A tag-by-tag diff of all 22,248 images across both builds
shows no change to any src or attribute other than the added dimensions and the
one intended alt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

👍 All image files/references (if any) are in webp format, in line with our policy.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

📝 Spell Check Results

Found 118 potential spelling issue(s) when checking 42 changed file(s):

📄 content/ai-metascience/index.md

Line Issue
580 Harware ==> Hardware
580 nWe ==> new
580 nIn ==> inn, min, bin, nine
580 nWe ==> new
580 nWe ==> new
580 nWe ==> new
580 nWe ==> new

📄 static/apps/community_map.html

Line Issue
158 facsimilie ==> facsimile
522 overrideable ==> overridable
714 asyncronous ==> asynchronous
837 evalulate ==> evaluate
916 accomodate ==> accommodate
945 ue ==> use, due
945 ue ==> use, due
945 ue ==> use, due
945 ue ==> use, due
945 te ==> the, be, we, to
945 ue ==> use, due
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 ue ==> use, due
945 ue ==> use, due
945 ue ==> use, due
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Te ==> The, Be, We, To
945 Ue ==> Use, Due
945 te ==> the, be, we, to
945 te ==> the, be, we, to
945 Ue ==> Use, Due
945 te ==> the, be, we, to
945 ot ==> to, of, or, not, it
945 ot ==> to, of, or, not, it
945 ot ==> to, of, or, not, it
945 te ==> the, be, we, to
945 ot ==> to, of, or, not, it
945 Ot ==> To, Of, Or, Not, It
945 Ot ==> To, Of, Or, Not, It
945 Ot ==> To, Of, Or, Not, It
952 te ==> the, be, we, to
952 te ==> the, be, we, to
952 te ==> the, be, we, to
952 ue ==> use, due
952 ue ==> use, due
952 ue ==> use, due
952 ue ==> use, due
952 ue ==> use, due
952 ue ==> use, due
952 ot ==> to, of, or, not, it
952 ot ==> to, of, or, not, it
952 Ot ==> To, Of, Or, Not, It
952 Ot ==> To, Of, Or, Not, It
952 statics ==> statistics
952 statics ==> statistics
952 statics ==> statistics
952 te ==> the, be, we, to
952 ue ==> use, due
952 ot ==> to, of, or, not, it
952 ot ==> to, of, or, not, it
952 ot ==> to, of, or, not, it
952 Te ==> The, Be, We, To
952 Te ==> The, Be, We, To
952 Te ==> The, Be, We, To
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
952 Ue ==> Use, Due
990 coverting ==> converting, covering, coveting
990 havn't ==> haven't
990 havn't ==> haven't
990 havn't ==> haven't
990 havn't ==> haven't
990 ot ==> to, of, or, not, it
990 ot ==> to, of, or, not, it
990 Mesures ==> Measures
990 Ot ==> To, Of, Or, Not, It
990 ot ==> to, of, or, not, it
990 ot ==> to, of, or, not, it
990 ot ==> to, of, or, not, it
990 ot ==> to, of, or, not, it
990 Ot ==> To, Of, Or, Not, It
1191 inluding ==> including
1471 instanciate ==> instantiate
5677 Wll ==> Will, Well
5677 Wll ==> Will, Well
5677 SOry ==> sorry, sort
5677 bU ==> by, be, but, bug, bun, bud, buy, bum
5677 Fo ==> Of, For, To, Do, Go
5677 nd ==> and, 2nd
5677 wOH ==> who
5677 ue ==> use, due

ℹ️ How to address these issues:

  1. Fix the typo: If it's a genuine typo, please correct it.
  2. Add to whitelist: If it's a valid word (e.g., a name, technical term), add it to .codespell-ignore.txt
  3. False positive: If this is a false positive, please report it in the PR comments.

🤖 This check was performed by codespell

@LukasWallrich LukasWallrich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with a local build of this branch and main. The mechanics all hold up: the build is clean, the render-image hook changes no attribute other than width/height (and the one alt text) across all 7,285 pages, the CSS the PR relies on already exists (img { height: auto; max-width: 100% } in _root.scss, width: auto on .navbar-brand img), and check_seo_html.py fails on the main build and passes on this one (25.7% → 98.8% of images sized).

One fix needed before this leaves draft:

  • content/home/5-get-involved.md:26 — the new alt text ("Several hands stacked on top of each other") does not match static/img/teamwork.webp either. The image shows three people, head and shoulders. Something like "Three people standing together. Illustration." would be accurate.

Smaller, take or leave:

  • content/awards/awards.md still has five raw <img src="sips.webp" align="right"> tags without width/height, in the same file this PR edits.
  • layouts/_default/_markup/render-image.html could add loading="lazy", which #869 mentions; the hook is the natural place for it.
  • logo_dims.html rounds the viewBox with %.0f, so the declared aspect ratio is about 1% off the true one. Harmless given the CSS, but %.4g would keep it exact.
  • Check 5 is a hard gate in deploy.yaml, so any future unsized homepage image blocks the production deploy. Fine if that is the intent, just flagging it.

- teamwork.webp shows three people, head and shoulders; the previous alt
  described stacked hands, which the image does not contain.
- The ten SIPS logos in awards.md declare their intrinsic 200x70. No CSS sizes
  them, so they already render at that size; the attributes only reserve the box.
- The deploy step name now reflects that check_seo_html.py covers dimensions.
@richarddushime
richarddushime marked this pull request as ready for review September 14, 2026 19:45
@richarddushime
richarddushime requested a review from a team as a code owner September 14, 2026 19:45
@LukasWallrich

LukasWallrich commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Staging Deployment Status

This PR has been successfully deployed to staging as part of an aggregated deployment.

Deployed at: 2026-09-17 18:53:01 UTC
Staging URL: https://staging.forrt.org

The staging site shows the combined state of all compatible open PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants