diff options
| author | grm <grm@eyesin.space> | 2026-09-13 00:45:06 +0300 |
|---|---|---|
| committer | grm <grm@eyesin.space> | 2026-09-13 00:45:06 +0300 |
| commit | e671381121a63422f0cf4d5b0842f80109a12d20 (patch) | |
| tree | 9c6d218ea58930fecdd9520beb48b5afad9642e1 /internal | |
| parent | d11e4c9544f544b3a024c7ac705a674b4096cf50 (diff) | |
| download | blogspace-e671381121a63422f0cf4d5b0842f80109a12d20.tar.gz blogspace-e671381121a63422f0cf4d5b0842f80109a12d20.tar.bz2 blogspace-e671381121a63422f0cf4d5b0842f80109a12d20.zip | |
Drop the content width option: the page is always full width
With the column grid, a centred max-width box meant the main content did
not fill the page when no side columns were shown. The column
percentages now divide the whole page; a blogger who wants a narrower,
centred main column keeps the columns' space instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/web/static/blog.css | 3 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/design.html | 7 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/layout.html | 4 | ||||
| -rw-r--r-- | internal/web/theme.go | 16 | ||||
| -rw-r--r-- | internal/web/web_test.go | 6 |
5 files changed, 8 insertions, 28 deletions
diff --git a/internal/web/static/blog.css b/internal/web/static/blog.css index c785ca6..d4465a2 100644 --- a/internal/web/static/blog.css +++ b/internal/web/static/blog.css @@ -1,7 +1,7 @@ /* Public blog base styles — colours, fonts and widths come from the inline theme <style>. */ * { box-sizing: border-box; } img { max-width: 100%; height: auto; } -.wrap { padding: 0 1em; } +.wrap { padding: 0 1em; } /* full width; the columns' percentages divide the page */ .site-header { padding: 0; } .header-image img { display: block; width: 100%; max-height: 320px; object-fit: cover; } .header-text { padding: 1.4em 1em; } @@ -56,7 +56,6 @@ img { max-width: 100%; height: auto; } flexbox puts the left column before it. Widths come from the theme CSS. Browsers without flexbox see the columns stacked, which still reads fine. */ .cols { display: flex; flex-wrap: wrap; align-items: flex-start; } -body.has-left .wrap, body.has-right .wrap { max-width: none; } /* side columns: use the whole page */ .col { width: 100%; } .col-left { order: -1; padding-right: 1.5em; } .col-right { padding-left: 1.5em; } diff --git a/internal/web/templates/dashboard/design.html b/internal/web/templates/dashboard/design.html index 342cabe..4c86c79 100644 --- a/internal/web/templates/dashboard/design.html +++ b/internal/web/templates/dashboard/design.html @@ -73,11 +73,6 @@ </select></label> </div> <div class="row"> - <label>Width<br><select name="content_width"> - <option value="narrow"{{if eq $t.ContentWidth "narrow"}} selected{{end}}>Narrow</option> - <option value="medium"{{if eq $t.ContentWidth "medium"}} selected{{end}}>Medium</option> - <option value="wide"{{if eq $t.ContentWidth "wide"}} selected{{end}}>Wide</option> - </select></label> <label>Box style<br><select name="content_style"> <option value="card"{{if eq $t.ContentStyle "card"}} selected{{end}}>Card (shadow, rounded corners)</option> <option value="flat"{{if eq $t.ContentStyle "flat"}} selected{{end}}>Flat</option> @@ -88,7 +83,7 @@ <option value="roomy"{{if eq $t.ContentPadding "roomy"}} selected{{end}}>Roomy</option> </select></label> </div> - <p class="muted small">Width only applies while there are no side columns; with a left or right column the blog uses the whole page.</p> + <p class="muted small">The content spans the whole page; how much of it the posts get is set by the column widths on the <a href="/b/{{.Blog.Subdomain}}/layout#columns">Layout</a> tab.</p> </div> <div class="card" id="header"> diff --git a/internal/web/templates/dashboard/layout.html b/internal/web/templates/dashboard/layout.html index 7691b1e..229ca0e 100644 --- a/internal/web/templates/dashboard/layout.html +++ b/internal/web/templates/dashboard/layout.html @@ -25,8 +25,8 @@ <label>Left column width<br><input type="number" name="left_width" value="{{$t.LeftWidth}}" min="15" max="40" step="5"> %</label> <label>Right column width<br><input type="number" name="right_width" value="{{$t.RightWidth}}" min="15" max="40" step="5"> %</label> </div> - <p class="muted small">Between 15% and 40% each; the main content takes the rest. A column only appears when it has at least one module; as soon as one does, the blog spreads over the whole page. On phones the columns stack: main content first, then the left and right columns, then the footer.</p> - <label class="check"><input type="checkbox" name="keep_columns"{{if $t.KeepColumns}} checked{{end}}> Always keep the columns' space, even when a column is empty or hidden <span class="muted">(the main content then has the same width on every page)</span></label> + <p class="muted small">Between 15% and 40% each; the main content takes the rest. A column only appears when it has at least one module; without columns the posts take the whole width. On phones the columns stack: main content first, then the left and right columns, then the footer.</p> + <label class="check"><input type="checkbox" name="keep_columns"{{if $t.KeepColumns}} checked{{end}}> Always keep the columns' space, even when a column is empty or hidden <span class="muted">(the main content then keeps its width and stays centred)</span></label> <p class="actionrow"><button type="submit">Save columns</button></p> </form> </div> diff --git a/internal/web/theme.go b/internal/web/theme.go index 46067ba..1ecd832 100644 --- a/internal/web/theme.go +++ b/internal/web/theme.go @@ -24,7 +24,6 @@ type Theme struct { LinkColor string `json:"link_color"` LinkHover string `json:"link_hover"` // "" = same as LinkColor LinkUnderline string `json:"link_underline"` // always | hover | never - ContentWidth string `json:"content_width"` // narrow | medium | wide (no side columns) ContentStyle string `json:"content_style"` // card | flat ContentPadding string `json:"content_padding"` // normal | compact | roomy Font string `json:"font"` // sans | serif | mono @@ -79,7 +78,7 @@ func DefaultTheme() Theme { return Theme{ BgColor: "#e9e6df", BgMode: "cover", ContentBg: "#ffffff", TextColor: "#222222", LinkColor: "#1a5fb4", LinkUnderline: "always", - ContentWidth: "medium", ContentStyle: "card", ContentPadding: "normal", + ContentStyle: "card", ContentPadding: "normal", Font: "sans", HeadingFont: "same", FontSize: "normal", HeaderImageHeight: "medium", HeaderAlign: "left", HeaderBg: "#2f3a4a", HeaderText: "#ffffff", NavAlign: "left", NavStyle: "normal", NavBg: "#ffffff", NavText: "#222222", @@ -140,7 +139,6 @@ func (t *Theme) normalize() { t.LinkColor = color(t.LinkColor, d.LinkColor) t.LinkHover = optColor(t.LinkHover) t.LinkUnderline = pick(t.LinkUnderline, "always", "hover", "never") - t.ContentWidth = pick(t.ContentWidth, "medium", "narrow", "wide") t.ContentStyle = pick(t.ContentStyle, "card", "flat") t.ContentPadding = pick(t.ContentPadding, "normal", "compact", "roomy") t.Font = pick(t.Font, "sans", "serif", "mono") @@ -198,7 +196,6 @@ func ThemeFromForm(cur Theme, f url.Values) Theme { t.LinkColor = get("link_color") t.LinkHover = hover("link_hover") t.LinkUnderline = get("link_underline") - t.ContentWidth = get("content_width") t.ContentStyle = get("content_style") t.ContentPadding = get("content_padding") t.Font = get("font") @@ -371,16 +368,6 @@ func (t Theme) FontSizePx() string { return "17px" } -func (t Theme) MaxWidth() string { - switch t.ContentWidth { - case "narrow": - return "640px" - case "wide": - return "1100px" - } - return "840px" -} - // ContentPaddingCSS returns desktop and phone paddings; "normal" is left to blog.css. func (t Theme) ContentPaddingCSS() (desktop, phone string) { switch t.ContentPadding { @@ -430,7 +417,6 @@ a { color:{{.LinkColor}};{{if eq .LinkUnderline "always"}} text-decoration:under {{- if or .LinkHover (eq .LinkUnderline "hover")}} a:hover {{"{"}}{{if .LinkHover}} color:{{.LinkHover}};{{end}}{{if eq .LinkUnderline "hover"}} text-decoration:underline;{{end}} } {{- end}} -.wrap { max-width:{{.MaxWidth}}; margin:0 auto; } .site-header { background:{{.HeaderBg}}; color:{{.HeaderText}}; text-align:{{.HeaderAlign}}; } .site-header a { color:{{.HeaderText}}; } .header-image img { max-height:{{.HeaderImageMaxHeight}}; } diff --git a/internal/web/web_test.go b/internal/web/web_test.go index b8f761a..a988a23 100644 --- a/internal/web/web_test.go +++ b/internal/web/web_test.go @@ -82,18 +82,18 @@ func TestThemeNormalizeAndCSS(t *testing.T) { if !th.HeaderOn || !th.LeftOn || !th.RightOn || !th.FooterOn || th.LeftWidth != 15 { t.Errorf("old theme layout defaults: %+v", th) } - f := url.Values{"bg_color": {"#ABCDEF"}, "content_width": {"wide"}, "bg_image": {"not-a-uuid"}, "logo_size": {"large"}, + f := url.Values{"bg_color": {"#ABCDEF"}, "bg_image": {"not-a-uuid"}, "logo_size": {"large"}, "link_hover": {"#ff0000"}, "nav_hover": {"#00ff00"}, "nav_hover_custom": {"on"}, "nav_style": {"uppercase"}, "nav_align": {"center"}, "link_underline": {"hover"}, "heading_font": {"serif"}, "content_style": {"flat"}, "content_padding": {"roomy"}, "date_format": {"iso"}} th = ThemeFromForm(DefaultTheme(), f) - if th.BgColor != "#abcdef" || th.ContentWidth != "wide" || th.BgImage != "" || th.LogoSize != "large" { + if th.BgColor != "#abcdef" || th.BgImage != "" || th.LogoSize != "large" { t.Errorf("from form: %+v", th) } if th.LinkHover != "" || th.NavHover != "#00ff00" || th.ShowDates || th.DateFormat != "iso" { t.Errorf("hover checkbox / unticked checkboxes: %+v", th) } css := th.CSS() - for _, want := range []string{"background-color:#abcdef", "max-width:1100px", "text-transform:uppercase", ".site-nav a:hover { color:#00ff00", "a:hover { text-decoration:underline", + for _, want := range []string{"background-color:#abcdef", "text-transform:uppercase", ".site-nav a:hover { color:#00ff00", "a:hover { text-decoration:underline", "h1, h2, h3, h4, h5, h6 { font-family:Georgia", "text-align:center", "border-radius:0", "padding:2.2em 3em", "@media (max-width: 700px)", ".logo { max-height:140px"} { if !strings.Contains(css, want) { t.Errorf("css missing %q:\n%s", want, css) |
