fix(appearance): font size setting now visibly scales UI text (closes #843)
* fix(appearance): font size setting now visibly scales UI text
Root cause: the original CSS override only changed :root{font-size} which
has no effect on the 232+ hardcoded px values throughout style.css. Only
the ~49 em/rem values were affected, which are not the main visible text.
Fix: add explicit px overrides for the key UI surfaces under each
data-font-size attribute selector:
- .msg-body (chat messages) + headings, code, tables
- .session-item, .session-meta (sidebar session list)
- #msg (composer textarea)
- .file-item (workspace file tree)
The :root override is kept so em/rem cascade correctly, but the targeted
element overrides are what actually make the text visibly larger/smaller.
Also: 8 new regression tests lock in the targeted CSS rules so this
cannot silently regress again.
* fix: composer large font was no-op — bump to 18px (default is 16px)
---------
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,5 +1,15 @@
|
||||
# Hermes Web UI -- Changelog
|
||||
|
||||
## [v0.50.147] — 2026-04-22
|
||||
|
||||
### Fixed
|
||||
- **Font size setting now visibly changes UI text** — selecting Small or Large
|
||||
in Appearance settings previously had no visible effect because the CSS override
|
||||
only changed `:root{font-size}`, but the stylesheet uses 230+ hardcoded `px`
|
||||
values that are unaffected by root font-size. Added explicit per-element overrides
|
||||
for the key UI surfaces: chat message body, sidebar session list, composer
|
||||
textarea, and workspace file tree. Closes #843. (#844)
|
||||
|
||||
## [v0.50.146] — 2026-04-22
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -12,8 +12,47 @@
|
||||
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;font-size:14px;line-height:1.6;
|
||||
}
|
||||
/* ── Font size modifiers ── */
|
||||
:root[data-font-size="small"]{font-size:12px;}
|
||||
:root[data-font-size="large"]{font-size:16px;}
|
||||
/* ── Font size preference: scale key UI text elements ── */
|
||||
/* Default is 14px (no attribute needed). Small=12px, Large=16px. */
|
||||
/* We override the px values directly on key containers since most of the */
|
||||
/* stylesheet uses hardcoded px — changing :root font-size alone only affects */
|
||||
/* the small number of em/rem values. */
|
||||
|
||||
/* Sidebar session list */
|
||||
:root[data-font-size="small"] .session-item { font-size: 11px; }
|
||||
:root[data-font-size="large"] .session-item { font-size: 15px; }
|
||||
:root[data-font-size="small"] .session-meta { font-size: 10px; }
|
||||
:root[data-font-size="large"] .session-meta { font-size: 13px; }
|
||||
:root[data-font-size="small"] .session-title-input { font-size: 11px; }
|
||||
:root[data-font-size="large"] .session-title-input { font-size: 15px; }
|
||||
|
||||
/* Chat message body */
|
||||
:root[data-font-size="small"] .msg-body { font-size: 12px; }
|
||||
:root[data-font-size="large"] .msg-body { font-size: 16px; }
|
||||
:root[data-font-size="small"] .msg-body h1 { font-size: 15px; }
|
||||
:root[data-font-size="large"] .msg-body h1 { font-size: 21px; }
|
||||
:root[data-font-size="small"] .msg-body h2 { font-size: 13px; }
|
||||
:root[data-font-size="large"] .msg-body h2 { font-size: 19px; }
|
||||
:root[data-font-size="small"] .msg-body h3 { font-size: 12px; }
|
||||
:root[data-font-size="large"] .msg-body h3 { font-size: 16px; }
|
||||
:root[data-font-size="small"] .msg-body code { font-size: 10.5px; }
|
||||
:root[data-font-size="large"] .msg-body code { font-size: 14.5px; }
|
||||
:root[data-font-size="small"] .msg-body pre code { font-size: 11px; }
|
||||
:root[data-font-size="large"] .msg-body pre code { font-size: 15px; }
|
||||
:root[data-font-size="small"] .msg-body table { font-size: 11px; }
|
||||
:root[data-font-size="large"] .msg-body table { font-size: 14px; }
|
||||
|
||||
/* Composer textarea (default is 16px in stylesheet) */
|
||||
:root[data-font-size="small"] #msg { font-size: 14px; }
|
||||
:root[data-font-size="large"] #msg { font-size: 18px; }
|
||||
|
||||
/* Workspace file tree */
|
||||
:root[data-font-size="small"] .file-item { font-size: 11px; }
|
||||
:root[data-font-size="large"] .file-item { font-size: 14px; }
|
||||
|
||||
/* App-level base — keeps em/rem values scaling correctly */
|
||||
:root[data-font-size="small"] { font-size: 12px; }
|
||||
:root[data-font-size="large"] { font-size: 16px; }
|
||||
/* ── Dark mode — navy-black + gold accent matching Hermes terminal ── */
|
||||
:root.dark {
|
||||
--bg:#0D0D1A;--sidebar:#141425;--border:#2A2A45;--border2:rgba(255,255,255,0.14);
|
||||
|
||||
@@ -25,8 +25,9 @@ class TestFontSizeCssModifiers:
|
||||
|
||||
def test_small_is_smaller_than_default(self):
|
||||
css = _read("static/style.css")
|
||||
m_small = re.search(r':root\[data-font-size="small"\]\{font-size:(\d+)px', css)
|
||||
m_large = re.search(r':root\[data-font-size="large"\]\{font-size:(\d+)px', css)
|
||||
# Match both compact {font-size:12px} and spaced { font-size: 12px; } formats
|
||||
m_small = re.search(r':root\[data-font-size="small"\][^{]*\{[^}]*font-size:\s*(\d+)px', css)
|
||||
m_large = re.search(r':root\[data-font-size="large"\][^{]*\{[^}]*font-size:\s*(\d+)px', css)
|
||||
assert m_small and m_large, "Both small and large font-size rules must set px values"
|
||||
assert int(m_small.group(1)) < 14, "Small font size must be < 14px (default)"
|
||||
assert int(m_large.group(1)) > 14, "Large font size must be > 14px (default)"
|
||||
@@ -171,3 +172,57 @@ class TestFontSizeI18nCoverage:
|
||||
src = _read("static/i18n.js")
|
||||
count = src.count("font_size_large")
|
||||
assert count >= 6, f"font_size_large must appear in all 6 locales, found {count}"
|
||||
|
||||
|
||||
class TestFontSizeCssTargetedOverrides:
|
||||
"""CSS must override px-unit text in key UI elements, not just :root font-size.
|
||||
|
||||
The original PR only set :root font-size, but the stylesheet uses hardcoded px
|
||||
values throughout — changing :root has no effect on those. This test class locks
|
||||
in the targeted overrides for the most visible UI surfaces.
|
||||
"""
|
||||
|
||||
def test_msg_body_overridden_for_small(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="small"] .msg-body' in css, \
|
||||
"Chat message text must be explicitly scaled for small"
|
||||
|
||||
def test_msg_body_overridden_for_large(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="large"] .msg-body' in css, \
|
||||
"Chat message text must be explicitly scaled for large"
|
||||
|
||||
def test_session_item_overridden_for_small(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="small"] .session-item' in css, \
|
||||
"Sidebar session list text must be explicitly scaled for small"
|
||||
|
||||
def test_session_item_overridden_for_large(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="large"] .session-item' in css, \
|
||||
"Sidebar session list text must be explicitly scaled for large"
|
||||
|
||||
def test_composer_overridden_for_small(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="small"] #msg' in css, \
|
||||
"Composer textarea must be explicitly scaled for small"
|
||||
|
||||
def test_composer_overridden_for_large(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="large"] #msg' in css, \
|
||||
"Composer textarea must be explicitly scaled for large"
|
||||
# Large composer must not equal the default 16px — that's a no-op
|
||||
import re
|
||||
m = re.search(r':root\[data-font-size="large"\] #msg \{ font-size: (\d+)px', css)
|
||||
assert m and int(m.group(1)) != 16, \
|
||||
"Large composer font-size must differ from default (16px) to have visible effect"
|
||||
|
||||
def test_file_item_overridden_for_small(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="small"] .file-item' in css, \
|
||||
"Workspace file tree text must be explicitly scaled for small"
|
||||
|
||||
def test_file_item_overridden_for_large(self):
|
||||
css = _read("static/style.css")
|
||||
assert ':root[data-font-size="large"] .file-item' in css, \
|
||||
"Workspace file tree text must be explicitly scaled for large"
|
||||
|
||||
Reference in New Issue
Block a user