Honor inherited heading font weights

This commit is contained in:
SGavrl
2026-07-31 01:33:15 +00:00
parent c5210b1684
commit 6f71c302c5
2 changed files with 72 additions and 3 deletions

View File

@@ -869,8 +869,29 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
"letter-spacing" => apply_letter_spacing(style, value),
"font" => apply_font_shorthand(style, value),
"font-weight" => {
if let Some(weight) = specified_font_weight(value) {
style.font_weight = Some(weight);
let lower = value.trim().to_ascii_lowercase();
match lower.as_str() {
// font-weight is inherited. Preserve the inherited marker
// until the DOM's top-down computed-style pass can see the
// parent's numeric weight. `unset` has the same behavior for
// an inherited property.
"inherit" | "unset" => {
style.font_weight = Some("inherit".to_string());
}
// The initial font weight is normal, independent of both the
// parent and a heading's bold UA rule.
"initial" => {
style.font_weight = Some("400".to_string());
}
// The compact cascade does not retain origin/layer history,
// so leave its current state unchanged instead of pretending
// the revert forms mean inherit or initial.
"revert" | "revert-layer" => {}
_ => {
if let Some(weight) = specified_font_weight(&lower) {
style.font_weight = Some(weight);
}
}
}
}
"font-family" => {
@@ -3625,7 +3646,8 @@ fn specified_font_weight(value: &str) -> Option<String> {
pub(crate) fn computed_font_weight(specified: Option<&str>, inherited: u16) -> u16 {
match specified {
None => inherited,
Some("normal") => 400,
Some("inherit" | "unset") => inherited,
Some("normal" | "initial") => 400,
Some("bold") => 700,
Some("bolder") if inherited < 100 => 400,
Some("bolder") if inherited < 350 => 400,
@@ -4723,6 +4745,21 @@ mod tests {
assert_eq!(computed_font_weight(Some("lighter"), 900), 700);
}
#[test]
fn font_weight_css_wide_keywords_override_heading_ua_weight() {
let inherited = compute_style("h1", Some("font-weight:inherit"));
assert_eq!(inherited.font_weight.as_deref(), Some("inherit"));
assert_eq!(computed_font_weight(inherited.font_weight.as_deref(), 500), 500);
let unset = compute_style("h1", Some("font-weight:unset"));
assert_eq!(unset.font_weight.as_deref(), Some("inherit"));
assert_eq!(computed_font_weight(unset.font_weight.as_deref(), 500), 500);
let initial = compute_style("h1", Some("font-weight:initial"));
assert_eq!(initial.font_weight.as_deref(), Some("400"));
assert_eq!(computed_font_weight(initial.font_weight.as_deref(), 500), 400);
}
#[test]
fn variable_font_properties_parse_canonically_and_atomically() {
let style = compute_style(

View File

@@ -1644,6 +1644,38 @@ fn font_weight_computes_numerically_through_inheritance() {
assert_eq!(weight("lighter"), Some("100"));
}
#[test]
fn heading_font_weight_css_wide_keywords_override_the_ua_bold_rule() {
let tree = parse_html(
r#"
<style>
@layer base {
#parent { font-weight: 500 }
#inherited { font-weight: inherit }
#unset { font-weight: unset }
#initial { font-weight: initial }
}
</style>
<div id="parent">
<h1 id="ua">UA bold</h1>
<h1 id="inherited">Inherited medium</h1>
<h1 id="unset">Unset medium</h1>
<h1 id="initial">Initial normal</h1>
</div>
"#,
);
let layout = layout_dom(&tree, (900.0, 1000.0));
let weight = |id| {
layout.styles[&tree.get_element_by_id(id).unwrap()]
.font_weight
.as_deref()
};
assert_eq!(weight("ua"), Some("700"));
assert_eq!(weight("inherited"), Some("500"));
assert_eq!(weight("unset"), Some("500"));
assert_eq!(weight("initial"), Some("400"));
}
#[test]
fn contextual_right_inset_uses_root_font_tokens() {
let tree = parse_html(