Skip to content

Commit b47d2c1

Browse files
A divider stops at its box's sides in HTML (#54)
.ms-divider reached 1ch past each side of its box whatever the box's padding, so a divider in a box padded 0 ran past the border. It now reaches across --ms-pad, and each box sets --ms-pad itself so a nested box does not inherit its parent's. Claude-Session: https://claude.ai/code/session_018zYSohsQvDRVmjizSfxGWi Co-authored-by: Claude <noreply@anthropic.com>
1 parent b43ceaf commit b47d2c1

3 files changed

Lines changed: 24 additions & 4 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5252

5353
### Fixed
5454

55+
- **A divider stops at its box's sides in HTML.** `.ms-divider` reached 1ch past each side of its box
56+
whatever the box's padding, so in a box padded 0 (`--ms-pad:0ch`) every divider ran past the border.
57+
It now reaches across `--ms-pad`, and not at all in a borderless box. Each box sets `--ms-pad: 1ch`
58+
itself, so a box inside one padded 0 is no longer padded 0 too.
5559
- **A box round a picture spans the width in a terminal again.** 2.14.2 fitted a box holding only a
5660
picture to the picture, so in a scene log it stood narrower than every box and rule around it. It is
5761
drawn across the width again, with its padding, and the picture at its left. HTML still fits it

‎MarkupString.Html/LayoutCss.cs‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ namespace MarkupString.Html;
1111
/// second row of a striped table or list (a faint grey when unset). A page
1212
/// sets these to theme every layout on it; a layout's own theme sets them on its block, and a game's
1313
/// default theme sets the <c>-default</c> form of each, under what the page sets.
14-
/// A box's padding is <c>--ms-pad</c> (<c>1ch</c> unset), set on the box when its own differs.
14+
/// A box's padding is <c>--ms-pad</c>, <c>1ch</c> unless the box sets its own; a divider in the box reaches
15+
/// across that padding to the box's sides.
1516
/// Everything is sized in <c>ch</c>, the width of a cell in the terminal font the layout was laid out
1617
/// in, and every row wraps, so nothing scrolls sideways on a narrow page.
1718
/// </remarks>
@@ -21,7 +22,7 @@ public static class LayoutCss
2122
public static readonly string Fixed =
2223
".ms-layout { display: block; max-width: 100%; white-space: normal; }\n" +
2324
".ms-text { white-space: pre-wrap; overflow-wrap: anywhere; }\n" +
24-
".ms-box { margin: 0; padding: 0 var(--ms-pad, 1ch); min-width: 0; border: 1px solid var(--ms-border, var(--ms-border-default, currentColor)); }\n" +
25+
".ms-box { --ms-pad: 1ch; margin: 0; padding: 0 var(--ms-pad); min-width: 0; border: 1px solid var(--ms-border, var(--ms-border-default, currentColor)); }\n" +
2526
".ms-box.ms-border-none { border: none; padding: 0; }\n" +
2627
".ms-box.ms-border-double { border: 3px double var(--ms-border, var(--ms-border-default, currentColor)); }\n" +
2728
".ms-box.ms-border-heavy { border-width: 2px; }\n" +
@@ -34,7 +35,8 @@ public static class LayoutCss
3435
".ms-rule::before, .ms-rule::after, .ms-divider::before, .ms-divider::after { content: \"\"; flex: 1 1 0; border-top: 1px solid var(--ms-border, var(--ms-border-default, currentColor)); }\n" +
3536
".ms-rule[data-align=\"left\"]::before, .ms-divider[data-align=\"left\"]::before { flex: 0 0 1ch; }\n" +
3637
".ms-rule[data-align=\"right\"]::after, .ms-divider[data-align=\"right\"]::after { flex: 0 0 1ch; }\n" +
37-
".ms-divider { margin: 0 -1ch; }\n" +
38+
".ms-divider { margin: 0 calc(-1 * var(--ms-pad, 1ch)); }\n" +
39+
".ms-box.ms-border-none > .ms-divider { margin: 0; }\n" +
3840
".ms-border-double.ms-rule::before, .ms-border-double.ms-rule::after { border-top: 3px double var(--ms-border, var(--ms-border-default, currentColor)); }\n" +
3941
".ms-border-none.ms-rule::before, .ms-border-none.ms-rule::after { border-top: none; }\n" +
4042
".ms-flex { display: flex; flex-wrap: wrap; }\n" +

‎MarkupString.Tests/Layout/BlockLayoutTests.cs‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,21 @@ public async Task Figure_AloneInABox_TheBoxFitsThePicture()
324324
// The picture sits on the top of its line rather than its baseline, so no gap for descenders is left under it.
325325
await Assert.That(LayoutCss.Fixed).Contains(".ms-figure-image { max-width: 100%; height: auto; vertical-align: top; }");
326326
await Assert.That(LayoutCss.Fixed).Contains(".ms-box.ms-box-picture { padding: 0; width: fit-content; max-width: 100%; box-sizing: border-box; }");
327-
await Assert.That(LayoutCss.Fixed).Contains(".ms-box { margin: 0; padding: 0 var(--ms-pad, 1ch);");
327+
await Assert.That(LayoutCss.Fixed).Contains(".ms-box { --ms-pad: 1ch; margin: 0; padding: 0 var(--ms-pad);");
328+
}
329+
330+
[Test]
331+
public async Task Divider_InABoxWithoutPadding_ReachesOnlyToItsSides()
332+
{
333+
var tight = BlockLayout.Build(new Frame(new Stack([T("Above"), new Rule(), T("Below")])) { Padding = 0 }, 30).Render(MarkupFormat.Html, Registry);
334+
335+
await Assert.That(tight).Contains("<fieldset class=\"ms-box ms-border-single\" style=\"--ms-pad:0ch\">");
336+
await Assert.That(tight).Contains("<div class=\"ms-divider ms-border-single\" role=\"separator\"></div>");
337+
// A divider stretches across its box's padding, not a fixed 1ch, so it stops at the sides of a box padded 0.
338+
await Assert.That(LayoutCss.Fixed).Contains(".ms-divider { margin: 0 calc(-1 * var(--ms-pad, 1ch)); }");
339+
await Assert.That(LayoutCss.Fixed).Contains(".ms-box.ms-border-none > .ms-divider { margin: 0; }");
340+
// Each box sets its own padding, so a box inside one padded 0 is padded 1ch again.
341+
await Assert.That(LayoutCss.Fixed).Contains(".ms-box { --ms-pad: 1ch;");
328342
}
329343

330344
[Test]

0 commit comments

Comments
 (0)