ssh git@grit.deadkey.org man

Commit e44cb73 h

Pat Ambrosio · 26-09-01 14:02

Widen the measure from 60 to 78 characters

Changes: 3 files +47 -13

Changes (Side-by-Side)

share/jenny/layout/page.sh +21 -6

cat << _EOF_
503 for a narrow screen to get smaller text: the measure is already 503 for a narrow screen to get smaller text: the measure is already
504 handled by the column width, and shrinking the type only buys 504 handled by the column width, and shrinking the type only buys
505 characters per line that the reader did not ask for. */ 505 characters per line that the reader did not ask for. */
506 article { padding: 0; margin: 1em 0; max-width: 74ch; }
507 /* 74ch is sized for a post: the arrow's column plus a 60ch body. A
506 article { padding: 0; margin: 1em 0; max-width: 92ch; }
507 /* 92ch is sized for a post: the arrow's column plus a 78ch body. A
508 sidebar is an addition to that, so the article grows by exactly the 508 sidebar is an addition to that, so the article grows by exactly the
509 sidebar's column and gap. Without this the sidebar ate into the 509 sidebar's column and gap. Without this the sidebar ate into the
510 74ch and the body came out 537px against a post's 540 -- a
510 measure and the body came out narrower than a post's -- a
511 difference with no cause the reader could see. Widening here rather 511 difference with no cause the reader could see. Widening here rather
512 than narrowing the body keeps the measure identical everywhere. */ 512 than narrowing the body keeps the measure identical everywhere. */
513 article:has(.page-nav-wrap) { max-width: calc(74ch + var(--page-nav-width) + var(--page-nav-gap)); }
513 article:has(.page-nav-wrap) { max-width: calc(92ch + var(--page-nav-width) + var(--page-nav-gap)); }
514 /* A bare URL has no spaces to wrap at, so on a narrow screen one 514 /* A bare URL has no spaces to wrap at, so on a narrow screen one
515 long link sets the width of the whole page -- a reference to 515 long link sets the width of the whole page -- a reference to
516 https://github.com/hmngwy/jenny made this post 375px wide at a 516 https://github.com/hmngwy/jenny made this post 375px wide at a
cat << _EOF_
742 share its line is below the text now -- and min-width: 0 lets it 742 share its line is below the text now -- and min-width: 0 lets it
743 shrink under a narrow viewport instead of setting a floor that makes 743 shrink under a narrow viewport instead of setting a floor that makes
744 the page scroll sideways. */ 744 the page scroll sideways. */
745 .contents { display: block; max-width: 60ch; width: 100%; min-width: 0; }
745 /* 78ch. Measured against the MDD site, which reads well at 82ch in
746 its own font; a few characters under that keeps a comparable line
747 without going as long. Roboto at 16px puts one character at 8.99px,
748 so this is about 700px of text. */
749 .contents { display: block; max-width: 78ch; width: 100%; min-width: 0; }
746 750
747 /* Narrow: the sidebar has nowhere to go, so it stacks above the body 751 /* Narrow: the sidebar has nowhere to go, so it stacks above the body
748 and everything collapses to one column. Every part has to leave 752 and everything collapses to one column. Every part has to leave
cat << _EOF_
1069 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); 1073 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
1070 z-index: 1000; 1074 z-index: 1000;
1071 opacity: 0; 1075 opacity: 0;
1072 visibility: hidden;
1076 /* display:none while hidden, not merely visibility:hidden. A
1077 hidden-but-displayed box still takes part in layout, so one
1078 centred on a marker near the right margin stretched the page and
1079 gave it a horizontal scrollbar -- which only showed up once the
1080 body widened and the markers moved further right. The nudge that
1081 pulls a tooltip back inside runs on show, too late for a
1082 scrollbar the reader already has, and contain: layout does not
1083 help: an absolutely positioned box still reaches its scroll
1084 container. Measurement is unaffected because the box is measured
1085 after .visible is added, when it has dimensions again. */
1086 display: none;
1073 transition: none; 1087 transition: none;
1074 margin-bottom: 0.5em; 1088 margin-bottom: 0.5em;
1075 pointer-events: auto; 1089 pointer-events: auto;
cat << _EOF_
1084 /* Show tooltip. */ 1098 /* Show tooltip. */
1085 .fn-tip.visible, 1099 .fn-tip.visible,
1086 .citation-tip.visible { 1100 .citation-tip.visible {
1101 display: block;
1087 opacity: 1; 1102 opacity: 1;
1088 visibility: visible; 1103 visibility: visible;
1089 } 1104 }

share/jenny/layout/post.sh +18 -3

cat << _EOF_
385 for a narrow screen to get smaller text: the measure is already 385 for a narrow screen to get smaller text: the measure is already
386 handled by the column width, and shrinking the type only buys 386 handled by the column width, and shrinking the type only buys
387 characters per line that the reader did not ask for. */ 387 characters per line that the reader did not ask for. */
388 article { padding: 0; margin: 1em 0; max-width: 74ch; }
388 article { padding: 0; margin: 1em 0; max-width: 92ch; }
389 /* A bare URL has no spaces to wrap at, so on a narrow screen one 389 /* A bare URL has no spaces to wrap at, so on a narrow screen one
390 long link sets the width of the whole page -- a reference to 390 long link sets the width of the whole page -- a reference to
391 https://github.com/hmngwy/jenny made this post 375px wide at a 391 https://github.com/hmngwy/jenny made this post 375px wide at a
cat << _EOF_
575 width. Without it a 60ch measure kept the row from ever narrowing 575 width. Without it a 60ch measure kept the row from ever narrowing
576 past that, so at 320px the page scrolled sideways rather than the 576 past that, so at 320px the page scrolled sideways rather than the
577 text reflowing. */ 577 text reflowing. */
578 .contents { display: block; max-width: 60ch; width: 100%; min-width: 0; }
578 /* 78ch. Measured against the MDD site, which reads well at 82ch in
579 its own font; a few characters under that keeps a comparable line
580 without going as long. Roboto at 16px puts one character at 8.99px,
581 so this is about 700px of text. */
582 .contents { display: block; max-width: 78ch; width: 100%; min-width: 0; }
579 .body-row { min-width: 0; } 583 .body-row { min-width: 0; }
580 584
581 /* On a phone the stamp column is a quarter of the screen held open for 585 /* On a phone the stamp column is a quarter of the screen held open for
cat << _EOF_
890 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); 894 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
891 z-index: 1000; 895 z-index: 1000;
892 opacity: 0; 896 opacity: 0;
893 visibility: hidden;
897 /* display:none while hidden, not merely visibility:hidden. A
898 hidden-but-displayed box still takes part in layout, so one
899 centred on a marker near the right margin stretched the page and
900 gave it a horizontal scrollbar -- which only showed up once the
901 body widened and the markers moved further right. The nudge that
902 pulls a tooltip back inside runs on show, too late for a
903 scrollbar the reader already has, and contain: layout does not
904 help: an absolutely positioned box still reaches its scroll
905 container. Measurement is unaffected because the box is measured
906 after .visible is added, when it has dimensions again. */
907 display: none;
894 transition: none; 908 transition: none;
895 margin-bottom: 0.5em; 909 margin-bottom: 0.5em;
896 pointer-events: auto; 910 pointer-events: auto;
cat << _EOF_
905 /* Show tooltip. */ 919 /* Show tooltip. */
906 .fn-tip.visible, 920 .fn-tip.visible,
907 .citation-tip.visible { 921 .citation-tip.visible {
922 display: block;
908 opacity: 1; 923 opacity: 1;
909 visibility: visible; 924 visibility: visible;
910 } 925 }

test/regressions.sh +8 -4

assert_file_contains "$al/.dist/index.html" 'width: 2.25em'
1036 it "the body is not indented by a second mechanism" 1036 it "the body is not indented by a second mechanism"
1037 # A margin on .contents would be another copy of the column, drifting the 1037 # A margin on .contents would be another copy of the column, drifting the
1038 # moment the stamp changes. 1038 # moment the stamp changes.
1039 assert_file_not_contains "$al_post" '.contents { display: block; max-width: 60ch; width: 100%; min-width: 0; margin-left'
1039 # Matched on the tail rather than the whole declaration: pinning the measure
1040 # in here meant the assertion stopped guarding anything the moment the width
1041 # changed, while still passing.
1042 assert_file_not_contains "$al_post" 'width: 100%; min-width: 0; margin-left'
1040 1043
1041 it "long words cannot widen the page" 1044 it "long words cannot widen the page"
1042 # A bare URL has no spaces to wrap at; one reference link made a post 375px 1045 # A bare URL has no spaces to wrap at; one reference link made a post 375px
assert_file_not_contains "$nav_sb/.dist/plain.html" 'home-spacer'
2249 assert_file_contains "$nav_sb/.dist/plain.html" '.site-footer { display: flex; align-items: baseline;' 2252 assert_file_contains "$nav_sb/.dist/plain.html" '.site-footer { display: flex; align-items: baseline;'
2250 2253
2251 it "a sidebar widens the article rather than narrowing the body" 2254 it "a sidebar widens the article rather than narrowing the body"
2252 # 74ch is sized for a post: arrow column plus a 60ch body. Letting the sidebar
2253 # eat into it made the body 537px against a post's 540.
2254 assert_file_contains "$nav_sb/.dist/test.html" 'article:has(.page-nav-wrap) { max-width: calc(74ch'
2255 # 92ch is sized for a post: arrow column plus a 78ch body. Letting the sidebar
2256 # eat into it made the body narrower on a page than on a post -- a difference
2257 # with no cause the reader could see.
2258 assert_file_contains "$nav_sb/.dist/test.html" 'article:has(.page-nav-wrap) { max-width: calc(92ch'
2255 2259
2256 it "the body column is declared identically to a post's" 2260 it "the body column is declared identically to a post's"
2257 # The user's constraint: the body of a page should differ from the body of a 2261 # The user's constraint: the body of a page should differ from the body of a

Raw

commit e44cb737088fd89315843bd1df0a529176361e66
Author: Pat Ambrosio <cp.ambrosio@gmail.com>
Date:   Tue Sep 1 14:02:10 2026 +0800

    Widen the measure from 60 to 78 characters
    
    Measured against the MDD site rather than copied from it: its stylesheet
    says 800px, but that is General Sans at 9.30px a character where this is
    Roboto at 8.99px, so the same pixel width is not the same line. Rendered
    and measured in the browser, MDD reads at 82 characters. This takes 78 --
    a few short of it, which is what was asked for -- and comes out at 701px
    against the 540 it was.
    
    The article grows with it, 74ch to 92ch, so the stamp column keeps the
    14ch it had; measured, the gutter is unchanged at 109px.
    
    Widening surfaced a bug that was always latent. A footnote or citation
    tooltip is hidden with visibility, which keeps it in layout, and one
    centred on a marker near the right margin sat past the viewport and gave
    the page a horizontal scrollbar. It only appeared now because the wider
    body puts markers further right. The nudge that pulls a tooltip back
    inside runs when it is shown, which is too late for a scrollbar the
    reader already has, and contain: layout does not help -- an absolutely
    positioned box still reaches its scroll container. It is display: none
    while hidden now, restored by the visible class; the measurement the
    nudge depends on happens after that class is added, so it still has
    dimensions to measure.
    
    One assertion here was dead and passing. It guarded against a margin-left
    on .contents but matched the whole declaration including the measure, so
    it stopped observing anything the moment the width changed while still
    reporting green. It matches the tail now, and adding a stray margin fails
    it.

diff --git a/share/jenny/layout/page.sh b/share/jenny/layout/page.sh
index 53449df..5a026f9 100755
--- a/share/jenny/layout/page.sh
+++ b/share/jenny/layout/page.sh
@@ -503,14 +503,14 @@ cat << _EOF_
            for a narrow screen to get smaller text: the measure is already
            handled by the column width, and shrinking the type only buys
            characters per line that the reader did not ask for. */
-        article { padding: 0; margin: 1em 0; max-width: 74ch; }
-        /* 74ch is sized for a post: the arrow's column plus a 60ch body. A
+        article { padding: 0; margin: 1em 0; max-width: 92ch; }
+        /* 92ch is sized for a post: the arrow's column plus a 78ch body. A
            sidebar is an addition to that, so the article grows by exactly the
            sidebar's column and gap. Without this the sidebar ate into the
-           74ch and the body came out 537px against a post's 540 -- a
+           measure and the body came out narrower than a post's -- a
            difference with no cause the reader could see. Widening here rather
            than narrowing the body keeps the measure identical everywhere. */
-        article:has(.page-nav-wrap) { max-width: calc(74ch + var(--page-nav-width) + var(--page-nav-gap)); }
+        article:has(.page-nav-wrap) { max-width: calc(92ch + var(--page-nav-width) + var(--page-nav-gap)); }
         /* A bare URL has no spaces to wrap at, so on a narrow screen one
            long link sets the width of the whole page -- a reference to
            https://github.com/hmngwy/jenny made this post 375px wide at a
@@ -742,7 +742,11 @@ cat << _EOF_
            share its line is below the text now -- and min-width: 0 lets it
            shrink under a narrow viewport instead of setting a floor that makes
            the page scroll sideways. */
-        .contents { display: block; max-width: 60ch; width: 100%; min-width: 0; }
+        /* 78ch. Measured against the MDD site, which reads well at 82ch in
+           its own font; a few characters under that keeps a comparable line
+           without going as long. Roboto at 16px puts one character at 8.99px,
+           so this is about 700px of text. */
+        .contents { display: block; max-width: 78ch; width: 100%; min-width: 0; }
 
         /* Narrow: the sidebar has nowhere to go, so it stacks above the body
            and everything collapses to one column. Every part has to leave
@@ -1069,7 +1073,17 @@ cat << _EOF_
           box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
           z-index: 1000;
           opacity: 0;
-          visibility: hidden;
+          /* display:none while hidden, not merely visibility:hidden. A
+             hidden-but-displayed box still takes part in layout, so one
+             centred on a marker near the right margin stretched the page and
+             gave it a horizontal scrollbar -- which only showed up once the
+             body widened and the markers moved further right. The nudge that
+             pulls a tooltip back inside runs on show, too late for a
+             scrollbar the reader already has, and contain: layout does not
+             help: an absolutely positioned box still reaches its scroll
+             container. Measurement is unaffected because the box is measured
+             after .visible is added, when it has dimensions again. */
+          display: none;
           transition: none;
           margin-bottom: 0.5em;
           pointer-events: auto;
@@ -1084,6 +1098,7 @@ cat << _EOF_
         /* Show tooltip. */
         .fn-tip.visible,
         .citation-tip.visible {
+          display: block;
           opacity: 1;
           visibility: visible;
         }
diff --git a/share/jenny/layout/post.sh b/share/jenny/layout/post.sh
index 59e6308..90b6d90 100755
--- a/share/jenny/layout/post.sh
+++ b/share/jenny/layout/post.sh
@@ -385,7 +385,7 @@ cat << _EOF_
            for a narrow screen to get smaller text: the measure is already
            handled by the column width, and shrinking the type only buys
            characters per line that the reader did not ask for. */
-        article { padding: 0; margin: 1em 0; max-width: 74ch; }
+        article { padding: 0; margin: 1em 0; max-width: 92ch; }
         /* A bare URL has no spaces to wrap at, so on a narrow screen one
            long link sets the width of the whole page -- a reference to
            https://github.com/hmngwy/jenny made this post 375px wide at a
@@ -575,7 +575,11 @@ cat << _EOF_
            width. Without it a 60ch measure kept the row from ever narrowing
            past that, so at 320px the page scrolled sideways rather than the
            text reflowing. */
-        .contents { display: block; max-width: 60ch; width: 100%; min-width: 0; }
+        /* 78ch. Measured against the MDD site, which reads well at 82ch in
+           its own font; a few characters under that keeps a comparable line
+           without going as long. Roboto at 16px puts one character at 8.99px,
+           so this is about 700px of text. */
+        .contents { display: block; max-width: 78ch; width: 100%; min-width: 0; }
         .body-row { min-width: 0; }
 
         /* On a phone the stamp column is a quarter of the screen held open for
@@ -890,7 +894,17 @@ cat << _EOF_
           box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
           z-index: 1000;
           opacity: 0;
-          visibility: hidden;
+          /* display:none while hidden, not merely visibility:hidden. A
+             hidden-but-displayed box still takes part in layout, so one
+             centred on a marker near the right margin stretched the page and
+             gave it a horizontal scrollbar -- which only showed up once the
+             body widened and the markers moved further right. The nudge that
+             pulls a tooltip back inside runs on show, too late for a
+             scrollbar the reader already has, and contain: layout does not
+             help: an absolutely positioned box still reaches its scroll
+             container. Measurement is unaffected because the box is measured
+             after .visible is added, when it has dimensions again. */
+          display: none;
           transition: none;
           margin-bottom: 0.5em;
           pointer-events: auto;
@@ -905,6 +919,7 @@ cat << _EOF_
         /* Show tooltip. */
         .fn-tip.visible,
         .citation-tip.visible {
+          display: block;
           opacity: 1;
           visibility: visible;
         }
diff --git a/test/regressions.sh b/test/regressions.sh
index 131759f..2648ca9 100755
--- a/test/regressions.sh
+++ b/test/regressions.sh
@@ -1036,7 +1036,10 @@ assert_file_contains "$al/.dist/index.html" 'width: 2.25em'
 it "the body is not indented by a second mechanism"
 # A margin on .contents would be another copy of the column, drifting the
 # moment the stamp changes.
-assert_file_not_contains "$al_post" '.contents { display: block; max-width: 60ch; width: 100%; min-width: 0; margin-left'
+# Matched on the tail rather than the whole declaration: pinning the measure
+# in here meant the assertion stopped guarding anything the moment the width
+# changed, while still passing.
+assert_file_not_contains "$al_post" 'width: 100%; min-width: 0; margin-left'
 
 it "long words cannot widen the page"
 # A bare URL has no spaces to wrap at; one reference link made a post 375px
@@ -2249,9 +2252,10 @@ assert_file_not_contains "$nav_sb/.dist/plain.html" 'home-spacer'
 assert_file_contains "$nav_sb/.dist/plain.html" '.site-footer { display: flex; align-items: baseline;'
 
 it "a sidebar widens the article rather than narrowing the body"
-# 74ch is sized for a post: arrow column plus a 60ch body. Letting the sidebar
-# eat into it made the body 537px against a post's 540.
-assert_file_contains "$nav_sb/.dist/test.html" 'article:has(.page-nav-wrap) { max-width: calc(74ch'
+# 92ch is sized for a post: arrow column plus a 78ch body. Letting the sidebar
+# eat into it made the body narrower on a page than on a post -- a difference
+# with no cause the reader could see.
+assert_file_contains "$nav_sb/.dist/test.html" 'article:has(.page-nav-wrap) { max-width: calc(92ch'
 
 it "the body column is declared identically to a post's"
 # The user's constraint: the body of a page should differ from the body of a