From 63f9fdff6e5bdf6333a4b7813ebeb5b797838b6d Mon Sep 17 00:00:00 2001 From: grm Date: Fri, 18 Sep 2026 19:29:30 +0300 Subject: Fold the header menu into a button when its links do not fit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long menu wrapped onto two or three lines on phones and narrow windows. With the new Design switch the header menu folds into a ☰ button (an icon, the word Menu, or both) carried by the title or logo block just above it, at the right end of its row, or by the menu bar when nothing is above it; the button opens the links as a stacked list with the search box on top. The open/closed state is a hidden checkbox and the button its label, so opening needs no script and works in old browsers. Whether to fold is decided by a small inline script — any link on a second line means the menu does not fit — re-checked on resize; without it blog.css folds on phones only, and browsers too old for that keep the wrapping menu. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A --- internal/web/theme.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'internal/web/theme.go') diff --git a/internal/web/theme.go b/internal/web/theme.go index 031f8fd..a43603b 100644 --- a/internal/web/theme.go +++ b/internal/web/theme.go @@ -54,6 +54,10 @@ type Theme struct { NavSize string `json:"nav_size"` // normal | small | large NavGap string `json:"nav_gap"` // normal | tight | wide (space around each link) NavActive string `json:"nav_active"` // underline | bold | box | none: how the current page's link is marked + // NavFold folds the header menu into a button when its links do not fit + // the bar (see Layout.BurgerAt); NavFoldLabel is what the button shows. + NavFold bool `json:"nav_fold"` + NavFoldLabel string `json:"nav_fold_label"` // icon | text | both NavBg string `json:"nav_bg"` NavText string `json:"nav_text"` NavHover string `json:"nav_hover"` // "" = same as NavText @@ -118,7 +122,7 @@ func DefaultTheme() Theme { ContentStyle: "card", ContentPadding: "normal", Font: "sans", HeadingFont: "same", FontSize: "normal", HeaderImageHeight: "medium", HeaderAlign: "left", HeaderBg: "#2f3a4a", HeaderText: "#ffffff", TitleSize: "normal", HeaderRule: "none", - NavAlign: "left", NavBold: true, NavUnderline: "hover", NavSize: "normal", NavGap: "normal", NavActive: "underline", NavBg: "#ffffff", NavText: "#222222", + NavAlign: "left", NavBold: true, NavUnderline: "hover", NavSize: "normal", NavGap: "normal", NavActive: "underline", NavFoldLabel: "icon", NavBg: "#ffffff", NavText: "#222222", ShowDates: true, DateFormat: "long", PostsPerPage: postsPerPageChoices[0], ListStyle: "full", PostImage: "top", TitleRule: "none", PostNotices: true, FooterBg: "#2f3a4a", FooterColor: "#d0d5dc", FooterAlign: "center", LogoSize: "medium", @@ -213,6 +217,7 @@ func (t *Theme) normalize() { t.NavSize = pick(t.NavSize, "normal", "small", "large") t.NavGap = pick(t.NavGap, "normal", "tight", "wide") t.NavActive = pick(t.NavActive, "underline", "bold", "box", "none") + t.NavFoldLabel = pick(t.NavFoldLabel, "icon", "text", "both") t.NavBg = color(t.NavBg, d.NavBg) t.NavText = color(t.NavText, d.NavText) t.NavHover = optColor(t.NavHover) @@ -287,6 +292,8 @@ func ThemeFromForm(cur Theme, f url.Values) Theme { t.NavSize = get("nav_size") t.NavGap = get("nav_gap") t.NavActive = get("nav_active") + t.NavFold = on("nav_fold") + t.NavFoldLabel = get("nav_fold_label") t.NavBg = get("nav_bg") t.NavText = get("nav_text") t.NavHover = hover("nav_hover") @@ -591,7 +598,7 @@ a:hover {{"{"}}{{if .LinkHover}} color:{{.LinkHover}};{{end}}{{if eq .LinkUnderl .site-header a { color:{{.HeaderText}}; } .header-image img { max-height:{{.HeaderImageMaxHeight}}; } .site-nav { background:{{.NavBg}}; } -.site-nav a { color:{{.NavText}}; } +.site-nav a, .site-nav .nav-burger { color:{{.NavText}}; } {{- if .NavHover}} .site-nav a:hover { color:{{.NavHover}}; } {{- end}} -- cgit v1.2.3