LibWeb: Implement CSS inherit() function

The remaining failing imported tests are due to wider issues which are
covered by FIXMEs (both existing and added in this commit)
This commit is contained in:
Callum Law
2026-03-14 16:04:41 +13:00
committed by Jelle Raaijmakers
parent f06bd0303f
commit 915fc4602b
Notes: github-actions[bot] 2026-03-19 09:27:01 +00:00
17 changed files with 346 additions and 2 deletions

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<title>CSS Values: The inherit() function (basic behavior)</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#inherit-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<main id=main>
</main>
<template id=inherit_immediate_parent>
<style>
#parent {
--z: 2;
}
#target {
--z: 13;
z-index: inherit(--z);
}
</style>
<div id=parent>
<div id=target>
</div>
</div>
</template>
<script>
test((t) => {
main.append(inherit_immediate_parent.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(target).zIndex, '2');
}, 'inherit() on value set on parent');
</script>
<template id=inherit_ancestor>
<style>
:root {
--z: 2;
}
#foo {
--z: 13;
z-index: inherit(--z);
}
</style>
<div id=foo>
</div>
</template>
<script>
test((t) => {
main.append(inherit_ancestor.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(foo).zIndex, '2');
}, 'inherit() on value set on ancestor');
</script>
<template id=inherit_fallback>
<style>
#foo {
--z: 13;
z-index: inherit(--z, 4);
}
</style>
<div id=foo>
</div>
</template>
<script>
test((t) => {
main.append(inherit_fallback.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(foo).zIndex, '4');
}, 'inherit(), no value set on parent');
</script>
<template id=inherit_accumulate_values>
<style>
#e1 { --v: e1; }
#e2 { --v: e2 inherit(--v); }
#e3 { --v: e3 inherit(--v); }
</style>
<div id=e1>
<div id=e2>
<div id=e3>
</div>
</div>
</div>
</template>
<script>
test((t) => {
main.append(inherit_accumulate_values.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(e3).getPropertyValue('--v'), 'e3 e2 e1');
}, 'inherit(), accumulating values');
</script>
<template id=inherit_accumulate_font_size>
<style>
@property --f {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
#e1 { font-size: 3px; --f: 1em; }
#e2 { font-size: 5px; --f: calc(1em + inherit(--f)); }
#e3 { font-size: 7px; --f: calc(1em + inherit(--f)); }
</style>
<div id=e1>
<div id=e2>
<div id=e3>
</div>
</div>
</div>
</template>
<script>
test((t) => {
main.append(inherit_accumulate_font_size.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(e3).getPropertyValue('--f'), '15px');
}, 'inherit(), accumulating font-size');
</script>
<template id=inherit_within_if>
<style>
#parent {
--z: 2;
}
#target {
--z: 13;
z-index: if(style(--z > inherit(--z)):4; else:7);
}
</style>
<div id=parent>
<div id=target>
</div>
</div>
</template>
<script>
test((t) => {
main.append(inherit_within_if.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(target).zIndex, '4');
}, 'inherit() can be used within if()');
</script>

View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<title>CSS Values: The inherit() function (invalidation)</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#inherit-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<main id=main>
</main>
<template id=parent_change_unregistered>
<style>
#outer {
--z: 2;
}
#target {
z-index: inherit(--z);
}
</style>
<div id=outer>
<div id=target>
</div>
</div>
</template>
<script>
test((t) => {
main.append(parent_change_unregistered.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(target).zIndex, '2');
assert_equals(getComputedStyle(target).getPropertyValue('--z'), '2');
outer.style.setProperty('--z', '4');
assert_equals(getComputedStyle(target).zIndex, '4');
assert_equals(getComputedStyle(target).getPropertyValue('--z'), '4');
}, 'inherit() invalidates when values changes on parent element, inherited');
</script>
<!-- Like the previous test, but #target is buried deeper. -->
<template id=parent_change_unregistered_deep>
<style>
#outer {
--z: 2;
}
#target {
z-index: inherit(--z, 7);
}
</style>
<div id=outer>
<div>
<div>
<div>
<div id=target></div>
</div>
</div>
</div>
</div>
</template>
<script>
test((t) => {
main.append(parent_change_unregistered_deep.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(target).zIndex, '2');
outer.style.setProperty('--z', '4');
assert_equals(getComputedStyle(target).zIndex, '4');
}, 'inherit() invalidates when values changes on parent element, inherited, deeper');
</script>
<template id=parent_change_registered>
<style>
@property --z {
syntax: "<integer>";
inherits: false;
initial-value: 0;
}
#outer {
--z: 2;
}
#target {
z-index: inherit(--z, 7);
}
</style>
<div id=outer>
<div id=target>
</div>
</div>
</template>
<script>
test((t) => {
main.append(parent_change_registered.content.cloneNode(true));
t.add_cleanup(() => { main.replaceChildren(); });
assert_equals(getComputedStyle(target).zIndex, '2');
assert_equals(getComputedStyle(target).getPropertyValue('--z'), '0');
outer.style.setProperty('--z', '4');
assert_equals(getComputedStyle(target).zIndex, '4');
assert_equals(getComputedStyle(target).getPropertyValue('--z'), '0');
}, 'inherit() invalidates when values changes on parent element, non-inherited');
</script>

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<title>CSS Values: The inherit() function (parsing)</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#inherit-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../css/support/parsing-testcommon.js"></script>
<script>
// 'left' chosen arbitrarily:
test_valid_value('left', 'inherit(--x)');
test_valid_value('left', 'calc(inherit(--x) + 1px)');
test_valid_value('left', 'inherit(--x,)');
test_valid_value('left', 'inherit(--x, )');
test_valid_value('left', 'inherit(--x , )');
test_valid_value('left', 'inherit(--x, foo)');
test_invalid_value('left', 'inherit(!!, foo)');
test_invalid_value('left', 'inherit(, foo)');
</script>