render: percentage padding, box-shadow, external-sprite svg, gradient text

percentage padding/margin: top/bottom percentages resolve against the
containing-block width (the responsive aspect-ratio-box trick, e.g.
padding-top:56.25%), resolved to px in the top-down layout pass so card
media boxes reserve space instead of collapsing.
box-shadow: parse and paint an outset shadow (rounded, offset, spread,
soft-edge approximation) so cards/buttons/menus have depth.
external-sprite svg: resolve <use href="url#id"> to an external sprite
file, inject the referenced symbol so inline-svg icon systems rasterize.
background-clip:text: paint transparent-with-gradient text (the common
gradient hero/button label) instead of leaving it invisible.
This commit is contained in:
SGavrl committed 2026-07-11 21:02:57 +00:00
1 parent 58dee6330e
commit 23594b1f96
6 files changed
+954 -24

No files matched your search

@@ -101,6 +101,27 @@ fn relative_units_resolve_against_viewport_and_font_size() {
assert!(hit, "expected a 500x160 box from 50vw/10em, rects: {:?}", layout.rects.values().map(|r| (r.width, r.height)).collect::<Vec<_>>());
}
#[test]
fn percentage_padding_top_reserves_aspect_ratio_box() {
// The responsive aspect-ratio trick: an empty box with padding-top:56.25%
// inside a 1000px-wide block reserves a 16:9 area (~562px tall), the room a
// `position:absolute; inset:0` media child fills. Percentage padding
// resolves against the containing block WIDTH on every side, so the box
// gains real height instead of collapsing to zero.
let html = r##"<div style="width:1000px"><div style="padding-top:56.25%"></div></div>"##;
let tree = parse_html(html);
let layout = layout_dom(&tree, (1200.0, 800.0));
let hit = layout
.rects
.values()
.any(|r| (r.width - 1000.0).abs() < 1.0 && (r.height - 562.5).abs() < 2.0);
assert!(
hit,
"expected a ~1000x562 aspect-ratio box from padding-top:56.25%, rects: {:?}",
layout.rects.values().map(|r| (r.width, r.height)).collect::<Vec<_>>()
);
}
#[test]
fn long_text_run_wraps_across_multiple_lines() {
// A long single text node with no inline elements breaking it up must