diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0dbe1ab..16861ec6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,6 +56,18 @@ dependencies and activate it. - Place a header image (either `header.png` or `header.jpg`) in your blog post folder. Make sure the image is under a free license. +### Authoring images (performance and accessibility) + +- **Alt text:** Always add descriptive `alt` text for images (e.g. in Markdown: + `![Description of the image](image.png)`). This helps accessibility and SEO. +- **Dimensions:** Prefer images with reasonable dimensions (e.g. 1200px wide for + in-content screenshots). The theme applies responsive sizing and lazy-loading + to blog content images; very large originals will still be downscaled by the + browser but use more bandwidth. +- **Format:** PNG or JPEG is fine. For very large images, consider providing + WebP versions where the build or CMS supports it; the theme can use + `` / `srcset` for fallbacks. + ### Metadata and Formatting - **Markdown Posts:** Add a metadata block at the beginning of your `index.md` diff --git a/theme/base.html b/theme/base.html index 22ee2ba2..c70aaf3a 100644 --- a/theme/base.html +++ b/theme/base.html @@ -498,7 +498,7 @@

- Creative Commons License + Creative Commons License
diff --git a/theme/blog-post.html b/theme/blog-post.html index febdcaa9..b2a4883b 100644 --- a/theme/blog-post.html +++ b/theme/blog-post.html @@ -79,7 +79,7 @@

{{ sub_nav_item.title }} + alt="{{ sub_nav_item.title }}" loading="lazy" decoding="async" width="400" height="200" />

{{ sub_nav_item.title }}

{{ sub_nav_item.summary }}

diff --git a/theme/css/blog.css b/theme/css/blog.css index 210b3f07..2cccce0d 100644 --- a/theme/css/blog.css +++ b/theme/css/blog.css @@ -221,3 +221,14 @@ /* Safety: never allow gigantic SVGs inside blog content */ .blog-article .post_body svg.icon { width: 1em; height: 1em; } + +/* Responsive images in blog content (LCP / defer offscreen images) */ +.blog-article .post_body img { + max-width: 100%; + height: auto; + display: block; +} +.blog-article .post_body img:not([width]):not([height]) { + /* Reserve space to reduce CLS when dimensions unknown */ + min-height: 1px; +} diff --git a/theme/events.html b/theme/events.html index 8b1aefb8..07bca23f 100644 --- a/theme/events.html +++ b/theme/events.html @@ -14,7 +14,7 @@

Upcoming Events

@@ -47,7 +47,7 @@

Past Events

diff --git a/theme/home.html b/theme/home.html index d1712187..3361af01 100644 --- a/theme/home.html +++ b/theme/home.html @@ -116,7 +116,7 @@

Our Partners

{% for partner in page.meta["partners"] %}
  • - {{ partner.name }} + {{ partner.name }} {{ partner.name }}
  • diff --git a/theme/js/theme.js b/theme/js/theme.js index ea3fa4d5..b47d79bf 100644 --- a/theme/js/theme.js +++ b/theme/js/theme.js @@ -84,6 +84,12 @@ document.querySelectorAll('.dropdown-menu.mega').forEach(menu => { menu.addEventListener('click', (e) => e.stopPropagation()); }); + + /* 7) Lazy-load images in blog content (markdown-rendered imgs don't have loading attr) */ + document.querySelectorAll('.post_body img:not([loading])').forEach(function (img) { + img.setAttribute('loading', 'lazy'); + img.setAttribute('decoding', 'async'); + }); }); // Optional public API diff --git a/theme/partners.html b/theme/partners.html index 52dcee01..7aa502a0 100644 --- a/theme/partners.html +++ b/theme/partners.html @@ -18,7 +18,7 @@
    {% if logo %} - {{ partner.name }} + {{ partner.name }} {% endif %}
    diff --git a/theme/projects.html b/theme/projects.html index a9ea636f..6075f814 100644 --- a/theme/projects.html +++ b/theme/projects.html @@ -25,11 +25,13 @@

    Static Badge {% elif project.type == "affiliated" %} Static Badge {% endif %} {{ project.name }} diff --git a/theme/team.html b/theme/team.html index 2bd456b9..e51af337 100644 --- a/theme/team.html +++ b/theme/team.html @@ -25,7 +25,7 @@

    {{ group.name }}

    {% if member.image_url %} - {{ member.name }} + {{ member.name }} {% endif %}