diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-24 10:04:47 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-24 10:04:47 +0300 |
| commit | ba7ed37f671c92424a3058fb26465652fad3a131 (patch) | |
| tree | 3d403eae8cb044cd57547837c2582401488287ff | |
| parent | f85b0cd77b3b72a487ca4f35a2eac053100dc8e7 (diff) | |
Make the generated album mobile friendly
Pure CSS/HTML, no JavaScript:
- Add a <meta name="viewport"> tag to the two display heads (header.tmpl
and splash.tmpl) so phones stop rendering at a zoomed-out desktop
width.
- Make the overview grid responsive: minmax(min(THUMBHEIGHT, 100%), 1fr)
so a column never overflows a narrow screen, plus a max-width:700px
media query that shows exactly two square columns on phones (2x2
feature tiles become full-width heroes). aspect-ratio keeps cells
square at every width.
- Add overflow-x:hidden to body so the slam/glitch entry animations
(translateX +/-80vw) cannot make a phone scroll sideways.
- Make the menus touch friendly on phones: the navigator/footer/splash
links become large rounded buttons (~44px tap targets) and the "|"
separators (now wrapped in <span class="nav-sep">) are hidden on
mobile while still showing on desktop.
- Fix a pre-existing W3C error: the stats filter view-page image was
missing an alt attribute (and carried an obsolete border attribute).
Verified with headless screenshots at phone width and the W3C Nu HTML
checker + CSS validator (zero errors).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rwxr-xr-x | bin/shuriken | 7 | ||||
| -rw-r--r-- | share/templates/default/details.tmpl | 2 | ||||
| -rw-r--r-- | share/templates/default/header.tmpl | 53 | ||||
| -rw-r--r-- | share/templates/default/splash.tmpl | 1 | ||||
| -rw-r--r-- | share/templates/default/view.tmpl | 4 | ||||
| -rw-r--r-- | src/lib/stats-filter-album.source.sh | 7 | ||||
| -rwxr-xr-x | tests/cli.sh | 5 |
7 files changed, 67 insertions, 12 deletions
diff --git a/bin/shuriken b/bin/shuriken index aad054e..94e38bd 100755 --- a/bin/shuriken +++ b/bin/shuriken @@ -4736,7 +4736,8 @@ _stats_build_filterview_body() { fi view_page=$(album_view_page_for_photo "$photo") if [ -n "$view_page" ]; then - details_link=$(printf ' <a href="%s/%s-details.html">Details</a> |' \ + details_link=$(printf \ + ' <a href="%s/%s-details.html">Details</a> <span class="nav-sep">|</span>' \ "$backhref_html" "$view_page") fi _stats_print_filterview_body "$backhref_html" "$photo_html" \ @@ -4760,11 +4761,11 @@ _stats_print_filterview_body() { cat <<END <div class='view'> <a href="$next.html"> - <img class='view $animation_class' border='0' src='$backhref_html/$STATS_PHOTOS_DIR/$photo_html'$tooltip_attr /> + <img class='view $animation_class' alt='$photo_html' src='$backhref_html/$STATS_PHOTOS_DIR/$photo_html'$tooltip_attr /> </a> <div class="navigator"> <a href="$prev.html" class="arrow">⇐</a> - <a href="index.html">Gallery</a> |$details_link + <a href="index.html">Gallery</a> <span class="nav-sep">|</span>$details_link <a href="$backhref_html/$STATS_PHOTOS_DIR/$photo_html">Direct link</a> <a href="$next.html" class="arrow">⇒</a> </div> diff --git a/share/templates/default/details.tmpl b/share/templates/default/details.tmpl index cd70328..c61aafd 100644 --- a/share/templates/default/details.tmpl +++ b/share/templates/default/details.tmpl @@ -13,7 +13,7 @@ cat <<END </a> <div class="navigator details-navigator"> <a href="${render_page_num_html}-${render_view_prev_html}-details.html" class="arrow">⇐</a> - <a href="${render_page_num_html}-${render_preview_num_html}.html">Image view</a> | + <a href="${render_page_num_html}-${render_preview_num_html}.html">Image view</a> <span class="nav-sep">|</span> <a href='${render_backhref_html}/${render_photos_dir_html}/${render_photo_html}'>Direct link</a> <a href="${render_page_num_html}-${render_view_next_html}-details.html" class="arrow">⇒</a> </div> diff --git a/share/templates/default/header.tmpl b/share/templates/default/header.tmpl index 2d01e21..d5d1648 100644 --- a/share/templates/default/header.tmpl +++ b/share/templates/default/header.tmpl @@ -3,6 +3,7 @@ cat <<END <html lang="en"> <head> <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> <title>${render_title_html}</title> <link rel="icon" href="${render_backhref_html}/favicon.ico" type="image/x-icon"> <style> @@ -18,6 +19,9 @@ cat <<END width, and makes the gap above the header / below the footer the same 2px as the gaps between the header, grid and footer. */ margin: 0; + /* The slam/glitch entry animations translate elements by +/-80vw; + clip the horizontal overflow so a phone never scrolls sideways. */ + overflow-x: hidden; } a { @@ -204,8 +208,11 @@ cat <<END leave. Spacing comes from the grid gap, so images carry no padding. */ div.thumbs-grid { display: grid; + /* min(THUMBHEIGHT, 100%) keeps a column from ever exceeding the + viewport width, so narrow phones never scroll sideways; on wide + screens the columns are >= THUMBHEIGHT and grow (1fr) to fill. */ grid-template-columns: - repeat(auto-fill, minmax(${render_thumbheight_html}px, 1fr)); + repeat(auto-fill, minmax(min(${render_thumbheight_html}px, 100%), 1fr)); grid-auto-flow: dense; gap: 10px; margin: 0 4px; @@ -377,6 +384,50 @@ cat <<END width: 95%; } } + + /* Phone layout: a 2-column square grid, and the navigator/footer/splash + links become large, well-spaced tap targets (~44px). Pure CSS. */ + @media (max-width: 700px) { + div.thumbs-grid { + grid-template-columns: 1fr 1fr; + gap: 6px; + margin: 0 2px; + } + + div.navigator { + display: flex; + flex-wrap: wrap; + gap: 8px; + justify-content: center; + align-items: center; + } + + div.navigator a, + div.footer a { + display: inline-block; + padding: 12px 16px; + border: 2px solid #ffffff; + border-radius: 8px; + font-size: 1.1em; + text-decoration: none; + } + + div.navigator a.arrow { + padding: 10px 18px; + font-size: 1.4em; + } + + /* Hide the "|" separators (wrapped in spans) so the links read as + discrete buttons on a phone; they stay visible on desktop. */ + div.navigator span.nav-sep { + display: none; + } + + p.enter a { + padding: 14px 24px; + font-size: 1.3em; + } + } </style> </head> diff --git a/share/templates/default/splash.tmpl b/share/templates/default/splash.tmpl index de5837a..8937fc2 100644 --- a/share/templates/default/splash.tmpl +++ b/share/templates/default/splash.tmpl @@ -3,6 +3,7 @@ cat <<END <html lang="en"> <head> <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> <title>${render_title_html}</title> <link rel="icon" href="${render_backhref_html}/favicon.ico" type="image/x-icon"> <style> diff --git a/share/templates/default/view.tmpl b/share/templates/default/view.tmpl index b1e6c79..c28859b 100644 --- a/share/templates/default/view.tmpl +++ b/share/templates/default/view.tmpl @@ -13,8 +13,8 @@ cat <<END </a> <div class="navigator"> <a href="${render_page_num_html}-${render_view_prev_html}.html" class="arrow">⇐</a> - <a href="page-${render_page_num_html}.html#${render_photo_html}">Thumbnails</a> | - <a href="${render_page_num_html}-${render_preview_num_html}-details.html">Details</a> | + <a href="page-${render_page_num_html}.html#${render_photo_html}">Thumbnails</a> <span class="nav-sep">|</span> + <a href="${render_page_num_html}-${render_preview_num_html}-details.html">Details</a> <span class="nav-sep">|</span> <a href='${render_backhref_html}/${render_photos_dir_html}/${render_photo_html}'>Direct link</a> <a href="${render_page_num_html}-${render_view_next_html}.html" class="arrow">⇒</a> </div> diff --git a/src/lib/stats-filter-album.source.sh b/src/lib/stats-filter-album.source.sh index eedb474..c1c1e1c 100644 --- a/src/lib/stats-filter-album.source.sh +++ b/src/lib/stats-filter-album.source.sh @@ -154,7 +154,8 @@ _stats_build_filterview_body() { fi view_page=$(album_view_page_for_photo "$photo") if [ -n "$view_page" ]; then - details_link=$(printf ' <a href="%s/%s-details.html">Details</a> |' \ + details_link=$(printf \ + ' <a href="%s/%s-details.html">Details</a> <span class="nav-sep">|</span>' \ "$backhref_html" "$view_page") fi _stats_print_filterview_body "$backhref_html" "$photo_html" \ @@ -178,11 +179,11 @@ _stats_print_filterview_body() { cat <<END <div class='view'> <a href="$next.html"> - <img class='view $animation_class' border='0' src='$backhref_html/$STATS_PHOTOS_DIR/$photo_html'$tooltip_attr /> + <img class='view $animation_class' alt='$photo_html' src='$backhref_html/$STATS_PHOTOS_DIR/$photo_html'$tooltip_attr /> </a> <div class="navigator"> <a href="$prev.html" class="arrow">⇐</a> - <a href="index.html">Gallery</a> |$details_link + <a href="index.html">Gallery</a> <span class="nav-sep">|</span>$details_link <a href="$backhref_html/$STATS_PHOTOS_DIR/$photo_html">Direct link</a> <a href="$next.html" class="arrow">⇒</a> </div> diff --git a/tests/cli.sh b/tests/cli.sh index 6dfac0a..2c784bc 100755 --- a/tests/cli.sh +++ b/tests/cli.sh @@ -515,8 +515,9 @@ test_generate_cli_overrides_config_values() { test::assert_path_absent "$TEST_TMPDIR/config-dist" test::assert_find_count 0 "$TEST_TMPDIR/cli-dist" '*.tar' test::assert_contains '<title>CLI title</title>' "$page_html" - # THUMBHEIGHT is the grid's minimum cell width (columns grow to fill). - test::assert_contains 'minmax(45px, 1fr)' "$page_html" + # THUMBHEIGHT is the grid's minimum cell width (columns grow to fill); it is + # wrapped in min(...,100%) so a column never overflows a narrow phone. + test::assert_contains 'minmax(min(45px, 100%), 1fr)' "$page_html" test::assert_contains 'max-height: 456px;' "$view_html" test::assert_contains 'Next 1 pictures' "$page_html" test::assert_contains 'href="page-2.html" class="arrow">⇒</a>' \ |
