render: table vertical-align and specified column/row sizing
Cells now vertical-align the way tables actually do: middle by default (the effective UA behavior), with author top/middle/bottom parsed and applied to whichever shape the cell took: main-axis alignment on the flex-column stand-in, line alignment on a promoted inline context, or a pinned-origin offset for the pure-text leaf path where the shaped text height is known at finalize. Specified column widths finally apply. <col>/<colgroup> widths (style or attribute, with span) and colspan-1 cell widths are recorded per column at build time and pinned inside the column-balancing pass: px directly, percent against the table's content width, with each column's content min-content still flooring it. The cell's own width is neutralized once it has fed the column, so the cell box fills its grid area instead of shrinking to a fraction of its own already-sized track (a width:50% cell previously ended up at 25 percent). Unspecified columns keep content sizing but stretch to fill a definite table width instead of leaving a dead strip of table background. Row and cell heights act as row minimums. Verified against Chromium on a 5-case repro (column from cell width, row backgrounds, vertical alignment, col element width, percent cell in a fixed table): all match. Wikipedia and the prose spot set unchanged; obstacle course 33/33.
This commit is contained in:
1 parent
1d96c316ca
commit
953292563d
3 files changed
+221
-20
No files matched your search
@@ -130,6 +130,10 @@ pub fn ua_style(tag: &str) -> LayoutStyle {
|
||||
style.align_items = Some(taffy::AlignItems::FLEX_START);
|
||||
style.padding = Edges { top: 0.0, right: 5.0, bottom: 0.0, left: 0.0 };
|
||||
style.min_width = crate::Dimension::Px(0.0);
|
||||
// Cells are effectively middle-aligned by default in browsers (the
|
||||
// HTML UA sheet's row-group vertical-align inherited into cells);
|
||||
// an author `vertical-align` on the cell overrides this.
|
||||
style.vertical_align = Some(crate::VerticalAlign::Middle);
|
||||
if tag == "th" {
|
||||
style.font_weight = Some("bold".to_string());
|
||||
}
|
||||
@@ -438,6 +442,15 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
|
||||
}
|
||||
"visibility" => style.visibility_hidden = Some(value.eq_ignore_ascii_case("hidden")),
|
||||
"opacity" => style.opacity = value.trim().parse::<f32>().ok(),
|
||||
"vertical-align" => {
|
||||
style.vertical_align = match value.trim().to_ascii_lowercase().as_str() {
|
||||
"top" | "baseline" | "text-top" => Some(crate::VerticalAlign::Top),
|
||||
"middle" => Some(crate::VerticalAlign::Middle),
|
||||
"bottom" | "text-bottom" => Some(crate::VerticalAlign::Bottom),
|
||||
// sub/super/lengths are text-level; leave the cell default.
|
||||
_ => style.vertical_align,
|
||||
};
|
||||
}
|
||||
"list-style-type" => {
|
||||
style.list_style = Some(list_style_keyword(value.trim()).unwrap_or(crate::ListStyle::Disc));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user