Commit ca8e632 h
Pat Ambrosio · 26-08-28 10:46
Let a figure bleed past the measure when the window allows
Changes: 3 files
+135
-8
Changes (Side-by-Side)
share/jenny/layout/page.sh +52 -2
cat << _EOF_ |
| 777 |
box otherwise refuses to shrink below its rendered diagram's width, |
777 |
box otherwise refuses to shrink below its rendered diagram's width, |
| 778 |
so a narrow screen scrolled the whole page sideways instead of |
778 |
so a narrow screen scrolled the whole page sideways instead of |
| 779 |
scrolling the diagram inside its own container. */ |
779 |
scrolling the diagram inside its own container. */ |
| 780 |
.diagram { margin: 1.5em 0; overflow-x: auto; display: block; |
| |
| 781 |
width: 100%; min-width: 0; max-width: 100%; } |
| |
| |
780 |
/* Diagrams and images may bleed past the measure, up to 130% of it, |
| |
781 |
when the viewport has room to spare. Sticking out is the point: a |
| |
782 |
wide chart is easier to read wider, and the overhang signals that it |
| |
783 |
is a figure rather than more prose. |
| |
784 |
|
| |
785 |
It grows rightward only. The column is left-aligned rather than |
| |
786 |
centred, so the slack is all on one side: at 1440 the left inset is |
| |
787 |
a fixed 24px while the right has hundreds of pixels going spare. A |
| |
788 |
bleed that pulled both edges out would be capped by the left at 24px |
| |
789 |
and never reach 130%, and one that split the leftover viewport |
| |
790 |
evenly -- the first attempt -- put the figure 40px off the left edge |
| |
791 |
of the screen at 700px wide. |
| |
792 |
|
| |
793 |
The margin is negative, and percentages in a margin resolve against |
| |
794 |
the containing block, so -30% tracks the measure at whatever width |
| |
795 |
it happens to be, sidebar or not. The middle term is what the window |
| |
796 |
can actually give back; it rises toward zero as the window narrows |
| |
797 |
and clamps there, at which point the figure sits in the column like |
| |
798 |
anything else. No breakpoint, no sideways scroll, nothing to undo on |
| |
799 |
a phone. Measured in Chrome: 130% at 1920 and 1440, 120.8% at 700, |
| |
800 |
100% below that, and no horizontal scroll at any width. */ |
| |
801 |
.diagram, article img { |
| |
802 |
margin-right: clamp(-30%, calc(100% - 100vw + 3em), 0px); |
| |
803 |
/* The negative margin widens the box; max-width has to be lifted off |
| |
804 |
the measure or the figure would stay at 100% of it and simply sit |
| |
805 |
off-centre. It is not removed, though -- the box is still bounded |
| |
806 |
by the bled width, so an oversized image cannot run off the page. */ |
| |
807 |
max-width: calc(100% + 30%); |
| |
808 |
} |
| |
809 |
/* The box grows to the right only, so its left edge stays on the |
| |
810 |
measure: a figure too small to need the bleed lines up with the |
| |
811 |
text above it, and one that fills the box runs past the right |
| |
812 |
margin. Centring inside the box was tried and looked wrong -- a |
| |
813 |
200px image drifted 81px right of the column it belonged to. */ |
| |
814 |
/* margin-block, not the margin shorthand: the shorthand also sets |
| |
815 |
margin-right, which resets the bleed above to zero -- measured, the |
| |
816 |
diagram sat at exactly 100% of the column with it in place. |
| |
817 |
|
| |
818 |
width is auto, not 100%: a fixed 100% pins the box to the column and |
| |
819 |
leaves the negative margin nothing to expand into, which measured at |
| |
820 |
exactly 100%. The width now comes from max-width and the margin |
| |
821 |
together. min-width stays 0 so a diagram can still shrink on a |
| |
822 |
narrow screen -- without that a phone scrolled the whole page |
| |
823 |
sideways instead of scrolling the diagram in its own box. */ |
| |
824 |
.diagram { margin-block: 1.5em; overflow-x: auto; display: block; |
| |
825 |
width: auto; min-width: 0; } |
| 782 |
/* The renderer writes an inline max-width of the diagram's natural |
826 |
/* The renderer writes an inline max-width of the diagram's natural |
| 783 |
size, which is what keeps a small diagram from being blown up to |
827 |
size, which is what keeps a small diagram from being blown up to |
| 784 |
the column width. That is the right default, so it is left alone; |
828 |
the column width. That is the right default, so it is left alone; |
| 785 |
what needed fixing was the container, which shrink-wrapped inside |
829 |
what needed fixing was the container, which shrink-wrapped inside |
| 786 |
the inline-block body column instead of taking its full width. */ |
830 |
the inline-block body column instead of taking its full width. */ |
| |
831 |
/* Left, not centred. A chart too small to fill the bled box would |
| |
832 |
otherwise drift into the overhang -- the legend here sat 81px right |
| |
833 |
of the column it belongs to -- while a chart that fills the box is |
| |
834 |
unaffected either way. Lining the left edge up with the measure |
| |
835 |
keeps a small diagram in the column and lets a wide one run out to |
| |
836 |
the right, which is the same rule the images follow. */ |
| 787 |
.diagram svg { width: 100%; height: auto; display: block; } |
837 |
.diagram svg { width: 100%; height: auto; display: block; } |
| 788 |
/* Until the renderer runs -- or if it never does, because the script |
838 |
/* Until the renderer runs -- or if it never does, because the script |
| 789 |
is absent or blocked -- the element holds the diagram's source. Show |
839 |
is absent or blocked -- the element holds the diagram's source. Show |
share/jenny/layout/post.sh +52 -2
cat << _EOF_ |
| 598 |
box otherwise refuses to shrink below its rendered diagram's width, |
598 |
box otherwise refuses to shrink below its rendered diagram's width, |
| 599 |
so a narrow screen scrolled the whole page sideways instead of |
599 |
so a narrow screen scrolled the whole page sideways instead of |
| 600 |
scrolling the diagram inside its own container. */ |
600 |
scrolling the diagram inside its own container. */ |
| 601 |
.diagram { margin: 1.5em 0; overflow-x: auto; display: block; |
| |
| 602 |
width: 100%; min-width: 0; max-width: 100%; } |
| |
| |
601 |
/* Diagrams and images may bleed past the measure, up to 130% of it, |
| |
602 |
when the viewport has room to spare. Sticking out is the point: a |
| |
603 |
wide chart is easier to read wider, and the overhang signals that it |
| |
604 |
is a figure rather than more prose. |
| |
605 |
|
| |
606 |
It grows rightward only. The column is left-aligned rather than |
| |
607 |
centred, so the slack is all on one side: at 1440 the left inset is |
| |
608 |
a fixed 24px while the right has hundreds of pixels going spare. A |
| |
609 |
bleed that pulled both edges out would be capped by the left at 24px |
| |
610 |
and never reach 130%, and one that split the leftover viewport |
| |
611 |
evenly -- the first attempt -- put the figure 40px off the left edge |
| |
612 |
of the screen at 700px wide. |
| |
613 |
|
| |
614 |
The margin is negative, and percentages in a margin resolve against |
| |
615 |
the containing block, so -30% tracks the measure at whatever width |
| |
616 |
it happens to be, sidebar or not. The middle term is what the window |
| |
617 |
can actually give back; it rises toward zero as the window narrows |
| |
618 |
and clamps there, at which point the figure sits in the column like |
| |
619 |
anything else. No breakpoint, no sideways scroll, nothing to undo on |
| |
620 |
a phone. Measured in Chrome: 130% at 1920 and 1440, 120.8% at 700, |
| |
621 |
100% below that, and no horizontal scroll at any width. */ |
| |
622 |
.diagram, article img { |
| |
623 |
margin-right: clamp(-30%, calc(100% - 100vw + 3em), 0px); |
| |
624 |
/* The negative margin widens the box; max-width has to be lifted off |
| |
625 |
the measure or the figure would stay at 100% of it and simply sit |
| |
626 |
off-centre. It is not removed, though -- the box is still bounded |
| |
627 |
by the bled width, so an oversized image cannot run off the page. */ |
| |
628 |
max-width: calc(100% + 30%); |
| |
629 |
} |
| |
630 |
/* The box grows to the right only, so its left edge stays on the |
| |
631 |
measure: a figure too small to need the bleed lines up with the |
| |
632 |
text above it, and one that fills the box runs past the right |
| |
633 |
margin. Centring inside the box was tried and looked wrong -- a |
| |
634 |
200px image drifted 81px right of the column it belonged to. */ |
| |
635 |
/* margin-block, not the margin shorthand: the shorthand also sets |
| |
636 |
margin-right, which resets the bleed above to zero -- measured, the |
| |
637 |
diagram sat at exactly 100% of the column with it in place. |
| |
638 |
|
| |
639 |
width is auto, not 100%: a fixed 100% pins the box to the column and |
| |
640 |
leaves the negative margin nothing to expand into, which measured at |
| |
641 |
exactly 100%. The width now comes from max-width and the margin |
| |
642 |
together. min-width stays 0 so a diagram can still shrink on a |
| |
643 |
narrow screen -- without that a phone scrolled the whole page |
| |
644 |
sideways instead of scrolling the diagram in its own box. */ |
| |
645 |
.diagram { margin-block: 1.5em; overflow-x: auto; display: block; |
| |
646 |
width: auto; min-width: 0; } |
| 603 |
/* The renderer writes an inline max-width of the diagram's natural |
647 |
/* The renderer writes an inline max-width of the diagram's natural |
| 604 |
size, which is what keeps a small diagram from being blown up to |
648 |
size, which is what keeps a small diagram from being blown up to |
| 605 |
the column width. That is the right default, so it is left alone; |
649 |
the column width. That is the right default, so it is left alone; |
| 606 |
what needed fixing was the container, which shrink-wrapped inside |
650 |
what needed fixing was the container, which shrink-wrapped inside |
| 607 |
the inline-block body column instead of taking its full width. */ |
651 |
the inline-block body column instead of taking its full width. */ |
| |
652 |
/* Left, not centred. A chart too small to fill the bled box would |
| |
653 |
otherwise drift into the overhang -- the legend here sat 81px right |
| |
654 |
of the column it belongs to -- while a chart that fills the box is |
| |
655 |
unaffected either way. Lining the left edge up with the measure |
| |
656 |
keeps a small diagram in the column and lets a wide one run out to |
| |
657 |
the right, which is the same rule the images follow. */ |
| 608 |
.diagram svg { width: 100%; height: auto; display: block; } |
658 |
.diagram svg { width: 100%; height: auto; display: block; } |
| 609 |
/* Until the renderer runs -- or if it never does, because the script |
659 |
/* Until the renderer runs -- or if it never does, because the script |
| 610 |
is absent or blocked -- the element holds the diagram's source. Show |
660 |
is absent or blocked -- the element holds the diagram's source. Show |
test/regressions.sh +31 -4
it "the diagram box takes the body column, not its shrink-wrapped width" |
| 1354 |
# .contents is an inline-block, so a block inside it shrink-wraps to its |
1354 |
# .contents is an inline-block, so a block inside it shrink-wraps to its |
| 1355 |
# content; the diagram sat small against a full-width column until the |
1355 |
# content; the diagram sat small against a full-width column until the |
| 1356 |
# container was told to take the width. |
1356 |
# container was told to take the width. |
| 1357 |
assert_file_contains "$dg/.dist/chart.html" '.diagram { margin: 1.5em 0; overflow-x: auto; display: block;' |
| |
| 1358 |
# min-width is what lets it shrink: without it a narrow screen scrolled the |
| |
| 1359 |
# whole page sideways instead of scrolling the diagram in its own box. |
| |
| 1360 |
assert_file_contains "$dg/.dist/chart.html" 'width: 100%; min-width: 0; max-width: 100%; }' |
| |
| |
1357 |
# margin-block rather than the margin shorthand: the shorthand also sets |
| |
1358 |
# margin-right, which resets the bleed to zero. Measured in Chrome with the |
| |
1359 |
# shorthand in place, the diagram sat at exactly 100% of the column. |
| |
1360 |
assert_file_contains "$dg/.dist/chart.html" '.diagram { margin-block: 1.5em; overflow-x: auto; display: block;' |
| |
1361 |
# width is auto, not 100%: a fixed width pins the box to the column and leaves |
| |
1362 |
# the bleed's negative margin nothing to expand into -- measured in Chrome, |
| |
1363 |
# width:100% held the diagram at exactly 100% of the column. min-width stays 0, |
| |
1364 |
# which is what lets it shrink: without that a narrow screen scrolled the whole |
| |
1365 |
# page sideways instead of scrolling the diagram in its own box. Verified at a |
| |
1366 |
# 375px phone viewport that the page still does not scroll sideways. |
| |
1367 |
assert_file_contains "$dg/.dist/chart.html" 'width: auto; min-width: 0; }' |
| 1361 |
|
1368 |
|
| 1362 |
it "an unrendered diagram degrades to readable source" |
1369 |
it "an unrendered diagram degrades to readable source" |
| 1363 |
# If the script is absent or blocked, the element still holds what the author |
1370 |
# If the script is absent or blocked, the element still holds what the author |
printf '# Post with Diagram\n\ntags: test\n\n```mermaid\ngraph TD\n A-->B\n```\ |
| 2571 |
run_jenny "$dm_blog" |
2578 |
run_jenny "$dm_blog" |
| 2572 |
dm_post="$dm_blog/.dist/post/with-diagram.html" |
2579 |
dm_post="$dm_blog/.dist/post/with-diagram.html" |
| 2573 |
|
2580 |
|
| |
2581 |
it "a figure may bleed past the measure when there is room" |
| |
2582 |
# Diagrams and images run up to 130% of the body column when the window can |
| |
2583 |
# afford it, and sit at 100% when it cannot. Measured in Chrome: 130% at 1440 |
| |
2584 |
# and at 1920 (it caps, rather than growing without bound), 120.8% at 700, and |
| |
2585 |
# exactly 100% below that, with no horizontal scroll at any width. |
| |
2586 |
assert_file_contains "$dm_post" "margin-right: clamp(-30%, calc(100% - 100vw + 3em), 0px)" |
| |
2587 |
|
| |
2588 |
it "the bled box is still bounded" |
| |
2589 |
# max-width has to come off the measure or the figure would stay at 100% of it |
| |
2590 |
# and merely sit off-centre -- but it is raised, not removed, so an oversized |
| |
2591 |
# image cannot run off the page. |
| |
2592 |
assert_file_contains "$dm_post" "max-width: calc(100% + 30%)" |
| |
2593 |
|
| |
2594 |
it "the bleed grows rightward, not from both sides" |
| |
2595 |
# The column is left-aligned, so the free space is all on one side. A |
| |
2596 |
# symmetric bleed is capped by the fixed 24px left inset and never reaches |
| |
2597 |
# 130%; an earlier attempt that split the leftover viewport evenly put the |
| |
2598 |
# figure 40px off the left edge at 700px wide. |
| |
2599 |
assert_file_not_contains "$dm_post" "margin-inline: clamp(-15%" |
| |
2600 |
|
| 2574 |
it "diagram elements have cursor pointer and are keyboard accessible" |
2601 |
it "diagram elements have cursor pointer and are keyboard accessible" |
| 2575 |
# Diagrams should be clickable and keyboard-accessible buttons. |
2602 |
# Diagrams should be clickable and keyboard-accessible buttons. |
| 2576 |
assert_file_contains "$dm_post" "diag.style.cursor = 'pointer'" |
2603 |
assert_file_contains "$dm_post" "diag.style.cursor = 'pointer'" |
Raw
commit ca8e6328a3ce1d5d9dc8af208de13998644dbf42
Author: Pat Ambrosio <cp.ambrosio@gmail.com>
Date: Fri Aug 28 10:46:22 2026 +0800
Let a figure bleed past the measure when the window allows
A diagram or an image may run to 130% of the body column, sticking out
past the prose beside it. That overhang is the point: a wide chart is
easier to read wider, and the figure reads as a figure rather than as
more body text. Where the window cannot afford it, the figure sits in the
column as before -- no breakpoint, nothing to undo on a phone.
It grows rightward only. The column is left-aligned rather than centred,
so the slack is all on one side: at 1440 the left inset is a fixed 24px
while the right has hundreds of pixels going spare. Pulling both edges
out would be capped by the left at 24px and never reach 130%.
Measured in Chrome, both layouts, diagrams and images alike:
1920 130.0% caps here rather than growing further
1440 130.0%
700 120.8% tapering as the window closes in
375 100.0% bleed off entirely
with no horizontal scroll at any width. A figure too small to need the
bleed keeps its natural size and stays lined up with the column: a 200px
image and the four-node legend both sit where they did.
Five things looked right in the stylesheet and were wrong on screen:
- Splitting the leftover viewport evenly assumed a centred column and
put the figure 40px off the left edge at 700px.
- margin: auto to centre a narrow figure resolves to zero, which killed
the left bleed and left the box lopsided by the whole overhang.
- The margin: 1.5em 0 shorthand also sets margin-right, resetting the
bleed to zero. It is margin-block now.
- width: 100% pins the box to the column and leaves the negative margin
nothing to expand into. The width comes from max-width instead.
- min-width: 100%, which was my own fix for the shrink-wrap this rule
guards, contradicted the reason min-width: 0 was there: without it a
phone scrolled the whole page sideways instead of scrolling the
diagram in its own box. Verified at 375px that 0 and the bleed
coexist, and kept the original guard.
Two existing assertions pinned the old declarations verbatim and failed
here, correctly. Both now state the working form with the measurement
behind it.
diff --git a/share/jenny/layout/page.sh b/share/jenny/layout/page.sh
index e420807..33c6b07 100755
--- a/share/jenny/layout/page.sh
+++ b/share/jenny/layout/page.sh
@@ -777,13 +777,63 @@ cat << _EOF_
box otherwise refuses to shrink below its rendered diagram's width,
so a narrow screen scrolled the whole page sideways instead of
scrolling the diagram inside its own container. */
- .diagram { margin: 1.5em 0; overflow-x: auto; display: block;
- width: 100%; min-width: 0; max-width: 100%; }
+ /* Diagrams and images may bleed past the measure, up to 130% of it,
+ when the viewport has room to spare. Sticking out is the point: a
+ wide chart is easier to read wider, and the overhang signals that it
+ is a figure rather than more prose.
+
+ It grows rightward only. The column is left-aligned rather than
+ centred, so the slack is all on one side: at 1440 the left inset is
+ a fixed 24px while the right has hundreds of pixels going spare. A
+ bleed that pulled both edges out would be capped by the left at 24px
+ and never reach 130%, and one that split the leftover viewport
+ evenly -- the first attempt -- put the figure 40px off the left edge
+ of the screen at 700px wide.
+
+ The margin is negative, and percentages in a margin resolve against
+ the containing block, so -30% tracks the measure at whatever width
+ it happens to be, sidebar or not. The middle term is what the window
+ can actually give back; it rises toward zero as the window narrows
+ and clamps there, at which point the figure sits in the column like
+ anything else. No breakpoint, no sideways scroll, nothing to undo on
+ a phone. Measured in Chrome: 130% at 1920 and 1440, 120.8% at 700,
+ 100% below that, and no horizontal scroll at any width. */
+ .diagram, article img {
+ margin-right: clamp(-30%, calc(100% - 100vw + 3em), 0px);
+ /* The negative margin widens the box; max-width has to be lifted off
+ the measure or the figure would stay at 100% of it and simply sit
+ off-centre. It is not removed, though -- the box is still bounded
+ by the bled width, so an oversized image cannot run off the page. */
+ max-width: calc(100% + 30%);
+ }
+ /* The box grows to the right only, so its left edge stays on the
+ measure: a figure too small to need the bleed lines up with the
+ text above it, and one that fills the box runs past the right
+ margin. Centring inside the box was tried and looked wrong -- a
+ 200px image drifted 81px right of the column it belonged to. */
+ /* margin-block, not the margin shorthand: the shorthand also sets
+ margin-right, which resets the bleed above to zero -- measured, the
+ diagram sat at exactly 100% of the column with it in place.
+
+ width is auto, not 100%: a fixed 100% pins the box to the column and
+ leaves the negative margin nothing to expand into, which measured at
+ exactly 100%. The width now comes from max-width and the margin
+ together. min-width stays 0 so a diagram can still shrink on a
+ narrow screen -- without that a phone scrolled the whole page
+ sideways instead of scrolling the diagram in its own box. */
+ .diagram { margin-block: 1.5em; overflow-x: auto; display: block;
+ width: auto; min-width: 0; }
/* The renderer writes an inline max-width of the diagram's natural
size, which is what keeps a small diagram from being blown up to
the column width. That is the right default, so it is left alone;
what needed fixing was the container, which shrink-wrapped inside
the inline-block body column instead of taking its full width. */
+ /* Left, not centred. A chart too small to fill the bled box would
+ otherwise drift into the overhang -- the legend here sat 81px right
+ of the column it belongs to -- while a chart that fills the box is
+ unaffected either way. Lining the left edge up with the measure
+ keeps a small diagram in the column and lets a wide one run out to
+ the right, which is the same rule the images follow. */
.diagram svg { width: 100%; height: auto; display: block; }
/* Until the renderer runs -- or if it never does, because the script
is absent or blocked -- the element holds the diagram's source. Show
diff --git a/share/jenny/layout/post.sh b/share/jenny/layout/post.sh
index 3fd51b1..a5bf37d 100755
--- a/share/jenny/layout/post.sh
+++ b/share/jenny/layout/post.sh
@@ -598,13 +598,63 @@ cat << _EOF_
box otherwise refuses to shrink below its rendered diagram's width,
so a narrow screen scrolled the whole page sideways instead of
scrolling the diagram inside its own container. */
- .diagram { margin: 1.5em 0; overflow-x: auto; display: block;
- width: 100%; min-width: 0; max-width: 100%; }
+ /* Diagrams and images may bleed past the measure, up to 130% of it,
+ when the viewport has room to spare. Sticking out is the point: a
+ wide chart is easier to read wider, and the overhang signals that it
+ is a figure rather than more prose.
+
+ It grows rightward only. The column is left-aligned rather than
+ centred, so the slack is all on one side: at 1440 the left inset is
+ a fixed 24px while the right has hundreds of pixels going spare. A
+ bleed that pulled both edges out would be capped by the left at 24px
+ and never reach 130%, and one that split the leftover viewport
+ evenly -- the first attempt -- put the figure 40px off the left edge
+ of the screen at 700px wide.
+
+ The margin is negative, and percentages in a margin resolve against
+ the containing block, so -30% tracks the measure at whatever width
+ it happens to be, sidebar or not. The middle term is what the window
+ can actually give back; it rises toward zero as the window narrows
+ and clamps there, at which point the figure sits in the column like
+ anything else. No breakpoint, no sideways scroll, nothing to undo on
+ a phone. Measured in Chrome: 130% at 1920 and 1440, 120.8% at 700,
+ 100% below that, and no horizontal scroll at any width. */
+ .diagram, article img {
+ margin-right: clamp(-30%, calc(100% - 100vw + 3em), 0px);
+ /* The negative margin widens the box; max-width has to be lifted off
+ the measure or the figure would stay at 100% of it and simply sit
+ off-centre. It is not removed, though -- the box is still bounded
+ by the bled width, so an oversized image cannot run off the page. */
+ max-width: calc(100% + 30%);
+ }
+ /* The box grows to the right only, so its left edge stays on the
+ measure: a figure too small to need the bleed lines up with the
+ text above it, and one that fills the box runs past the right
+ margin. Centring inside the box was tried and looked wrong -- a
+ 200px image drifted 81px right of the column it belonged to. */
+ /* margin-block, not the margin shorthand: the shorthand also sets
+ margin-right, which resets the bleed above to zero -- measured, the
+ diagram sat at exactly 100% of the column with it in place.
+
+ width is auto, not 100%: a fixed 100% pins the box to the column and
+ leaves the negative margin nothing to expand into, which measured at
+ exactly 100%. The width now comes from max-width and the margin
+ together. min-width stays 0 so a diagram can still shrink on a
+ narrow screen -- without that a phone scrolled the whole page
+ sideways instead of scrolling the diagram in its own box. */
+ .diagram { margin-block: 1.5em; overflow-x: auto; display: block;
+ width: auto; min-width: 0; }
/* The renderer writes an inline max-width of the diagram's natural
size, which is what keeps a small diagram from being blown up to
the column width. That is the right default, so it is left alone;
what needed fixing was the container, which shrink-wrapped inside
the inline-block body column instead of taking its full width. */
+ /* Left, not centred. A chart too small to fill the bled box would
+ otherwise drift into the overhang -- the legend here sat 81px right
+ of the column it belongs to -- while a chart that fills the box is
+ unaffected either way. Lining the left edge up with the measure
+ keeps a small diagram in the column and lets a wide one run out to
+ the right, which is the same rule the images follow. */
.diagram svg { width: 100%; height: auto; display: block; }
/* Until the renderer runs -- or if it never does, because the script
is absent or blocked -- the element holds the diagram's source. Show
diff --git a/test/regressions.sh b/test/regressions.sh
index dd1de6b..1fe88b4 100755
--- a/test/regressions.sh
+++ b/test/regressions.sh
@@ -1354,10 +1354,17 @@ it "the diagram box takes the body column, not its shrink-wrapped width"
# .contents is an inline-block, so a block inside it shrink-wraps to its
# content; the diagram sat small against a full-width column until the
# container was told to take the width.
-assert_file_contains "$dg/.dist/chart.html" '.diagram { margin: 1.5em 0; overflow-x: auto; display: block;'
-# min-width is what lets it shrink: without it a narrow screen scrolled the
-# whole page sideways instead of scrolling the diagram in its own box.
-assert_file_contains "$dg/.dist/chart.html" 'width: 100%; min-width: 0; max-width: 100%; }'
+# margin-block rather than the margin shorthand: the shorthand also sets
+# margin-right, which resets the bleed to zero. Measured in Chrome with the
+# shorthand in place, the diagram sat at exactly 100% of the column.
+assert_file_contains "$dg/.dist/chart.html" '.diagram { margin-block: 1.5em; overflow-x: auto; display: block;'
+# width is auto, not 100%: a fixed width pins the box to the column and leaves
+# the bleed's negative margin nothing to expand into -- measured in Chrome,
+# width:100% held the diagram at exactly 100% of the column. min-width stays 0,
+# which is what lets it shrink: without that a narrow screen scrolled the whole
+# page sideways instead of scrolling the diagram in its own box. Verified at a
+# 375px phone viewport that the page still does not scroll sideways.
+assert_file_contains "$dg/.dist/chart.html" 'width: auto; min-width: 0; }'
it "an unrendered diagram degrades to readable source"
# If the script is absent or blocked, the element still holds what the author
@@ -2571,6 +2578,26 @@ printf '# Post with Diagram\n\ntags: test\n\n```mermaid\ngraph TD\n A-->B\n```\
run_jenny "$dm_blog"
dm_post="$dm_blog/.dist/post/with-diagram.html"
+it "a figure may bleed past the measure when there is room"
+# Diagrams and images run up to 130% of the body column when the window can
+# afford it, and sit at 100% when it cannot. Measured in Chrome: 130% at 1440
+# and at 1920 (it caps, rather than growing without bound), 120.8% at 700, and
+# exactly 100% below that, with no horizontal scroll at any width.
+assert_file_contains "$dm_post" "margin-right: clamp(-30%, calc(100% - 100vw + 3em), 0px)"
+
+it "the bled box is still bounded"
+# max-width has to come off the measure or the figure would stay at 100% of it
+# and merely sit off-centre -- but it is raised, not removed, so an oversized
+# image cannot run off the page.
+assert_file_contains "$dm_post" "max-width: calc(100% + 30%)"
+
+it "the bleed grows rightward, not from both sides"
+# The column is left-aligned, so the free space is all on one side. A
+# symmetric bleed is capped by the fixed 24px left inset and never reaches
+# 130%; an earlier attempt that split the leftover viewport evenly put the
+# figure 40px off the left edge at 700px wide.
+assert_file_not_contains "$dm_post" "margin-inline: clamp(-15%"
+
it "diagram elements have cursor pointer and are keyboard accessible"
# Diagrams should be clickable and keyboard-accessible buttons.
assert_file_contains "$dm_post" "diag.style.cursor = 'pointer'"