Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<html>
<head>
<title>CSS Mixins: Parameters</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<style>
@mixin --m1() {
color: green;
}
@mixin --m1(junk-in-parameter-list) { /* Will be ignored. */
color: red;
}
#e1 {
@apply --m1;
}
</style>
<div><div id="e1">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e1');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Mixins with invalid parameter lists are ignored');
</script>
<style>
@mixin --m2(--my-color) {
color: var(--my-color);
}
#e2 {
@apply --m2(green);
}
</style>
<div><div id="e2">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e2');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Basic mixin parameter passing');
</script>
<style>
@mixin --m2b(--my-color) {
color: var(--my-color);
}
#e2b {
@apply --m2b(navy);
}
</style>
<div><div id="e2b">This text should be navy.</div></div>
<script>
test(() => {
let target = document.getElementById('e2b');
assert_equals(getComputedStyle(target).color, 'rgb(0, 0, 128)');
}, 'Mixins can be called multiple times with different parameters');
</script>
<style>
@mixin --m2c(--my-color) {
color: var(--my-color);
}
#e2c {
color: fuchsia;
@apply --m2c();
}
</style>
<div><div id="e2c">This text should be fuchsia.</div></div>
<script>
test(() => {
let target = document.getElementById('e2c');
assert_equals(getComputedStyle(target).color, 'rgb(0, 0, 0)');
}, 'Too few parameters and no default ignores mixin');
</script>
<style>
@mixin --m3(--my-color) {
color: var(--my-color);
}
#e3 {
@apply --m3({green});
}
</style>
<div><div id="e3">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e3');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Mixin argument parsing with arguments wrapped in {}');
</script>
<style>
@mixin --m4(--my-color: green) {
color: var(--my-color);
}
#e4 {
@apply --m4;
}
</style>
<div><div id="e4">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e4');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Defaults in mixin parameters');
</script>
<style>
@mixin --m5() {
color: red;
}
#e5 {
color: green;
@apply --m5(too-many-parameters);
}
</style>
<div><div id="e5">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e5');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, '@apply with too many parameters is ignored');
</script>
<style>
@mixin --m6(--my-color) {
color: var(--my-color, navy);
}
#e6 {
@apply --m6(green);
}
</style>
<div><div id="e6">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e6');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Fallback is ignored if argument is given');
</script>
<style>
@mixin --m6b(--my-color) {
color: var(--my-color, navy);
}
#e6b {
@apply --m6b;
}
</style>
<div><div id="e6b">This text should be navy.</div></div>
<script>
test(() => {
let target = document.getElementById('e6b');
assert_equals(getComputedStyle(target).color, 'rgb(0, 0, 128)');
}, 'Fallback is used with no parameter and no default');
</script>
<style>
@mixin --m6c(--my-color) {
color: var(--my-color, navy);
}
#e6c {
@apply --m6c(invalid-color);
}
</style>
<div><div id="e6c">This text should be black.</div></div>
<script>
test(() => {
let target = document.getElementById('e6c');
assert_equals(getComputedStyle(target).color, 'rgb(0, 0, 0)');
}, 'Fallback is not used on other errors');
</script>
<style>
#e6d {
color: var(--not-within-mixin, green);
}
</style>
<div><div id="e6d">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e6d');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Fallback is not when outside mixin');
</script>
<style>
#e6e {
color: var(--not-within-mixin);
}
</style>
<div><div id="e6e">This text should be black.</div></div>
<script>
test(() => {
let target = document.getElementById('e6e');
assert_equals(getComputedStyle(target).color, 'rgb(0, 0, 0)');
}, 'Invalid when no fallback and outside mixin');
</script>
<style>
@mixin --m7(--my-color) {
color: attr(color-attr type(<color>));
}
#e7 {
@apply --m7(green);
}
</style>
<div><div id="e7" color-attr="var(--my-color)">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e7');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'var() can be accessed from attributes');
</script>
<style>
@mixin --m8(--my-length type(<length>)) {
font-size: 10px;
--some-length: var(--my-length);
}
#e8 {
@apply --m8(1.0em);
}
</style>
<div><div id="e8">This text does not matter.</div></div>
<script>
test(() => {
let target = document.getElementById('e8');
assert_equals(getComputedStyle(target).getPropertyValue('--some-length'), '10px');
}, 'var() resolves typed parameters');
</script>
<style>
@mixin --m9(--my-length type(length)) { /* Note the syntax error. */
font-size: 10px;
--some-length: var(--my-length);
}
#e9 {
@apply --m9(1.0em);
}
</style>
<div><div id="e9">This text does not matter.</div></div>
<script>
test(() => {
let target = document.getElementById('e9');
assert_equals(getComputedStyle(target).getPropertyValue('--some-length'), '');
assert_equals(getComputedStyle(target).fontSize, '10px');
}, 'var() refuses illegal syntax parameters, but does not fail entire mixin');
</script>
<style>
@mixin --m10inner(--inner-color) {
color: var(--outer-color);
}
@mixin --m10outer(--outer-color) {
@apply --m10inner(red);
}
#e10 {
@apply --m10outer(green);
}
</style>
<div><div id="e10">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e10');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'var() can access parameters from outer mixins');
</script>
<style>
@mixin --m11(--val, --true, --false) {
color: if(style(--x: var(--val)): var(--true); else: var(--false))
}
#e11 {
--x: a;
@apply --m11(a, green, red);
}
</style>
<div><div id="e11">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e11');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'var() works inside if, in condition and true branch');
</script>
<style>
@mixin --m11b(--val, --true, --false) {
color: if(style(--x: var(--val)): var(--true); else: var(--false))
}
#e11b {
--x: a;
@apply --m11b(b, red, green);
}
</style>
<div><div id="e11b">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e11b');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'var() works inside if, in condition and false branch');
</script>
<style>
@function --f() {
color: var(--my-color);
}
@mixin --m12(--my-color) {
color: --f();
}
#e12 {
@apply --m12(red);
}
</style>
<div><div id="e12">This text should be black.</div></div>
<script>
test(() => {
let target = document.getElementById('e12');
assert_equals(getComputedStyle(target).color, 'rgb(0, 0, 0)');
}, 'var() within a function should not see parameters from a calling mixin');
</script>
<style>
@mixin --m13-override-outer(--inner, --outer) {
color: var(--inner);
}
@mixin --m13-set-inner(--inner) {
@apply --m13-override-outer(var(--inner), red);
}
@mixin --m13(--outer) {
@apply --m13-set-inner(var(--outer));
}
#e13 {
@apply --m13(green);
}
</style>
<div><div id="e13">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e13');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Mixin arguments are resolved at call site, not at use');
</script>
<style>
@mixin --m14(--param: green) {
color: var(--param);
}
#e14 {
@apply --m14();
}
</style>
<div><div id="e14">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e14');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'var() supports default parameters');
</script>
<style>
@mixin --m15(--my-length type(<length>): 1em) {
--some-length: var(--my-length);
}
#e15 {
font-size: 12px;
@apply --m15();
}
</style>
<div><div id="e15">This text does not matter.</div></div>
<script>
test(() => {
let target = document.getElementById('e15');
assert_equals(getComputedStyle(target).getPropertyValue('--some-length'), '12px');
}, 'var() typed default parameters are resolved against the element');
</script>
<style>
@mixin --m16(--arg: !!) { /* Invalid declaration. */
color: red;
}
#e16 {
color: green;
@apply --m16();
}
</style>
<div><div id="e16">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e16');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Invalid defaults should skip declaration, even on unused arguments');
</script>
<style>
@mixin --m17(--arg) {
color: red;
}
#e17 {
color: green;
@apply --m17(!!!); /* Invalid invocation. */
}
</style>
<div><div id="e17">This text should be green.</div></div>
<script>
test(() => {
let target = document.getElementById('e17');
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
}, 'Invalid @apply arguments should skip declaration');
</script>
</body>
</html>