Update web-platform-tests to revision b'ee6da9d71d0268d7fdb04e8e5b26858f46ee0cc4'

This commit is contained in:
WPT Sync Bot 2022-01-20 04:38:55 +00:00 committed by cybai
parent 4401622eb1
commit b77ad115f6
16832 changed files with 270819 additions and 87621 deletions

View file

@ -0,0 +1,43 @@
<!doctype html>
<title>Container Queries - Animating container size</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
@keyframes anim {
from { width: 200px; }
to { width: 100px; }
}
#container {
container-type: inline-size;
animation: anim 1s linear paused;
}
#target {
background-color: green;
}
@container size(width: 200px) {
#target {
background-color: blue;
}
}
</style>
<div id=container>
<div id=target>
Test
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(0, 0, 255)');
assert_equals(container.getAnimations().length, 1);
let animation = container.getAnimations()[0];
animation.currentTime = 500;
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(0, 128, 0)');
}, 'Animation affects container query evaluation');
</script>

View file

@ -0,0 +1,68 @@
<!doctype html>
<title>Container Queries - Animated container creating new containers</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
@keyframes anim {
from { width: 200px; }
to { width: 300px; }
}
#container {
container-type: inline-size;
animation: anim 1s linear paused;
}
#target {
background-color: red;
}
#intermediate {
width: 100px;
}
@container size(min-width: 250px) {
#intermediate {
container-type: inline-size;
}
}
@container size(width: 200px) {
#target {
background-color: blue;
}
}
@container size(width: 100px) {
/* Initially queries #container, but later queries #intermediate, when
the other container query starts matching. */
#target {
background-color: green;
}
}
</style>
<div id=container>
<div id=intermediate>
<div id=target>
Test
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(0, 0, 255)');
assert_equals(container.getAnimations().length, 1);
let animation = container.getAnimations()[0];
animation.currentTime = 600;
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(0, 128, 0)');
// Verify that #intermediate is queried by changing its width. The container
// query will stop matching if #intermediate is the queried container.
intermediate.style.width = '110px';
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(255, 0, 0)');
}, 'Animated container creating new container');
</script>

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<title>Container Queries - Animations within animating container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
@keyframes outer {
from { width: 100px; }
to { width: 300px; }
}
@keyframes inner {
from { background-color: blue; }
to { background-color: yellow; }
}
#container {
container-type: inline-size;
animation: outer 1s linear paused;
}
#target {
background-color: green;
}
@container size(min-width: 200px) {
#target {
animation: inner 1s linear paused;
}
}
</style>
<div id=container>
<div id=target>
Test
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(0, 128, 0)');
assert_equals(container.getAnimations().length, 1);
let animation = container.getAnimations()[0];
animation.currentTime = 600;
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(0, 0, 255)');
}, 'Animated container can create inner animation');
</script>

View file

@ -0,0 +1,44 @@
<!doctype html>
<title>Container Queries - Animated container with inner transition</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
@keyframes outer {
from { width: 100px; }
to { width: 300px; }
}
#container {
container-type: inline-size;
animation: outer 1s linear paused;
}
#target {
background-color: rgb(100, 100, 100);
}
@container size(min-width: 200px) {
#target {
transition: background-color 100s steps(2, start);
background-color: rgb(200, 200, 200);
}
}
</style>
<div id=container>
<div id=target>
Test
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(100, 100, 100)');
assert_equals(container.getAnimations().length, 1);
let animation = container.getAnimations()[0];
animation.currentTime = 600;
assert_equals(getComputedStyle(target).backgroundColor, 'rgb(150, 150, 150)');
}, 'Animated container size triggers transition');
</script>

View file

@ -0,0 +1,49 @@
<!doctype html>
<title>@container queries with aspect-ratio</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#aspect-ratio">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
.container {
width: 100px;
height: 100px;
}
#inline-size { container-type: inline-size; }
#size { container-type: size; }
span { color: red }
@container size(min-aspect-ratio: 1 / 1000) {
span { color: green; }
}
@container size(min-aspect-ratio: 2 / 1) {
span { background-color: lime; }
}
</style>
<div id="inline-size" class="container"><span></span></div>
<div id="size" class="container"><span></span></div>
<script>
setup(() => assert_implements_container_queries());
const red = "rgb(255, 0, 0)";
const green = "rgb(0, 128, 0)";
const lime = "rgb(0, 255, 0)";
const transparent = "rgba(0, 0, 0, 0)";
const inline_span = document.querySelector("#inline-size > span");
const size_span = document.querySelector("#size > span");
test(() => {
assert_equals(getComputedStyle(inline_span).color, red,
"Should not match for inline-size containment");
assert_equals(getComputedStyle(size_span).color, green,
"Should match for block-size containment");
assert_equals(getComputedStyle(size_span).backgroundColor, transparent,
"Square should not match 2/1 min-ratio");
}, "@container queries with aspect-ratio and size containment");
test(() => {
document.querySelector("#size").style.width = "200px";
assert_equals(getComputedStyle(size_span).backgroundColor, lime,
"Should match 2/1 min-ratio");
}, "@container query with aspect-ratio change after resize");
</script>

View file

@ -0,0 +1,143 @@
<!doctype html>
<title>@container: parsing</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-rule">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<div style="container:size; width:100px; height:100px">
<main id=main></main>
</div>
<script>
setup(() => assert_implements_container_queries());
function cleanup_main() {
while (main.firstChild)
main.firstChild.remove();
}
function set_style(text) {
let style = document.createElement('style');
style.innerText = text;
main.append(style);
return style;
}
function test_query_invalid(query) {
test(t => {
t.add_cleanup(cleanup_main);
let style = set_style(`@container ${query} {}`);
assert_equals(style.sheet.rules.length, 0);
}, query);
}
// Tests that 1) the query parses, and 2) is either "unknown" or not, as
// specified.
function test_query_valid(query, unknown) {
test(t => {
t.add_cleanup(cleanup_main);
let style = set_style(`
@container ${query} {}
@container (${query} or (not ${query})) { main { --match:true; } }
`);
assert_equals(style.sheet.rules.length, 2);
const expected = unknown ? '' : 'true';
assert_equals(getComputedStyle(main).getPropertyValue('--match'), expected);
}, query);
}
function test_query_known(query) {
test_query_valid(query, false /* unknown */);
}
function test_query_unknown(query) {
test_query_valid(query, true /* unknown */);
}
function test_container_selector_invalid(container_selector) {
test(t => {
t.add_cleanup(cleanup_main);
let style = set_style(`@container ${container_selector} (width) {}`);
assert_equals(style.sheet.rules.length, 0);
}, `Container selector: ${container_selector}`);
}
function test_container_selector_valid(container_selector) {
test(t => {
t.add_cleanup(cleanup_main);
let style = set_style(`@container ${container_selector} (width) {}`);
assert_equals(style.sheet.rules.length, 1);
}, `Container selector: ${container_selector}`);
}
test_query_known('size(width)');
test_query_known('size(min-width: 0px)');
test_query_known('size(max-width: 0px)');
test_query_known('size(height)');
test_query_known('size(min-height: 0px)');
test_query_known('size(max-height: 0px)');
test_query_known('size(aspect-ratio)');
test_query_known('size(min-aspect-ratio: 1/2)');
test_query_known('size(max-aspect-ratio: 1/2)');
test_query_known('size(orientation: portrait)');
test_query_known('size(inline-size)');
test_query_known('size(min-inline-size: 0px)');
test_query_known('size(max-inline-size: 0px)');
test_query_known('size(block-size)');
test_query_known('size(min-block-size: 0px)');
test_query_known('size(max-block-size: 0px)');
test_query_known('size(width: 100px)');
test_query_known('size((width: 100px))');
test_query_known('size(not (width: 100px))');
test_query_known('size((width: 100px) and (height: 100px))');
test_query_known('size((width: 50px) or (height: 100px))');
test_query_known('size(width < 100px)');
test_query_known('size(100px < width)');
test_query_known('size(100px < width < 200px)');
test_query_unknown('foo(width)');
test_query_unknown('size(asdf)');
test_query_unknown('size(resolution > 100dpi)');
test_query_unknown('size(resolution: 150dpi)');
test_query_unknown('size(color)');
test_query_unknown('size(min-color: 1)');
test_query_unknown('size(color-index >= 1)');
test_query_unknown('(color-index >= 1)');
test_query_unknown('size(grid)');
test_query_unknown('(grid)');
test_query_invalid('screen');
test_query_invalid('print');
test_query_invalid('not print');
test_query_invalid('only print');
test_query_invalid('screen and (width: 100px)');
test_query_invalid('screen or (width: 100px)');
test_query_invalid('not screen and (width: 100px)');
test_query_invalid('not screen or (width: 100px)');
test_query_invalid('(width: 100px), (height: 100px)');
test_container_selector_valid(' foo');
test_container_selector_valid(' foo ');
test_container_selector_valid('name(foo)');
test_container_selector_valid('name( foo )');
test_container_selector_valid('type(size)');
test_container_selector_valid('type( size )');
test_container_selector_valid('type(inline-size)');
test_container_selector_valid('type(block-size)');
test_container_selector_valid('name(bar) type(block-size)');
test_container_selector_valid('type(block-size) name(bar)');
test_container_selector_invalid('foo foo');
test_container_selector_invalid('1px');
test_container_selector_invalid('50gil');
test_container_selector_invalid('name(1px)');
test_container_selector_invalid('type(1px)');
test_container_selector_invalid('type(red)');
test_container_selector_invalid('type(size) type(size)');
test_container_selector_invalid('type(inline-size) type(block-size)');
test_container_selector_invalid('name(foo) name(bar)');
test_container_selector_invalid('type(inline-size) name(foo) type(block-size)');
test_container_selector_invalid('name(foo) type(size) name(bar)');
test_container_selector_invalid('name(type(size))');
test_container_selector_invalid('type(name(bar))');
</script>

View file

@ -0,0 +1,53 @@
<!doctype html>
<title>CSS Container Queries Test: scrollbar stability for @container queries and overflow:auto</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollbar-layout">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#scroller {
height: 100px;
width: 100px;
overflow-y: auto;
}
#container {
container-type: inline-size;
}
#inner {
height: 100px;
border-bottom: 1px solid red;
}
@container size(max-width: 99px) {
#inner {
height: 50px;
}
}
</style>
<div id="precondition" style="width:100px;height:100px;overflow:scroll"></div>
<div id="scroller">
<div id="container">
<div id="inner"></div>
</div>
</div>
<script>
setup(() => {
assert_implements_container_queries();
assert_implements_optional(precondition.clientWidth < 100,
"Tests do not work with overlay scrollbars");
});
test(() => {
assert_less_than(scroller.clientWidth, 100, "Expects a vertical scrollbar");
assert_equals(getComputedStyle(inner).height, "50px",
"Layout with a scrollbar means the container query applies");
}, "Initial layout - expecting a scrollbar without overflowing content instead of overflowing content without a scrollbar");
test(() => {
inner.style.borderBottomWidth = "2px";
assert_less_than(scroller.clientWidth, 100, "Expects a vertical scrollbar");
assert_equals(getComputedStyle(inner).height, "50px",
"Layout with a scrollbar means the container query applies");
}, "Same result after a reflow");
</script>

View file

@ -0,0 +1,51 @@
<!doctype html>
<title>Test that ::backdrop responds to container size changes</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
:root {
color: black;
}
#container {
container-type: size;
width: 200px;
height: 40px;
}
::backdrop {
background-color: black;
}
@container size(min-width: 300px) {
::backdrop {
background-color: green;
}
}
</style>
<main id=container>
<dialog>test</dialog>
</main>
<script>
setup(() => assert_implements_container_queries());
let dialog = document.querySelector('dialog');
test(function() {
try {
dialog.showModal();
assert_equals(getComputedStyle(dialog, '::backdrop').backgroundColor, 'rgb(0, 0, 0)');
container.style.width = '300px';
assert_equals(getComputedStyle(dialog, '::backdrop').backgroundColor, 'rgb(0, 128, 0)');
container.style = '';
assert_equals(getComputedStyle(dialog, '::backdrop').backgroundColor, 'rgb(0, 0, 0)');
} finally {
dialog.close();
}
}, 'Pseudo-element ::backdrop responds to container size changes');
</script>

View file

@ -0,0 +1,4 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>You should see the word PASS below.</p>
PASS

View file

@ -0,0 +1,27 @@
<!doctype html>
<title>CSS Container Queries Test: Change display and box inside a container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="match" href="change-display-in-container-ref.html">
<style>
.fail { display: inline; }
.pass { display: none; }
#container { container-type: size; width: 100px; }
@container size(min-width: 200px) {
.fail { display: none; }
.pass { display: inline; }
}
</style>
<p>You should see the word PASS below.</p>
<div id="container">
<span>
<span class="fail">FAIL</span>
</span>
<span>
<span class="pass">PASS</span>
<span class="fail">FAIL</span>
</span>
</div>
<script>
container.offsetTop;
container.style.width = "auto";
</script>

View file

@ -0,0 +1,28 @@
<!doctype html>
<title>Conditionally removing container status</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
.parent { width: 300px; }
.child { width: 100px; }
.parent, .child { container-type: inline-size; }
@container size(min-width: 200px) {
.child { container-type: initial; }
.grandchild { border: 3px solid green }
}
</style>
<div class="parent">
<div class="child">
<div class="grandchild">You should see a green border around this text</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(function() {
let s = getComputedStyle(document.querySelector('.grandchild'));
assert_equals(s.getPropertyValue('border-color'), 'rgb(0, 128, 0)');
}, 'Conditionally applying container-type:initial');
</script>

View file

@ -0,0 +1,28 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Containment Test: Computed values of container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-name">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="target"></div>
<script>
setup(() => assert_implements_container_queries());
test_computed_value('container', 'initial', 'none');
test_computed_value('container', 'inherit', 'none');
test_computed_value('container', 'unset', 'none');
test_computed_value('container', 'inline-size');
test_computed_value('container', 'size');
test_computed_value('container', 'inline-size / inline-size');
test_computed_value('container', 'size / block-size');
test_computed_value('container', 'size style / name', 'style size / name');
test_computed_value('container', 'inline-size state style/ name', 'style state inline-size / name');
test_computed_value('container', 'inline-size / foo');
test_computed_value('container', 'inline-size /foo', 'inline-size / foo');
test_computed_value('container', 'inline-size/ foo', 'inline-size / foo');
test_computed_value('container', 'inline-size/foo', 'inline-size / foo');
test_computed_value('container', 'size / FoO', 'size / FoO');
</script>

View file

@ -0,0 +1,287 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Container Queries Test: query container for Shadow DOM</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5984">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#query-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#inclusive-ancestor-across-root,
#inclusive-ancestor-skip-slotting,
#inclusive-ancestor-slotted,
#inclusive-ancestor-host,
#inclusive-ancestor-part,
#inclusive-ancestor-slotted-before,
#inclusive-ancestor-host-before,
#inclusive-ancestor-part-before,
#inclusive-ancestor-inner-part,
#inclusive-ancestor-slot-fallback {
width: 400px;
container-type: inline-size;
}
</style>
<div id="inclusive-ancestor-across-root">
<div>
<template shadowroot="open">
<style>
@container size(width = 400px) {
#t1 { color: green; }
}
</style>
<div id="t1"></div>
</template>
</div>
</div>
<div id="inclusive-ancestor-skip-slotting">
<div>
<template shadowroot="open">
<style>
div {
width: 200px;
container-type: inline-size;
}
</style>
<div>
<slot></slot>
</div>
</template>
<style>
@container size(width = 400px) {
#t2 { color: green; }
}
</style>
<div id="t2"></div>
</div>
</div>
<div id="inclusive-ancestor-slotted">
<div>
<template shadowroot="open">
<style>
slot {
display: block;
width: 200px;
container-type: inline-size;
}
@container size(width = 200px) {
::slotted(#t3) { color: green; }
}
</style>
<slot></slot>
</template>
<div id="t3"></div>
</div>
</div>
<div id="inclusive-ancestor-host">
<div id="t4">
<template shadowroot="open">
<style>
@container size(width = 400px) {
:host(#t4) { color: green; }
}
</style>
</template>
</div>
</div>
<div id="inclusive-ancestor-part">
<div>
<template shadowroot="open">
<style>
div {
width: 200px;
container-type: inline-size;
}
</style>
<div>
<span id="t5" part="part"></span>
</div>
</template>
<style>
@container size(width = 400px) {
#inclusive-ancestor-part > div::part(part) { color: green; }
}
</style>
</div>
</div>
<div id="inclusive-ancestor-slotted-before">
<div>
<template shadowroot="open">
<style>
slot {
display: block;
width: 200px;
container-type: inline-size;
}
@container size(width = 200px) {
::slotted(#t6)::before {
content: "X";
color: green;
}
}
</style>
<slot></slot>
</template>
<style>
#t6 {
width: 400px;
container-type: inline-size;
}
</style>
<div id="t6"></div>
</div>
</div>
<div id="inclusive-ancestor-host-before">
<div id="t7">
<template shadowroot="open">
<style>
:host {
width: 200px;
container-type: inline-size;
}
@container size(width = 200px) {
:host(#t7)::before {
content: "X";
color: green;
}
}
</style>
</template>
</div>
</div>
<div id="inclusive-ancestor-part-before">
<style>
@container size(width = 400px) {
#inclusive-ancestor-part-before > div::part(part)::before {
content: "X";
color: green;
}
}
</style>
<div>
<template shadowroot="open">
<style>
div {
width: 200px;
container-type: inline-size;
}
</style>
<div>
<span id="t8" part="part"></span>
</div>
</template>
</div>
</div>
<div id="inclusive-ancestor-inner-part">
<style>
@container size(width = 400px) {
#inclusive-ancestor-inner-part > div::part(inner-part) { color: green; }
}
</style>
<div>
<template shadowroot="open">
<style>
div {
width: 200px;
container-type: inline-size;
}
</style>
<div exportparts="inner-part">
<template shadowroot="open">
<style>
div {
width: 200px;
container-type: inline-size;
}
</style>
<div>
<span id="t9" part="inner-part"></span>
</div>
</template>
</div>
</template>
</div>
</div>
<div id="inclusive-ancestor-slot-fallback">
<div><template shadowroot="open">
<style>
div {
width: 200px;
container-type: inline-size;
}
@container size(width = 200px) {
#t10 { color: green; }
}
</style>
<div>
<slot><span id="t10"></span></slot>
</div>
</template></div>
</div>
<script>
setup(() => assert_implements_container_queries());
const green = "rgb(0, 128, 0)";
test(() => {
const t1 = document.querySelector("#inclusive-ancestor-across-root > div").shadowRoot.querySelector("#t1");
assert_equals(getComputedStyle(t1).color, green);
}, "Match container in outer tree");
test(() => {
const t2 = document.querySelector("#t2");
assert_equals(getComputedStyle(t2).color, green);
}, "Match container in same tree, not walking flat tree ancestors");
test(() => {
const t3 = document.querySelector("#t3");
assert_equals(getComputedStyle(t3).color, green);
}, "Match container in ::slotted selector's originating element tree");
test(() => {
const t4 = document.querySelector("#t4");
assert_equals(getComputedStyle(t4).color, green);
}, "Match container in outer tree for :host");
test(() => {
const t5 = document.querySelector("#inclusive-ancestor-part > div").shadowRoot.querySelector("#t5");
assert_equals(getComputedStyle(t5).color, green);
}, "Match container in ::part selector's originating element tree");
test(() => {
const t6 = document.querySelector("#t6");
assert_equals(getComputedStyle(t6, "::before").color, green);
}, "Match container for ::before in ::slotted selector's originating element tree");
test(() => {
const t7 = document.querySelector("#t7");
assert_equals(getComputedStyle(t7, "::before").color, green);
}, "Match container in outer tree for :host::before");
test(() => {
const t8 = document.querySelector("#inclusive-ancestor-part-before > div").shadowRoot.querySelector("#t8");
assert_equals(getComputedStyle(t8, "::before").color, green);
}, "Match container for ::before in ::part selector's originating element tree");
test(() => {
const outerhost = document.querySelector("#inclusive-ancestor-inner-part > div");
const innerhost = outerhost.shadowRoot.querySelector("div");
const t9 = innerhost.shadowRoot.querySelector("#t9");
assert_equals(getComputedStyle(t9).color, green);
}, "Match container for ::part selector's originating element tree for exportparts");
test(() => {
const t10 = document.querySelector("#inclusive-ancestor-slot-fallback > div").shadowRoot.querySelector("#t10");
assert_equals(getComputedStyle(t10).color, green);
}, "Match container for slot light tree child fallback");
</script>

View file

@ -0,0 +1,18 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Containment Test: Inheritance of container-*</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-name">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/inheritance-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="container">
<div id="target"></div>
</div>
<script>
setup(() => assert_implements_container_queries());
assert_not_inherited('container-name', 'none', 'foo');
assert_not_inherited('container-type', 'none', 'inline-size');
</script>

View file

@ -0,0 +1,17 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Containment Test: Computed values of container-name</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-name">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="target"></div>
<script>
setup(() => assert_implements_container_queries());
test_computed_value('container-name', 'initial', 'none');
test_computed_value('container-name', 'unset', 'none');
test_computed_value('container-name', 'foo');
test_computed_value('container-name', 'FoO');
</script>

View file

@ -0,0 +1,74 @@
<!doctype html>
<title>container-name invalidation</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-name">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
div {
color: black;
}
#outer {
container-name: c1;
container-type: inline-size;
width: 300px;
}
#inner {
container-name: c2;
container-type: inline-size;
width: 200px;
}
#intermediate {
width: 250px;
}
@container c1 size(width: 250px) {
#child {
color: green;
}
}
</style>
<div id=outer>
<div id=intermediate>
<div id=inner>
<div id=child>Test</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(function(t) {
t.add_cleanup(() => { outer.style = ''; });
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
outer.style.width = '250px';
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
outer.style.width = '251px';
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
}, 'Changing a named container invalidates relevant descendants');
test(function(t) {
t.add_cleanup(() => {
outer.style = '';
intermediate.style = '';
});
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
// #intermediate becomes the new container.
intermediate.style = 'container-name:c1; container-type:inline-size';
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
// #outer becomes the container again.
intermediate.style = '';
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
outer.style.width = '250px';
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
}, 'Changing container-name invalidates relevant descendants');
</script>

View file

@ -0,0 +1,27 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Containment Test: Parsing of container-name</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-name">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="target"></div>
<script>
setup(() => assert_implements_container_queries());
test_valid_value('container-name', 'initial');
test_valid_value('container-name', 'inherit');
test_valid_value('container-name', 'unset');
test_valid_value('container-name', 'revert');
test_valid_value('container-name', 'none');
test_valid_value('container-name', 'foo');
test_valid_value('container-name', 'BAR');
test_valid_value('container-name', 'foo bar');
test_invalid_value('container-name', 'none none');
test_invalid_value('container-name', 'foo, bar');
test_invalid_value('container-name', '#fff');
test_invalid_value('container-name', '1px');
test_invalid_value('container-name', 'default'); /* reserved */
</script>

View file

@ -0,0 +1,50 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Containment Test: Parsing of container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-name">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="target"></div>
<script>
setup(() => assert_implements_container_queries());
test_valid_value('container', 'initial');
test_valid_value('container', 'inherit');
test_valid_value('container', 'unset');
test_valid_value('container', 'revert');
test_valid_value('container', 'none');
test_valid_value('container', 'none / none', 'none');
test_valid_value('container', 'inline-size');
test_valid_value('container', 'inline-size / none', 'inline-size');
test_valid_value('container', 'size');
test_valid_value('container', 'size / block-size');
test_valid_value('container', 'inline-size / inline-size');
test_valid_value('container', 'size / size');
test_valid_value('container', 'size state / none', 'size state');
test_invalid_value('container', 'none none');
test_invalid_value('container', 'none inline-size');
test_invalid_value('container', 'inline-size none');
test_invalid_value('container', 'inline-size inline-size');
test_invalid_value('container', 'inline-size block-size unknown');
test_invalid_value('container', 'inline-size block-size');
test_invalid_value('container', 'size block-size');
test_invalid_value('container', 'none, none');
test_invalid_value('container', 'foo');
test_invalid_value('container', 'foo, bar');
test_invalid_value('container', '#fff');
test_invalid_value('container', '1px');
test_invalid_value('container', 'default');
test_invalid_value('container', 'inline-size / 10px');
test_invalid_value('container', 'inline-size / #fefefe');
test_invalid_value('container', 'inline-size / calc(3px)');
test_invalid_value('container', 'size 1 / name');
test_invalid_value('container', 'block-size');
test_invalid_value('container', 'block-size / name');
test_invalid_value('container', 'block-size / NAME', 'block-size / NAME');
test_invalid_value('container', 'block-size/NAME','block-size / NAME');
test_invalid_value('container', 'block-size / block-size');
</script>

View file

@ -0,0 +1,180 @@
<!doctype html>
<title>@container: selection using name(), type()</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-rule">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
main { background-color: lightgray; }
main > div { background-color: skyblue; }
main > div > div { background-color: seagreen; }
main > div > div > div { background-color: tomato; }
main {
width: 64px;
height: 64px;
}
main div {
width: 50%;
height: 50%;
}
.inline { container-type: inline-size; }
.size { container-type: size; }
.a-inline { container: inline-size / a; }
.a-size { container: size / a; }
.b-size { container: inline-size / b; }
.b-size { container: size / b; }
.a { container-name: a; contain: strict; }
</style>
<main>
<div class="inline">
<div class="size">
<span></span>
</div>
</div>
</main>
<main>
<div class="size">
<div class="inline">
<span></span>
</div>
</div>
</main>
<main>
<div class="inline">
<div class="inline">
<span></span>
</div>
</div>
</main>
<main>
<div class="a-size">
<div class="b-size">
<span></span>
</div>
</div>
</main>
<main>
<div class="a-size">
<div class="a-size">
<span></span>
</div>
</div>
</main>
<main>
<div class="a-size">
<div class="a">
<span></span>
</div>
</div>
</main>
<main>
<div class="a-size">
<div class="b-size">
<div class="a-inline">
<span></span>
</div>
</div>
</div>
</main>
<main>
<div class="a-inline">
<div class="b-size">
<span></span>
</div>
</div>
</main>
<script>
setup(() => assert_implements_container_queries());
function test_query(prelude, selector, expected) {
test(t => {
let elements = document.querySelectorAll(selector);
assert_equals(elements.length, 1);
let element = elements[0];
let style = document.createElement('style');
t.add_cleanup(() => { style.remove(); });
style.innerText = `@container ${prelude} { span { --match:true; } } `;
document.body.append(style);
assert_equals(getComputedStyle(element).getPropertyValue('--match'), expected);
}, `${prelude} for ${selector}`);
}
// Test that a given container query applies to the specified element.
// The provided selector must unique identify the element.
function test_applied(prelude, selector) {
test_query(prelude, selector, 'true');
}
function test_rejected(prelude, selector) {
test_query(prelude, selector, '');
}
// For the following tests, the inner container has a size of 16x16px,
// and the outer container has a size of 32x32px.
// "Nearest" selection:
test_applied('size(width: 16px)', '.size > .inline > span');
test_applied('size(height: 16px)', '.inline > .size > span');
test_applied('size(width: 16px)', '.inline > .size > span');
test_rejected('size(height)', '.size > .inline > span');
// type():
test_applied('type(inline-size) size(width: 16px)', '.inline > .size > span');
test_applied('type(inline-size) size(width: 16px)', '.size > .inline > span');
test_applied('type(size) size(height: 16px)', '.inline > .size > span');
test_applied('type(size) size(height: 32px)', '.size > .inline > span');
test_rejected('type(size) size(height)', '.inline > .inline > span');
// name():
test_applied('name(a) size(width: 32px)', '.a-size > .b-size > span');
test_applied('name(b) size(width: 16px)', '.a-size > .b-size > span');
test_rejected('name(c) size(width)','.a-size > .b-size > span');
test_applied('name(a) size(width: 16px)', '.a-size > .a-size > span');
// Name as plain ident:
test_applied('a size(width: 32px)', '.a-size > .b-size > span');
test_applied('b size(width: 16px)', '.a-size > .b-size > span');
test_rejected('c size(width)', '.a-size > .b-size > span');
test_applied('a size(width: 16px)', '.a-size > .a-size > span');
// container-name alone does not establish a container:
test_applied('a size(width: 32px)', '.a-size > .a > span');
// The following tests have three containers:
//
// outer -> 32x32px
// middle -> 16x16px
// inner -> 8x8px
// Mixing name() and type():
test_applied('name(a) type(inline-size) size(width: 8px)', '.a-size > .b-size > .a-inline > span');
test_applied('name(b) type(inline-size) size(width: 16px)', '.a-size > .b-size > .a-inline > span');
test_applied('name(a) type(size) size(width: 32px)', '.a-size > .b-size > .a-inline > span');
test_applied('name(b) type(size) size(width: 16px)', '.a-size > .b-size > .a-inline > span');
test_rejected('name(a) type(size) size(width)', '.a-inline > .b-size');
// type() first, then name():
test_applied('type(inline-size) name(a) size(width: 8px)', '.a-size > .b-size > .a-inline > span');
test_applied('type(size) name(a) size(height: 32px)', '.a-size > .b-size > .a-inline > span');
</script>

View file

@ -0,0 +1,39 @@
<!doctype html>
<title>@container-dependent elements respond to container size changes</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
container-type: size;
width: 200px;
height: 50px;
}
div { color: red; }
@container size(min-width: 300px) {
div { color: green; }
}
</style>
<main id=container>
<div id=child>
Test
<p><span id=descendant>Deep</span></p>
</div>
</main>
<script>
setup(() => assert_implements_container_queries());
test(function() {
assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)');
container.style.width = '300px';
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
}, 'Children respond to changes in container size');
test(function() {
container.style = '';
assert_equals(getComputedStyle(descendant).color, 'rgb(255, 0, 0)');
container.style.width = '300px';
assert_equals(getComputedStyle(descendant).color, 'rgb(0, 128, 0)');
}, 'Descendants respond to changes in container size');
</script>

View file

@ -0,0 +1,16 @@
<!doctype html>
<title>CSS Container Queries Test: Changing container-type in Chrome legacy layout</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="help" href="https://crbug.com/1286773">
<p>Pass if there is no crash.</p>
<span style="column-count: 1"><table></table></span>
<video id="video"></video>
<input id="input"></input>
<script>
document.body.offsetTop;
video.style.containerType = "inline-size";
document.body.offsetLeft;
video.style.columnCount = "1";
input.setAttribute("type", "button");
document.body.offsetTop;
</script>

View file

@ -0,0 +1,17 @@
<!doctype html>
<meta charset="utf-8">
<title>Computed values of container-type</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="target"></div>
<script>
setup(() => assert_implements_container_queries());
test_computed_value('container-type', 'initial', 'none');
test_computed_value('container-type', 'unset', 'none');
test_computed_value('container-type', 'inline-size');
test_computed_value('container-type', 'size');
</script>

View file

@ -0,0 +1,85 @@
<!doctype html>
<title>CSS Container Queries Test: applied containment for container-type</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
</script>
<style>
/* Note: background colors have no impact on the test result. They are
present to make it easier to visually verify that the test
does the right thing. */
.square {
width: 50px;
height: 50px;
background: tomato;
}
.half {
width: 25px;
height: 50px;
background: red;
}
div > div:nth-of-type(1) { background: skyblue; }
div > div:nth-of-type(2) { background: hotpink; }
</style>
<div id=test1 class=square>
<div id=float1 class=half style="float:left"></div>
<div id=child1 class=half style="container-type:inline-size"></div>
</div>
<script>
test(() => {
assert_equals(child1.offsetLeft, test1.offsetLeft + float1.offsetWidth);
}, 'container-type:inline-size turns on layout containment');
</script>
<hr>
<div id=test2 class=square>
<div id=ref2 style="float:left">A</div>
<div id=child2 style="float:left; container-type:inline-size">A</div>
</div>
<script>
test(() => {
assert_equals(child2.offsetWidth, 0);
assert_equals(child2.offsetHeight, ref2.offsetHeight);
}, 'container-type:inline-size turns on inline-size containment');
</script>
<hr>
<div id=test3 class=square>
<div id=child3 style="float:left; container-type:size">A</div>
</div>
<script>
test(() => {
assert_equals(child3.offsetHeight, 0);
assert_equals(child3.offsetWidth, 0);
}, 'container-type:size turns on full size containment');
</script>
<hr>
<style>
#ref4::before, #child4::before {
content: counter(foo);
}
</style>
<div id=test4 class=square style="counter-set: foo 5">
<div id=ref4 style="float:left"></div>
<section style="container-type:inline-size">
<span style="counter-increment: foo 1000;"></span>
</section>
<section style="container-type:size">
<span style="counter-increment: foo 1000;"></span>
</section>
<div id=child4 style="float:left"></div>
</div>
<script>
test(() => {
assert_equals(child4.offsetWidth, ref4.offsetWidth);
}, 'container-type:inline/size turns on style containment');
</script>

View file

@ -0,0 +1,70 @@
<!doctype html>
<title>container-type invalidation</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
div {
color: black;
}
#outer {
width: 300px;
}
#intermediate {
width: 250px;
}
#inner {
width: 200px;
}
.container {
container-type: inline-size;
}
@container size((max-width: 200px) or (min-width: 300px)) {
#child { color: green; }
}
</style>
<div id=outer>
<div id=intermediate>
<div id=inner>
<div id=child>Test</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(function(t) {
t.add_cleanup(() => {
for (let e of [outer, intermediate, inner])
e.classList.remove('container');
});
// No container.
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
outer.classList.add('container');
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
// The container query does not match widths in the range [201, 299],
// and #intermediate has width:250px.
intermediate.classList.add('container');
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
inner.classList.add('container');
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
// Should have no effect, #inner is the container.
outer.classList.remove('container');
intermediate.classList.remove('container');
assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
inner.classList.remove('container');
assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)');
}, 'Changing the container type invalidates relevant descendants');
</script>

View file

@ -0,0 +1,29 @@
<!doctype html>
<title>container-type layout invalidation</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#div {
width: fit-content;
}
</style>
<div id=div>
content
</div>
<script>
setup(() => assert_implements_container_queries());
test(function(t) {
t.add_cleanup(() => { div.style = ''; });
assert_greater_than(div.offsetWidth, 0);
assert_greater_than(div.offsetHeight, 0);
div.style.containerType = 'size';
assert_equals(div.offsetWidth, 0);
assert_equals(div.offsetHeight, 0);
}, 'Changing container-type invalidates layout');
</script>

View file

@ -0,0 +1,45 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Containment Test: Parsing of container-type</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id="target"></div>
<script>
setup(() => assert_implements_container_queries());
test_valid_value('container-type', 'initial');
test_valid_value('container-type', 'inherit');
test_valid_value('container-type', 'unset');
test_valid_value('container-type', 'revert');
test_valid_value('container-type', 'none');
test_valid_value('container-type', 'style');
test_valid_value('container-type', 'state');
test_valid_value('container-type', 'size');
test_valid_value('container-type', 'inline-size');
test_valid_value('container-type', 'inline-size state');
test_valid_value('container-type', 'style state');
test_valid_value('container-type', 'style inline-size');
test_valid_value('container-type', 'state size');
test_invalid_value('container-type', 'block-size');
test_invalid_value('container-type', 'none none');
test_invalid_value('container-type', 'none inline-size');
test_invalid_value('container-type', 'inline-size none');
test_invalid_value('container-type', 'inline-size inline-size');
test_invalid_value('container-type', 'inline-size block-size');
test_invalid_value('container-type', 'block-size inline-size');
test_invalid_value('container-type', 'size inline-size');
test_invalid_value('container-type', 'inline-size size');
test_invalid_value('container-type', 'none, none');
test_invalid_value('container-type', 'foo');
test_invalid_value('container-type', '"foo"');
test_invalid_value('container-type', 'foo, bar');
test_invalid_value('container-type', '#fff');
test_invalid_value('container-type', '1px');
test_invalid_value('container-type', 'default');
test_invalid_value('container-type', 'size nonsense');
</script>

View file

@ -0,0 +1,70 @@
<!doctype html>
<title>Container Relative Units: Animation</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
container-type: size;
width: 200px;
height: 200px;
}
@keyframes anim_qw { from { top: 20qw; } to { top: 40qw; } }
@keyframes anim_qh { from { top: 20qh; } to { top: 40qh; } }
@keyframes anim_qi { from { top: 20qi; } to { top: 40qi; } }
@keyframes anim_qb { from { top: 20qb; } to { top: 40qb; } }
@keyframes anim_qmin { from { top: 20qmin; } to { top: 40qmin; } }
@keyframes anim_qmax { from { top: 20qmax; } to { top: 40qmax; } }
#container > div {
animation-delay: -5s;
animation-play-state: paused;
animation-duration: 10s;
animation-timing-function: linear;
}
#element_qw { animation-name: anim_qw; }
#element_qh { animation-name: anim_qh; }
#element_qi { animation-name: anim_qi; }
#element_qb { animation-name: anim_qb; }
#element_qmin { animation-name: anim_qmin; }
#element_qmax { animation-name: anim_qmax; }
</style>
<div id=container>
<div id=element_qw></div>
<div id=element_qh></div>
<div id=element_qi></div>
<div id=element_qb></div>
<div id=element_qmin></div>
<div id=element_qmax></div>
</div>
<script>
setup(() => assert_implements_container_queries());
const units = ['qw', 'qh', 'qi', 'qb', 'qmin', 'qmax'];
for (let unit of units) {
test(() => {
let element = document.getElementById(`element_${unit}`)
assert_equals(getComputedStyle(element).top, '60px');
}, `Animation using ${unit} unit`);
test(() => {
let element = document.getElementById(`element_${unit}`)
assert_equals(getComputedStyle(element).top, '60px');
try {
container.style.width = '300px';
container.style.height = '300px';
assert_equals(getComputedStyle(element).top, '90px');
} finally {
container.style = '';
}
assert_equals(getComputedStyle(element).top, '60px');
}, `Animation using ${unit} unit responds to changing container size`);
}
</script>

View file

@ -0,0 +1,54 @@
<!doctype html>
<title>Container Relative Units: qi, qb, etc</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
.inline { container-type: inline-size; }
.size { container-type: size; }
.inline.outer { width: 500px; }
.size.outer { height: 400px; }
.inline.inner { width: 300px; }
</style>
<div id=ref></div>
<div class="inline outer">
<div class="size outer">
<div class="inline inner">
<div id=child>Test</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
function assert_unit_equals(element, actual, expected) {
try {
element.style.padding = actual;
ref.style.padding = expected;
assert_equals(getComputedStyle(element).paddingLeft,
getComputedStyle(ref).paddingLeft);
} finally {
element.style = '';
ref.style = '';
}
}
test(function() {
assert_unit_equals(child, '0qi', '0px');
assert_unit_equals(child, '1qi', '3px');
assert_unit_equals(child, '10qi', '30px');
assert_unit_equals(child, '10qw', '30px');
assert_unit_equals(child, '10qb', '40px');
assert_unit_equals(child, '10qh', '40px');
assert_unit_equals(child, '10qmin', '30px');
assert_unit_equals(child, '10qmax', '40px');
}, 'Container relative units');
test(function() {
assert_unit_equals(child, '10qi', '30px');
assert_unit_equals(child, '10qb', '40px');
assert_unit_equals(child, 'calc(10qi + 10qb)', '70px');
assert_unit_equals(child, 'max(10qi, 10qb)', '40px');
}, 'Container relative units in math functions');
</script>

View file

@ -0,0 +1,20 @@
<!doctype html>
<title>Container Relative Units: Computationally independent</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/#computationally-independent">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
const units = ['qw', 'qh', 'qi', 'qb', 'qmin', 'qmax'];
for (let unit of units) {
test(function() {
assert_throws_dom('SyntaxError', () => {
CSS.registerProperty({ name: '--x', inherits: false, syntax: '<length>', initialValue: `1${unit}` });
});
}, `Container relative unit ${unit} is not computationally independent`);
}
</script>

View file

@ -0,0 +1,103 @@
<!doctype html>
<title>Container Relative Units: Invalidation</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#inline { container-type: inline-size; }
#size, #outer { container-type: size; }
.h600 { height: 600px; }
.w500 { width: 500px; }
.h400 { height: 400px; }
.w300 { width: 300px; }
#child {
padding-left: 10qi;
padding-right: 10qb;
}
</style>
<div id=ref></div>
<div id=outer class="h600">
<div id=size class="w500 h400">
<div id=inline class="w300">
<div id=child>Test</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
function assert_qi_equals(element, expected) {
assert_equals(getComputedStyle(element).paddingLeft, expected);
}
function assert_qb_equals(element, expected) {
assert_equals(getComputedStyle(element).paddingRight, expected);
}
test(function(t) {
assert_qi_equals(child, '30px');
try {
inline.style.containerType = 'none';
assert_qi_equals(child, '50px');
} finally {
inline.style = '';
}
assert_qi_equals(child, '30px');
}, `qi respond when selected container changes type (inline-size -> none)`);
test(function() {
assert_qb_equals(child, '40px');
try {
size.style.containerType = 'none';
assert_qb_equals(child, '60px');
} finally {
size.style = '';
}
assert_qb_equals(child, '40px');
}, `qb respond when selected container changes type (size -> none)`);
test(function() {
assert_qb_equals(child, '40px');
try {
inline.style.containerType = 'size';
inline.style.height = '200px';
assert_qb_equals(child, '20px');
} finally {
inline.style = '';
}
assert_qb_equals(child, '40px');
}, `qb respond when intermediate container changes type (inline-size -> size)`);
test(function() {
assert_qi_equals(child, '30px');
try {
inline.style.width = '50px';
assert_qi_equals(child, '5px');
} finally {
inline.style = '';
}
assert_qi_equals(child, '30px');
}, 'qi respond when selected container changes inline-size');
test(function() {
assert_qb_equals(child, '40px');
try {
size.style.height = '50px';
assert_qb_equals(child, '5px');
} finally {
size.style = '';
}
assert_qb_equals(child, '40px');
}, 'qb respond when selected container changes block-size');
</script>

View file

@ -0,0 +1,129 @@
<!doctype html>
<title>Container Relative Units: Advanced Container Selection</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
* { writing-mode: initial; }
.inline { container-type: inline-size; }
.size { container-type: size; }
.vertical { writing-mode: vertical-rl; }
.w500 { width: 500px; }
.h400 { height: 400px; }
.w300 { width: 300px; }
.h200 { height: 200px; }
.w100 { width: 100px; }
</style>
<div id=ref></div>
<div id=c1>
<div id=c2>
<div id=c3>
<div id=c4>
<div id=child>Test</div>
</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
function assert_unit_equals(element, actual, expected) {
try {
element.style.padding = actual;
ref.style.padding = expected;
assert_equals(getComputedStyle(element).paddingLeft,
getComputedStyle(ref).paddingLeft);
} finally {
element.style = '';
ref.style = '';
}
}
test(() => {
try {
c1.className = 'inline w500'; // Selected by nothing.
c2.className = 'size h400 w300'; // Selected by qh, qb.
c3.className = 'inline w100'; // Selected by qw, qi.
assert_unit_equals(child, '10qw', '10px');
assert_unit_equals(child, '10qi', '10px');
assert_unit_equals(child, '10qh', '40px');
assert_unit_equals(child, '10qb', '40px');
assert_unit_equals(child, '10qmin', '10px');
assert_unit_equals(child, '10qmax', '40px');
c3.className = ''; // qw, qi now selects c2 instead.
assert_unit_equals(child, '10qw', '30px');
assert_unit_equals(child, '10qi', '30px');
assert_unit_equals(child, '10qh', '40px');
assert_unit_equals(child, '10qb', '40px');
assert_unit_equals(child, '10qmin', '30px');
assert_unit_equals(child, '10qmax', '40px');
} finally {
for (let c of [c1, c2, c3, c4, child])
c.className = '';
}
}, 'Container units select the proper container');
test(() => {
try {
c1.className = 'size w500 h400';
c2.className = 'inline w300';
c3.className = 'inline w100 h200 vertical';
// Should select c2, and resolve against w300.
assert_unit_equals(child, '10qw', '30px');
// Should select c3, and resolve against h200.
assert_unit_equals(child, '10qi', '20px');
// Should select c3, and resolve against h200.
assert_unit_equals(child, '10qh', '20px');
// Should select c1, and resolve against h400.
assert_unit_equals(child, '10qb', '40px');
c3.classList.remove('vertical');
// Should select c3, and resolve against w100.
assert_unit_equals(child, '10qw', '10px');
// Should select c3, and resolve against w100.
assert_unit_equals(child, '10qi', '10px');
// Should select c1, and resolve against h400.
assert_unit_equals(child, '10qh', '40px');
// Should select c1, and resolve against h400.
assert_unit_equals(child, '10qb', '40px');
} finally {
for (let c of [c1, c2, c3, c4, child])
c.className = '';
}
}, 'Container with vertical writing mode');
test(() => {
try {
c1.className = 'size w500 h400';
c2.className = 'inline w300';
assert_unit_equals(child, '10qw', '30px');
assert_unit_equals(child, '10qi', '30px');
assert_unit_equals(child, '10qh', '40px');
assert_unit_equals(child, '10qb', '40px');
child.className = 'vertical';
assert_unit_equals(child, '10qw', '30px');
assert_unit_equals(child, '10qi', '30px');
assert_unit_equals(child, '10qh', '40px');
assert_unit_equals(child, '10qb', '40px');
} finally {
for (let c of [c1, c2, c3, c4, child])
c.className = '';
}
}, 'Units are not affected by the writing-mode of the current element');
</script>

View file

@ -0,0 +1,59 @@
<!doctype html>
<title>Container Relative Units: CSS Typed OM</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-lengths">
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#stylepropertymap">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id=element></div>
<script>
setup(() => assert_implements_container_queries());
const units = ['qw', 'qh', 'qi', 'qb', 'qmin', 'qmax'];
const functions = {
qw: CSS.qw,
qh: CSS.qh,
qi: CSS.qi,
qb: CSS.qb,
qmin: CSS.qmin,
qmax: CSS.qmax,
};
for (let unit of units) {
let func = functions[unit];
test(() => {
assert_equals(`${func(10)}`, `10${unit}`);
}, `CSS.${unit} function`);
test(() => {
try {
element.style.top = `10${unit}`;
let value = element.attributeStyleMap.get('top');
assert_equals(value.value, 10);
assert_equals(value.unit, unit);
} finally {
element.style = '';
}
}, `Reify value with ${unit} unit`);
test(() => {
try {
element.attributeStyleMap.set('top', `10${unit}`);
assert_equals(element.style.top, `10${unit}`);
} finally {
element.style = '';
}
}, `Set value with ${unit} unit (string)`);
test(() => {
try {
element.attributeStyleMap.set('top', func(10));
assert_equals(element.style.top, `10${unit}`);
} finally {
element.style = '';
}
}, `Set value with ${unit} unit (CSS.${unit})`);
}
</script>

View file

@ -0,0 +1,76 @@
<!doctype html>
<title>CSS Container Queries Test: counters inside container should not affect container size via flex layout</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<link rel="stylesheet" href="/fonts/ahem.css">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#flex {
width: 200px;
display: flex;
flex-direction: row;
counter-reset: my-count 0;
}
/* #item1 grows to use remaining space given #item2's content */
#item1 {
flex-grow: 1;
height: 100px;
}
#container {
container-type: size;
}
#item2 {
flex-grow: 0;
font: 50px/1 Ahem;
}
/* #item2 size depends on generated content which depends on my-count
counter. */
#item2::before {
display: inline-block;
content: counter(my-count);
}
/* The counter-increment inside the container should not affect the size of
#item2 because of style containment. Otherwise we would have a
circularity. */
@container size(min-width: 125px) {
#inner {
counter-increment: my-count 10;
background-color: green;
}
}
</style>
<div id="flex">
<div id="item1">
<div id="container">
<div id="inner"></div>
</div>
</div>
<div id="item2"></div>
</div>
<script>
setup(() => assert_implements_container_queries());
const item1_width = parseInt(getComputedStyle(item1).width);
const item2_width = parseInt(getComputedStyle(item2).width);
const container_width = parseInt(getComputedStyle(container).width);
const inner_width = parseInt(getComputedStyle(inner).width);
test(() => {
assert_equals(item1_width, container_width);
assert_equals(item1_width, inner_width);
}, "#item1, #container, and #inner should all have the same width: " + item1_width);
test(() => {
let expected_background = container_width >= 125 ? "rgb(0, 128, 0)" : "rgba(0, 0, 0, 0)";
assert_equals(getComputedStyle(inner).backgroundColor, expected_background);
}, "The container query should match the layed out width");
test(() => {
assert_equals(item1_width + item2_width, 200);
}, "The sum of the item widths should match the flexbox width");
test(() => {
assert_equals(parseInt(getComputedStyle(item2, "::before").width), item2_width);
}, "The size of the flex item #2 should be given by its contents");
</script>

View file

@ -0,0 +1,29 @@
<!doctype html>
<title>CSS Container Queries Test: counter updates</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<link rel="match" href="counters-ref.html">
<style>
#container {
container-type: size;
width: 200px;
height: 200px;
}
#counter::before {
content: counter(my-counter);
}
@container size(min-width: 300px) {
#counter {
counter-reset: my-counter 100;
}
}
</style>
<p>Pass if you see the number 100 below.</p>
<div id="container">
<div id="counter"></div>
</div>
<script>
container.offsetTop;
container.style.width = "400px";
</script>

View file

@ -0,0 +1,25 @@
<!doctype html>
<title>CSS Container Queries Test: counters depending on container queries</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-type">
<link rel="match" href="counters-ref.html">
<style>
#container {
container-type: size;
width: 200px;
height: 200px;
}
#counter::before {
content: counter(my-counter);
}
@container size(min-width: 200px) {
#counter {
counter-reset: my-counter 100;
}
}
</style>
<p>Pass if you see the number 100 below.</p>
<div id="container">
<div id="counter"></div>
</div>

View file

@ -0,0 +1,4 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>Pass if you see the number 100 below.</p>
<div>100</div>

View file

@ -0,0 +1,93 @@
<!doctype html>
<title>@container and display:contents</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="help" href="https://drafts.csswg.org/css-contain-2/#containment-size">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
</script>
<style>
.container {
container-type: inline-size;
width: 30px;
height: 30px;
background: tomato;
}
.big {
width: 50px;
height: 50px;
background: skyblue;
}
.contents {
display: none;
}
@container size(width: 30px) {
.target { --x:30; }
}
@container size(width: 50px) {
.target { --x:50; }
}
main {
display: flex;
flex-wrap: wrap;
}
</style>
<main>
<!-- Container is display:contents -->
<div class="container contents">
<div>
<div class="target" id=target1></div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target1);
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when container is display:contents');
</script>
<!-- Container becomes display:contents -->
<div id=container2 class="container">
<div>
<div class="target" id=target2></div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target2);
assert_equals(s.getPropertyValue('--x'), '30');
container2.classList.add('contents');
assert_equals(s.getPropertyValue('--x'), '');
container2.classList.remove('contents');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when container becomes display:contents');
</script>
<!-- Intermediate container becomes display:contents -->
<div class="container">
<div>
<div id=container3 class="container">
<div>
<div class="target" id=target3></div>
</div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target3);
assert_equals(s.getPropertyValue('--x'), '30');
container3.classList.add('contents');
assert_equals(s.getPropertyValue('--x'), '');
container3.classList.remove('contents');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when intermediate container becomes display:contents');
</script>
</main>

View file

@ -0,0 +1,47 @@
<!doctype html>
<title>CSS Test Reference</title>
<style>
.container, .not_a_container {
width: auto;
height: 100px;
border: 1px solid black;
margin-bottom: 10px;
}
span {
border: 1px solid green;
margin: 2px;
}
</style>
<div style="width:150px">
<div class=container>
<main>
<div style="display:flex">
<span style="flex:1">Test1</span>
<span style="flex:1">Test2</span>
<span style="flex:1">Test3</span>
</div>
</main>
</div>
</div>
<div style="width:200px">
<div class=container>
<main>
<div>
<span style="display:block">Test1</span>
<span style="display:block">Test2</span>
<span style="display:block">Test3</span>
</div>
</main>
</div>
</div>
<div style="width:150px">
<div class=not_a_container>
<main>
<div>
<span>Test1</span>
<span>Test2</span>
<span>Test3</span>
</div>
</main>
</div>
</div>

View file

@ -0,0 +1,69 @@
<!doctype html>
<title>CSS Container Queries Test: @container queries affecting display type</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="match" href="display-in-container-ref.html">
<style>
.container, .not_a_container {
width: auto;
height: 100px;
border: 1px solid black;
margin-bottom: 10px;
}
.container {
container-type: size;
}
span {
border: 1px solid green;
margin: 2px;
}
/* Note: 150px - 2px, since .container has a 1px border */
@container size(min-width: 148px) {
div { display: flex; }
span { flex: 1; }
}
/* Note: 200px - 2px, since .container has a 1px border */
@container size(min-width: 198px) {
div { display: revert; }
span { display: block; }
}
/* Should not apply: */
@container size(min-width: 199px) {
* { color: red; background-color: red; }
}
</style>
<div style="width:150px">
<div class=container>
<main>
<div>
<span>Test1</span>
<span>Test2</span>
<span>Test3</span>
</div>
</main>
</div>
</div>
<div style="width:200px">
<div class=container>
<main>
<div>
<span>Test1</span>
<span>Test2</span>
<span>Test3</span>
</div>
</main>
</div>
</div>
<div style="width:150px">
<div class=not_a_container>
<main>
<div>
<span>Test1</span>
<span>Test2</span>
<span>Test3</span>
</div>
</main>
</div>
</div>

View file

@ -0,0 +1,349 @@
<!doctype html>
<title>@container in display:none</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="help" href="https://drafts.csswg.org/css-contain-2/#containment-size">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
</script>
<style>
.container {
container-type: size;
width: 30px;
height: 30px;
background: tomato;
}
.big {
width: 50px;
height: 50px;
background: skyblue;
}
.none {
display: none;
}
.pseudo::before {
content: "foo";
}
.pseudo_none::before {
content: "foo";
display: none;
}
@container size(width: 30px) {
.target { --x:30; }
}
@container size(width: 50px) {
.target { --x:50; }
}
main {
display: flex;
flex-wrap: wrap;
}
</style>
<main>
<!-- Target element is display:none -->
<div class="container">
<div>
<div>
<div class="target none" id=target1></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target1);
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when element is display:none');
</script>
<!-- Parent is display:none -->
<div class="container">
<div>
<div class="none">
<div class="target" id=target2></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target2);
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when parent is display:none');
</script>
<!-- Ancestor is display:none -->
<div class="container">
<div class="none">
<div>
<div class="target" id=target3></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target3);
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when ancestor is display:none');
</script>
<!-- Container is display:none -->
<div class="container none">
<div>
<div>
<div class="target" id=target4></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target4);
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when container is display:none');
</script>
<!-- Target element is display:none in nested container -->
<div class="container big">
<div>
<div>
<div class="container">
<div>
<div>
<div class="target none" id=target5></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target5);
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when element in nested container is display:none');
</script>
<!-- Inner container is display:none -->
<div class="container big">
<div>
<div>
<div class="container none">
<div>
<div>
<div class="target" id=target6></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target6);
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when inner container is display:none');
</script>
<!-- Intermediate ancestor is display:none -->
<div class="container big">
<div class="none">
<div>
<div class="container">
<div>
<div>
<div class="target" id=target7></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target7);
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when intermediate ancestor is display:none');
</script>
<!-- Outer container is display:none -->
<div class="container big none">
<div>
<div>
<div class="container">
<div>
<div>
<div class="target" id=target8></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target8);
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when outer container is display:none');
</script>
<!-- Nothing is display:none initially, but target becomes display:none -->
<div class="container">
<div>
<div>
<div class="target" id=target9></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target9);
assert_equals(s.getPropertyValue('--x'), '30');
target9.classList.add('none');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when element becomes display:none');
</script>
<!-- Nothing is display:none initially, but parent becomes display:none -->
<div class="container">
<div>
<div id=parent10>
<div class="target" id=target10></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target10);
assert_equals(s.getPropertyValue('--x'), '30');
parent10.classList.add('none');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when parent becomes display:none');
</script>
<!-- Nothing is display:none initially, but ancestor becomes display:none -->
<div class="container">
<div id=ancestor11>
<div>
<div class="target" id=target11></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target11);
assert_equals(s.getPropertyValue('--x'), '30');
ancestor11.classList.add('none');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when ancestor becomes display:none');
</script>
<!-- Nothing is display:none initially, but container becomes display:none -->
<div class="container" id=container12>
<div>
<div>
<div class="target" id=target12></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target12);
assert_equals(s.getPropertyValue('--x'), '30');
container12.classList.add('none');
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when container becomes display:none');
</script>
<!-- Intermediate container becomes display:none -->
<div class="container big">
<div>
<div>
<div class="container" id=container13>
<div>
<div>
<div class="target" id=target13></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target13);
assert_equals(s.getPropertyValue('--x'), '30');
container13.classList.add('none');
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle when intermediate container becomes display:none');
</script>
<!-- Pseudo-element is display:none -->
<div class="container">
<div>
<div>
<div class="target pseudo_none" id=target14></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target14, '::before');
assert_equals(s.getPropertyValue('content'), '"foo"');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when ::before is display:none');
</script>
<!-- Pseudo-element with display:none originating element -->
<div class="container">
<div>
<div>
<div class="target pseudo none" id=target15></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target15, '::before');
assert_equals(s.getPropertyValue('content'), '"foo"');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle when originating element is display:none');
</script>
<!-- Pseudo-element with display:none ancestor -->
<div class="container">
<div class="none">
<div>
<div class="target pseudo" id=target16></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target16, '::before');
assert_equals(s.getPropertyValue('content'), '"foo"');
assert_equals(s.getPropertyValue('--x'), '30');
}, 'getComputedStyle on ::before when ancestor element is display:none');
</script>
<!-- Pseudo-element with in display:none container -->
<div class="container none">
<div>
<div>
<div class="target pseudo" id=target17></div>
</div>
</div>
</div>
<script>
test(function() {
let s = getComputedStyle(target17, '::before');
assert_equals(s.getPropertyValue('content'), '"foo"');
assert_equals(s.getPropertyValue('--x'), '');
}, 'getComputedStyle on ::before when container is display:none');
</script>
</main>

View file

@ -0,0 +1,4 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>Pass if the rendered legend below is "PASS"</p>
<fieldset style="width:400px"><legend>PASS</legend></fieldset>

View file

@ -0,0 +1,26 @@
<!doctype html>
<title>CSS Container Queries Test: inline-size query changes rendered legend in fieldset</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="match" href="fieldset-legend-change-ref.html">
<p>Pass if the rendered legend below is "PASS"</p>
<style>
fieldset {
width: 200px;
container-type: inline-size;
}
.wide { width: 400px; }
@container size(min-width: 300px) {
#fail {
display: none;
}
}
</style>
<fieldset id="fieldset">
<legend id="fail">FAIL</legend>
<legend>PASS</legend>
</fieldset>
<script>
fieldset.offsetTop;
fieldset.className = "wide";
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
display: flex;
}
}
</style>
<div id="container" style="columns:2; container-type:inline-size; width:600px;">
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
container.style.width = "400px";
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
display: flex;
}
}
</style>
<div id="container" style="columns:2; container-type:inline-size; width:400px;">
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
container.style.width = "600px";
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 250px) {
#target {
display: flex;
}
}
</style>
<div id="ancestor" style="columns:2; column-gap:0; width:600px;">
<div style="container-type:inline-size;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
ancestor.style.width = "400px";
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 250px) {
#target {
display: flex;
}
}
</style>
<div id="ancestor" style="columns:2; column-gap:0; width:400px;">
<div style="container-type:inline-size;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
ancestor.style.width = "600px";
</script>

View file

@ -0,0 +1,42 @@
<!doctype html>
<title>Container Queries Test: size change detected while focusing inside content-visibility: auto container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="help" href="https://drafts.csswg.org/css-contain-2/#using-cv-auto">
<link rel="help" href="https://crbug.com/1270848">
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
<style>
.spacer { height: 3000px; }
.auto { content-visibility: auto; }
#container {
border: 1px solid black;
width: 100px;
height: 100px;
container-type: size;
}
#input {
width: 100%;
visibility: hidden;
}
@container size(min-width: 150px) {
#input { visibility: visible; }
}
</style>
<div class=spacer></div>
<div class=auto>
<div id=container>
<input id=input type=text></input>
</div>
</div>
<script>
function focus() {
container.style.width = "200px";
input.focus();
}
onload = () => requestAnimationFrame(() => requestAnimationFrame(focus));
</script>

View file

@ -0,0 +1,53 @@
<!doctype html>
<title>CSS Container Queries Test: font-relative units - dynamic</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
:root { font-size: 10px; }
:root.larger { font-size: 50px; }
body.larger { font-size: 20px; }
#container {
container-type: inline-size;
width: 100px;
color: red;
}
@container size(width: 5em) {
#em_test { color: green }
}
@container size(width: 2rem) {
#rem_test { color: green }
}
@container size(max-width: 15ex) {
#ex_test { color: green }
}
@container size(max-width: 15ch) {
#ch_test { color: green }
}
</style>
<div id="container">
<div id="em_test"></div>
<div id="rem_test"></div>
<div id="ex_test"></div>
<div id="ch_test"></div>
</div>
<script>
setup(() => assert_implements_container_queries());
const green = "rgb(0, 128, 0)";
const red = "rgb(255, 0, 0)";
test(() => assert_equals(getComputedStyle(em_test).color, red), "em relative before change");
test(() => assert_equals(getComputedStyle(rem_test).color, red), "rem relative before change");
test(() => assert_equals(getComputedStyle(ex_test).color, red), "ex relative before change");
test(() => assert_equals(getComputedStyle(ch_test).color, red), "ch relative before change");
document.documentElement.className = "larger";
document.body.className = "larger";
test(() => assert_equals(getComputedStyle(em_test).color, green), "em relative after change");
test(() => assert_equals(getComputedStyle(rem_test).color, green), "rem relative after change");
test(() => assert_equals(getComputedStyle(ex_test).color, green), "ex relative after change");
test(() => assert_equals(getComputedStyle(ch_test).color, green), "ch relative after change");
</script>

View file

@ -0,0 +1,55 @@
<!doctype html>
<title>CSS Container Queries Test: font-relative units</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
:root { font-size: 10px; }
#em_container {
container-type: inline-size;
width: 100px;
font-size: 100px;
}
#ex_container {
container-type: inline-size;
font-size: 50px;
width: 10ex;
}
#ch_container {
container-type: inline-size;
font-size: 50px;
width: 10ch;
}
@container size(width: 1em) {
#em_test { color: green }
}
@container size(width: 10rem) {
#rem_test { color: green }
}
@container size(width: 10ex) {
#ex_test { color: green }
}
@container size(width: 10ch) {
#ch_test { color: green }
}
</style>
<div id="em_container">
<div id="em_test"></div>
<div id="rem_test"></div>
</div>
<div id="ex_container">
<div id="ex_test"></div>
</div>
<div id="ch_container">
<div id="ch_test"></div>
</div>
<script>
setup(() => assert_implements_container_queries());
const green = "rgb(0, 128, 0)";
test(() => assert_equals(getComputedStyle(em_test).color, green), "em relative inline-size");
test(() => assert_equals(getComputedStyle(rem_test).color, green), "rem relative inline-size");
test(() => assert_equals(getComputedStyle(ex_test).color, green), "ex relative inline-size");
test(() => assert_equals(getComputedStyle(ch_test).color, green), "ch relative inline-size");
</script>

View file

@ -0,0 +1,34 @@
<!doctype html>
<title>getAnimations depending on container query</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
container-type: inline-size;
width: 100px;
}
#div { color: red; }
@keyframes test {
from { color: green; }
to { color: green; }
}
@container size(min-width: 200px) {
#div { animation: test 1s linear forwards; }
}
</style>
<div id=container>
<div id=div>Green</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(div).color, 'rgb(255, 0, 0)');
container.style = 'width:300px';
assert_equals(div.getAnimations().length, 1);
assert_equals(getComputedStyle(div).color, 'rgb(0, 128, 0)');
}, 'Calling getAnimations updates layout of parent frame if needed');
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
display: grid;
}
}
</style>
<div id="container" style="columns:2; container-type:inline-size; width:600px;">
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
container.style.width = "400px";
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
display: grid;
}
}
</style>
<div id="container" style="columns:2; container-type:inline-size; width:400px;">
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
container.style.width = "600px";
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 250px) {
#target {
display: grid;
}
}
</style>
<div id="ancestor" style="columns:2; column-gap:0; width:600px;">
<div style="container-type:inline-size;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
ancestor.style.width = "400px";
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 250px) {
#target {
display: grid;
}
}
</style>
<div id="ancestor" style="columns:2; column-gap:0; width:400px;">
<div style="container-type:inline-size;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
ancestor.style.width = "600px";
</script>

View file

@ -0,0 +1,43 @@
<!doctype html>
<title>@container-dependent elements respond to iframe size changes</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
iframe {
width: 200px;
height: 40px;
}
</style>
<iframe id=iframe srcdoc="
<style>
div#container {
container-type: size;
height: 20px;
}
div#child { color: red; }
@container size(min-width: 300px) {
div#child { color: green; }
}
</style>
<div id=container>
<div id=child>Test</div>
</div>
"></iframe>
<script>
setup(() => assert_implements_container_queries());
function waitForLoad(w) {
return new Promise(resolve => w.addEventListener('load', resolve));
}
promise_test(async () => {
await waitForLoad(window);
let inner_div = iframe.contentDocument.querySelector('div#child');
assert_equals(getComputedStyle(inner_div).color, 'rgb(255, 0, 0)');
iframe.style = 'width:400px';
assert_equals(getComputedStyle(inner_div).color, 'rgb(0, 128, 0)');
})
</script>

View file

@ -0,0 +1,51 @@
<!doctype html>
<title>Containers ineligible for containment</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="help" href="https://drafts.csswg.org/css-contain-2/#containment-size">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#outer, #inner1, #inner2 {
width: 200px;
container-type: inline-size;
}
#inner1 {
display: table;
}
p {
color: green;
}
@container size(min-width: 1px) {
p { color: red; }
}
</style>
<div id=outer>
<div id=inner1>
<p id=p1>Test1</p>
</div>
<div id=inner2>
<p id=p2>Test1</p>
</div>
</main>
<script>
setup(() => assert_implements_container_queries());
test(function(t) {
// #inner1 is the container, but it does not satisfy the containment
// requirements, hence the query should fail.
assert_equals(getComputedStyle(p1).color, 'rgb(0, 128, 0)');
}, 'Container ineligible for containment');
test(function(t) {
t.add_cleanup(() => { inner2.style = ''; });
assert_equals(getComputedStyle(p2).color, 'rgb(255, 0, 0)');
inner2.style = 'display:table';
// #inner2 is still the container, but it no longer satisfies the
// containment requirements.
assert_equals(getComputedStyle(p2).color, 'rgb(0, 128, 0)');
}, 'Changing containment eligibility invalidates style');
</script>

View file

@ -0,0 +1,21 @@
<!doctype html>
<title>CSS Container Queries Test: Inline multicol inside size container - crash</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="help" href="https://crbug.com/829028">
<style>
#container {
container-type: size;
width: 200px;
height: 100px;
}
@container size(width <= 200px) {
#multicol {
column-count: 2;
column-gap: 0;
}
}
</style>
<p>Test passes if it doesn't crash.</p>
<div id="container">
<span id="multicol"><div></div></span>
</div>

View file

@ -0,0 +1,26 @@
<!doctype html>
<title>CSS Container Queries Test: query of inline-size container is affected by min-width property</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
container-type: inline-size;
min-width: 200px;
width: fit-content;
}
@container size(min-width: 200px) {
#child { color: green }
}
</style>
<div id="container">
<div id="child">Green</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(child).color, "rgb(0, 128, 0)");
}, "min-width of inline-size container affects container size");
</script>

View file

@ -0,0 +1,9 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>You should see the text "no red" to the left of the third float and no red.</p>
<div style="width:400px">
<div style="float:right;width:200px;height:150px;background:blue"></div>
<div style="float:left;width:250px;height:100px;background:blue"></div>
<div style="float:right;width:300px;height:100px;background:blue"></div>
<div style="height:200px;display:flow-root">No red</div>
</div>

View file

@ -0,0 +1,47 @@
<!doctype html>
<title>CSS Container Queries Test: inline-size constrained by floats - layout moving forwards</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#containment-inline-size">
<link rel="match" href="inline-size-bfc-floats-ref.html">
<style>
.float { float: left; background-color: blue; }
.right { float: right; }
#outer { width: 400px; }
#float1 { width: 200px; height: 150px; }
#float2 { width: 250px; height: 100px; }
#float3 { width: 300px; height: 100px; }
#container { container-type: inline-size; }
/* Initially, text + 200px of red content (#content1 + #content2) is too tall
to make #container fit by #float1 */
.content { height: 100px; background-color: red; }
/* Trying to fit #container beside #float2 causes the width to remove
#content1. text + 100px of red content (#content2) is too tall to fit
beside #float2. It would at this point fit beside #float1, but that would
cause the width to increase again, and the spec says layout always moves
forward. */
@container size(width < 200px) {
#content1 { display: none }
}
/* Trying to fit #container beside #float3 causes the rest of the red content
(#content2) to disappear. */
@container size(width < 150px) {
#content2 { display: none }
}
</style>
<p>You should see the text "no red" to the left of the third float and no red.</p>
<div id="outer">
<div id="float1" class="float right"></div>
<div id="float2" class="float left"></div>
<div id="float3" class="float right"></div>
<div id="container">
No red
<div id="content1" class="content"></div>
<div id="content2" class="content"></div>
</div>
</div>

View file

@ -0,0 +1,38 @@
<!doctype html>
<title>CSS Container Queries Test: query of inline-size container in vertical-rl</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<style>
#ancestry { writing-mode: vertical-rl; }
#keg { container-type: inline-size; }
@container size(max-height: 200px) {
#target { width: 400px; }
}
@container size(min-height: 400px) {
#target { width: 20px; }
}
</style>
<div id="ancestry">
<div id="keg">
<div id="target">
<div style="width:50px;"></div>
</div>
</div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
test(()=> {
ancestry.style.height = "100px";
assert_equals(keg.offsetWidth, 400);
ancestry.style.height = "300px";
assert_equals(keg.offsetWidth, 50);
ancestry.style.height = "500px";
assert_equals(keg.offsetWidth, 20);
}, "inline-size containment only");
</script>

View file

@ -0,0 +1,37 @@
<!doctype html>
<title>CSS Container Queries Test: query of inline-size container is affected by min-width property</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<style>
#keg { container-type: inline-size; }
@container size(max-width: 200px) {
#target { height: 400px; }
}
@container size(min-width: 400px) {
#target { height: 20px; }
}
</style>
<div id="ancestry">
<div id="keg">
<div id="target">
<div style="height:50px;"></div>
</div>
</div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
test(()=> {
ancestry.style.width = "100px";
assert_equals(keg.offsetHeight, 400);
ancestry.style.width = "300px";
assert_equals(keg.offsetHeight, 50);
ancestry.style.width = "500px";
assert_equals(keg.offsetHeight, 20);
}, "inline-size containment only");
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
columns: 2;
}
}
</style>
<div id="container" style="container-type:inline-size; width:600px;">
<span id="target"></span>
</div>
<script>
document.body.offsetTop;
container.style.width = "400px";
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
columns: 2;
}
}
</style>
<div id="container" style="container-type:inline-size; width:400px;">
<span id="target"></span>
</div>
<script>
document.body.offsetTop;
container.style.width = "600px";
</script>

View file

@ -0,0 +1,14 @@
<!doctype html>
<title>CSS Container Queries Test: </title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="help" href="https://crbug.com/1282782">
<p>Pass if this test does not crash</p>
<span style="column-count: 1">
<span style="display:table-column-group"></span>
<input id="inp">
</span>
<script>
document.body.offsetTop;
document.body.style.setProperty("container", "inline-size");
inp.setAttribute("type", "image");
</script>

View file

@ -0,0 +1,28 @@
<!doctype html>
<title>CSS Container Queries Test: Multicol inside size container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
<style>
#container {
container-type: size;
width: 200px;
height: 100px;
}
@container size(width <= 200px) {
#multicol {
column-count: 2;
column-gap: 0;
}
}
#green {
display: inline-block;
width: 100%;
height: 100px;
background-color: green;
vertical-align: bottom;
}
</style>
<p>Test passes if there is a filled green square.</p>
<div id="container">
<div id="multicol"><div id="green"></div></div>
</div>

View file

@ -0,0 +1,38 @@
<!doctype html>
<title>CSS Container Queries Test: Orthogonal writing-mode change in @container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
#container {
container-type: size;
width: 50vw;
height: 50vh;
}
#orthogonal {
font: 50px/1 Ahem;
}
@container size(max-width: 100px) {
#orthogonal {
writing-mode: vertical-lr;
}
}
</style>
<div id="container">
<div id="orthogonal">XX</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(orthogonal.offsetWidth, container.offsetWidth);
}, "Initial non-orthogonal width");
test(() => {
container.style.width = "100px";
assert_equals(orthogonal.offsetWidth, 50);
assert_not_equals(orthogonal.offsetWidth, container.offsetWidth);
}, "Orthogonal width");
</script>

View file

@ -0,0 +1,66 @@
<!doctype html>
<title>CSS Container Queries Test: @container queries affecting height affecting percentage padding</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#vertical {
width: 500px;
writing-mode: vertical-lr;
}
#padded {
width: 100%;
box-sizing: border-box;
padding-right: 100%;
background-color: orange;
}
#horizontal {
writing-mode: horizontal-tb;
width: 100%;
}
#container {
width: 100%;
container-type: inline-size;
background-color: green;
}
#first, #second { height: 50px; }
@container size(width <= 400px) {
#second { display: none; }
}
</style>
<div id="vertical">
<div id="padded">
<div id="horizontal">
<div id="container">
<div id="first"></div>
<div id="second"></div>
</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => assert_equals(padded.offsetHeight, 100),
"#container height measured with 500px width. Both container children visible");
test(() => assert_equals(container.offsetWidth, 400),
"#container width 400px after padding is applied.");
test(() => assert_equals(container.offsetHeight, 50),
"#container width 400px after padding is applied. #second is removed from the rendering");
// Reduce width by 1px to test that a re-layout is not stateful.
vertical.style.width = "399px";
test(() => assert_equals(padded.offsetHeight, 100),
"#container height measured with 499px width. Both container children visible");
test(() => assert_equals(container.offsetWidth, 399),
"#container width 399px after padding is applied. #second is removed from the rendering");
test(() => assert_equals(container.offsetHeight, 50),
"#container width 399x after padding is applied. #second is removed from the rendering");
</script>

View file

@ -0,0 +1,14 @@
<!doctype html>
<title>CSS Container Queries Test: No crash when ::after is a container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#query-container">
<link rel="help" href="https://crbug.com/1225381">
<style>
div::after {
container-type: size;
content: '';
display: block;
}
</style>
<div>
PASS if no crash
</div>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<title>CSS Container Queries Test: Container for elements with pseudo elements</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#query-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
:root {
color: black;
}
.container {
container-type: size;
width: 200px;
height: 40px;
}
@container size(min-width: 300px) {
#container1 div::before { content: "before"; }
#container1 div::after { content: "after"; }
#container2 li::marker { color: green; }
}
</style>
<main id=container1 class=container>
<div>test</div>
</main>
<main id=container2 class=container>
<ol>
<li>One</li>
</ol>
</main>
<script>
setup(() => assert_implements_container_queries());
test(function() {
let div = document.querySelector('#container1 > div');
assert_equals(getComputedStyle(div, '::before').content, 'none');
assert_equals(getComputedStyle(div, '::after').content, 'none');
container1.style.width = '300px';
assert_equals(getComputedStyle(div, '::before').content, '"before"');
assert_equals(getComputedStyle(div, '::after').content, '"after"');
container1.style = '';
assert_equals(getComputedStyle(div, '::before').content, 'none');
assert_equals(getComputedStyle(div, '::after').content, 'none');
}, 'Pseudo-elements ::before and ::after respond to container size changes');
test(function() {
let li = document.querySelector('#container2 li');
assert_equals(getComputedStyle(li, '::marker').color, 'rgb(0, 0, 0)');
container2.style.width = '300px';
assert_equals(getComputedStyle(li, '::marker').color, 'rgb(0, 128, 0)');
container2.style = '';
assert_equals(getComputedStyle(li, '::marker').color, 'rgb(0, 0, 0)');
}, 'Pseudo-element ::marker responds to container size changes');
</script>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<title>CSS Test Reference</title>
<div>PASS</div>
<div>PASS</div>
<div>PASS</div>
<div>PASS</div>
<div><span style="color:green">P</span>ASS if P is green.</div>
<div><span style="color:green">P</span>ASS if P is green.</div>
<div><span style="color:green">P</span>ASS if P is green.</div>
<div><span style="color:green">P</span>ASS if P is green.</div>
<div style="color:green">PASS if text is green.</div>
<div style="color:green">PASS if text is green.</div>
<div style="color:green">PASS if text is green.</div>
<div style="color:green">PASS if text is green.</div>

View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<title>CSS Container Queries Test: Container for pseudo elements</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6711">
<link rel="match" href="pseudo-elements-002.tentative-ref.html">
<style>
.container { container-type: inline-size; }
@container size(max-width: 100px) { #c1::before { content: "PASS" } }
@container size(min-width: 150px) { #c1::before { content: "FAIL" } }
@container size(max-width: 100px) { #c2::before { content: "PASS" } }
@container size(min-width: 150px) { #c2::before { content: "FAIL" } }
@container size(max-width: 100px) { #c3::after { content: "PASS" } }
@container size(min-width: 150px) { #c3::after { content: "FAIL" } }
@container size(max-width: 100px) { #c4::after { content: "PASS" } }
@container size(min-width: 150px) { #c4::after { content: "FAIL" } }
@container size(max-width: 300px) { #c5::first-letter { color: green } }
@container size(max-width: 300px) { #c6::first-letter { color: green } }
@container size(min-width: 400px) { #c7::first-letter { color: green } }
@container size(min-width: 400px) { #c8::first-letter { color: green } }
@container size(max-width: 300px) { #c9::first-line { color: green } }
@container size(max-width: 300px) { #c10::first-line { color: green } }
@container size(min-width: 400px) { #c11::first-line { color: green } }
@container size(min-width: 400px) { #c12::first-line { color: green } }
</style>
<div id="c1" class="container" style="width:100px"></div>
<div id="c2" class="container" style="width:200px"></div>
<div id="c3" class="container" style="width:100px"></div>
<div id="c4" class="container" style="width:200px"></div>
<div class="container" style="width:400px">
<div id="c5" class="container" style="width:300px">PASS if P is green.</div>
</div>
<div class="container" style="width:400px">
<div id="c6" class="container" style="width:400px">PASS if P is green.</div>
</div>
<div id="c7" class="container" style="width:400px">
<div class="container" style="width:300px">PASS if P is green.</div>
</div>
<div id="c8" class="container" style="width:300px">
<div class="container" style="width:300px">PASS if P is green.</div>
</div>
<div class="container" style="width:400px">
<div id="c9" class="container" style="width:300px">PASS if text is green.</div>
</div>
<div class="container" style="width:400px">
<div id="c10" class="container" style="width:400px">PASS if text is green.</div>
</div>
<div id="c11" class="container" style="width:400px">
<div class="container" style="width:300px">PASS if text is green.</div>
</div>
<div id="c12" class="container" style="width:300px">
<div class="container" style="width:300px">PASS if text is green.</div>
</div>
<script>
document.body.offsetTop;
c2.style.width = "100px";
c4.style.width = "100px";
c6.style.width = "300px";
c8.style.width = "400px";
c10.style.width = "300px";
c12.style.width = "400px";
</script>

View file

@ -0,0 +1,68 @@
<!doctype html>
<title>@container: originating element container for pseudo elements</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6711">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
.container { container-type: inline-size; }
#target { display: list-item; }
@container size(max-width: 200px) {
#target::before { content: "PASS"; color: green; }
#target::after { color: green; }
#target::marker { color: green; }
#target::first-line { color: green; }
#target::first-letter { color: green; }
}
@container size((min-width: 300px) and (max-width: 350px)) {
#outer::first-line { color: green; }
#outer::first-letter { color: green; }
}
dialog::backdrop { background-color: lime; }
@container size(max-width: 100px) {
dialog::backdrop { background-color: green; }
}
</style>
<div style="width: 400px" class="container">
<div style="width: 300px" class="container">
<div id="target" class="container" style="width: 200px">First-line</div>
<dialog id="dialog" class="container" style="width: 100px"></dialog>
</div>
<div style="width: 400px" class="container">
<div id="outer" style="width: 300px" class="container">
<div class="container" style="width: 200px">First-line</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
const green = "rgb(0, 128, 0)";
const lime = "rgb(0, 255, 0)";
test(() => {
assert_equals(getComputedStyle(target, "::before").color, green);
}, "Originating element container for ::before");
test(() => {
assert_equals(getComputedStyle(target, "::after").color, green);
}, "Originating element container for ::after");
test(() => {
assert_equals(getComputedStyle(target, "::marker").color, green);
}, "Originating element container for ::marker");
test(() => {
assert_equals(getComputedStyle(target, "::first-line").color, green);
}, "Originating element container for ::first-line");
test(() => {
assert_equals(getComputedStyle(target, "::first-letter").color, green);
}, "Originating element container for ::first-letter");
test(() => {
assert_equals(getComputedStyle(outer, "::first-line").color, green);
}, "Originating element container for outer ::first-line");
test(() => {
assert_equals(getComputedStyle(outer, "::first-letter").color, green);
}, "Originating element container for outer ::first-letter");
test(() => {
assert_equals(getComputedStyle(dialog, "::backdrop").backgroundColor, lime, "::backdrop not rendered");
dialog.showModal();
assert_equals(getComputedStyle(dialog, "::backdrop").backgroundColor, green, "::backdrop rendered");
}, "Originating element container for ::backdrop");
</script>

View file

@ -0,0 +1,80 @@
<!doctype html>
<title>CSS Container Queries Test: Size queries match content-box</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
.container {
container-type: size;
border: 10px solid black;
padding: 40px;
margin: 20px;
}
#container1 {
box-sizing: content-box;
width: 100px;
height: 100px;
}
#container2 {
box-sizing: border-box;
width: 200px;
height: 200px;
}
#container3 {
box-sizing: content-box;
width: 100px;
height: 100px;
overflow: scroll;
}
#container4 {
box-sizing: border-box;
width: 200px;
height: 200px;
overflow: scroll;
}
@container size((width = 100px) and (height = 100px)) {
.target {
background-color: green;
height: 100%;
}
}
</style>
<div id="container1" class="container">
<div class="target"></div>
</div>
<div id="container2" class="container">
<div class="target"></div>
</div>
<div id="container3" class="container">
<div class="target"></div>
</div>
<div id="container4" class="container">
<div class="target"></div>
</div>
<script>
setup(() => assert_implements_container_queries());
const green = "rgb(0, 128, 0)";
test(() => {
assert_equals(getComputedStyle(document.querySelector("#container1 > .target")).backgroundColor, green);
}, "Size queries with content-box sizing");
test(() => {
assert_equals(getComputedStyle(document.querySelector("#container2 > .target")).backgroundColor, green);
}, "Size queries with border-box sizing");
test(() => {
assert_equals(getComputedStyle(document.querySelector("#container3 > .target")).backgroundColor, green);
}, "Size queries with content-box sizing and overflow:scroll");
test(() => {
assert_equals(getComputedStyle(document.querySelector("#container4 > .target")).backgroundColor, green);
}, "Size queries with border-box sizing and overflow:scroll");
</script>

View file

@ -0,0 +1,128 @@
<!doctype html>
<title>Evaluation of queries</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-rule">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
width: 1px;
height: 0px;
container-type: size;
--applied:false;
}
</style>
<div id=container>
<div id=inner></div>
</div>
<script>
setup(() => assert_implements_container_queries());
function test_query(query, expected) {
test((t) => {
let style = document.createElement('style');
t.add_cleanup(() => { style.remove(); });
style.innerText = `@container ${query} { #inner { --applied:true; } }`;
let cs = getComputedStyle(inner);
assert_equals(cs.getPropertyValue('--applied'), 'false');
document.head.append(style);
assert_equals(cs.getPropertyValue('--applied'), expected.toString());
}, query);
};
// We don't care about specific features in this file, only higher level
// evaluation like "and", "or", and so forth. The features "width", "height"
// and "unknown" are arbitrarily chosen to represent true, false, and
// unknown values, respectively.
test_query('size(width)', true);
test_query('size(height)', false);
test_query('size(unknown)', false);
test_query('unknown(width)', false);
// Nesting in <container-query>:
test_query('(size(width))', true);
test_query('(size(height))', false);
test_query('(size(unknown))', false);
test_query('(((size(width))))', true);
test_query('(((size(height))))', false);
test_query('(((size(unknown))))', false);
// "not" in <container-query>:
test_query('(not size(width))', false);
test_query('(not size(height))', true);
test_query('(not size(unknown))', false);
test_query('(not unknown(width))', false);
// "and" in <container-query>:
test_query('(size(width) and size(width))', true);
test_query('(size(width) and size(width) and size(width))', true);
test_query('(size(height) and size(height))', false);
test_query('(size(height) and size(width) and size(width))', false);
test_query('(size(width) and size(height) and size(width))', false);
test_query('(size(width) and size(width) and size(height))', false);
test_query('(size(unknown) and size(width) and size(width))', false);
test_query('(size(width) and size(unknown) and size(width))', false);
test_query('(size(width) and size(width) and size(unknown))', false);
// "or" in <container-query>:
test_query('(size(width) or size(width))', true);
test_query('(size(width) or size(width) or size(width))', true);
test_query('(size(height) or size(height))', false);
test_query('(size(height) or size(width) or size(width))', true);
test_query('(size(width) or size(height) or size(width))', true);
test_query('(size(width) or size(width) or size(height))', true);
test_query('(size(unknown) or size(width) or size(width))', true);
test_query('(size(width) or size(unknown) or size(width))', true);
test_query('(size(width) or size(width) or size(unknown))', true);
test_query('(size(unknown) or size(height) or size(width))', true);
// Combinations, <container-query>:
test_query('(not (size(width) and size(width)))', false);
test_query('(not (size(width) and size(height)))', true);
test_query('(size(width) and (not (size(height) or size(width))))', false);
test_query('(size(height) or (not (size(height) and size(width))))', true);
test_query('(size(height) or (size(height) and size(width)))', false);
// Nesting in <size-query>:
test_query('size((width))', true);
test_query('size((height))', false);
test_query('size((unknown))', false);
test_query('unknown((width))', false);
// "not" in <size-query>:
test_query('size(not (width))', false);
test_query('size(not (height))', true);
test_query('size(not (unknown))', false);
// "and" in <size-query>:
test_query('size((width) and (width))', true);
test_query('size((width) and (width) and (width))', true);
test_query('size((height) and (height))', false);
test_query('size((height) and (width) and (width))', false);
test_query('size((width) and (height) and (width))', false);
test_query('size((width) and (width) and (height))', false);
test_query('size((unknown) and (width) and (width))', false);
test_query('size((width) and (unknown) and (width))', false);
test_query('size((width) and (width) and (unknown))', false);
// "or" in <size-query>:
test_query('size((width) or (width))', true);
test_query('size((width) or (width) or (width))', true);
test_query('size((height) or (height))', false);
test_query('size((height) or (width) or (width))', true);
test_query('size((width) or (height) or (width))', true);
test_query('size((width) or (width) or (height))', true);
test_query('size((unknown) or (width) or (width))', true);
test_query('size((width) or (unknown) or (width))', true);
test_query('size((width) or (width) or (unknown))', true);
test_query('size((unknown) or (height) or (width))', true);
// Combinations, <size-query>:
test_query('size(not ((width) and (width)))', false);
test_query('size(not ((width) and (height)))', true);
test_query('size((width) and (not ((height) or (width))))', false);
test_query('size((height) or (not ((height) and (width))))', true);
test_query('size((height) or ((height) and (width)))', false);
</script>

View file

@ -0,0 +1,37 @@
<!doctype html>
<title>CSS Container Queries Test: @container changing display type while descendant styles change</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
container-type: inline-size;
}
@container size(min-width: 200px) {
div { color: red }
}
@container size(max-width: 150px) {
div { color: lime }
}
</style>
<div id="container">
<div id="child"><span id="inner">XXX</span></div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
container.offsetTop;
assert_equals(getComputedStyle(child).color, "rgb(255, 0, 0)");
}, "Initially wider than 200px");
test(() => {
container.style.width = "100px";
container.style.display = "inline-block";
inner.style.color = "green";
container.offsetTop;
assert_equals(getComputedStyle(child).color, "rgb(0, 255, 0)");
assert_equals(getComputedStyle(inner).color, "rgb(0, 128, 0)");
}, "Container query changed and inner.style applied");
</script>

View file

@ -0,0 +1,3 @@
<!doctype html>
<title>CSS Test Reference</title>
<div style="width:200px;height:200px;background:green"></div>

View file

@ -0,0 +1,53 @@
<!doctype html>
<html class="reftest-wait">
<title>CSS Container Queries Test: condition change while content-visibility: hidden</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="help" href="https://drafts.csswg.org/css-contain-2/#content-visibility">
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
<link rel="match" href="resize-while-content-visibility-hidden-ref.html">
<link rel="assert" content="Container query applies even if container is content-visibility: hidden">
<script src="/common/reftest-wait.js"></script>
<style>
#container {
container-name: container;
container-type: size;
width: 300px;
height: 300px;
}
#child {
width: 200px;
height: 200px;
background: red;
}
#container.wide { width: 500px; }
.locked { content-visibility: hidden; }
@container container size(min-width: 400px) { #child { background: green; } }
</style>
<div id=container>
<div id=child></div>
</div>
<script>
async function runTest() {
await new Promise(requestAnimationFrame);
container.classList.add("locked");
await new Promise(requestAnimationFrame);
container.classList.add("wide");
await new Promise(requestAnimationFrame);
container.classList.remove("locked");
await new Promise(requestAnimationFrame);
takeScreenshot();
}
requestAnimationFrame(() => { requestAnimationFrame(() => runTest()) });
</script>

View file

@ -0,0 +1,45 @@
<!doctype html>
<title>CSS Container Queries Test: size container types apply to elements without a principal box</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#outer {
container-type: inline-size;
}
#inner_none {
display: none;
container-type: inline-size;
}
#inner_contents {
display: contents;
container-type: inline-size;
}
@container size(min-width: 0) {
span { color: red; }
}
@container size(min-width: 0) {
#ref { color: green; }
}
</style>
<div id="outer">
<div id="ref"></div>
<div id="inner_none"><span></span></div>
<div id="inner_contents"><span></span></div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(ref).color, "rgb(0, 128, 0)");
}, "Check that container queries is supported");
test(() => {
assert_equals(getComputedStyle(inner_none.firstChild).color, "rgb(0, 0, 0)");
}, "(min-width: 0) does not match a container without a principal box (display:none)");
test(() => {
assert_equals(getComputedStyle(inner_contents.firstChild).color, "rgb(0, 0, 0)");
}, "(min-width: 0) does not match a container without a principal box (display:contents)");
</script>

View file

@ -0,0 +1,91 @@
<!doctype html>
<title>Evaluation of size features</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<div id=container>
<div id=target>
Test
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
function test_evaluation(container_class, query, expected) {
test(function(t) {
let style_node = document.createElement('style');
t.add_cleanup(() => {
container.classList.remove(container_class);
style_node.remove();
});
style_node.innerText = `@container ${query} { #target { --applied:true; } }`;
assert_equals(getComputedStyle(target).getPropertyValue('--applied'), '');
container.classList.add(container_class);
document.head.append(style_node);
assert_equals(getComputedStyle(target).getPropertyValue('--applied'), expected ? 'true' : '');
}, `${query} (.${container_class})`);
}
</script>
<style>
.horizontal {
width: 100px;
height: 200px;
container-type: size;
}
.vertical {
width: 100px;
height: 200px;
container-type: size;
writing-mode: vertical-rl;
}
</style>
<script>
for (let cls of ['horizontal', 'vertical']) {
let logical_width = (cls == 'horizontal') ? 'inline' : 'block';
let logical_height = (cls == 'horizontal') ? 'block' : 'inline';
test_evaluation(cls, 'size(width < 100px)', false);
test_evaluation(cls, 'size(width >= 100px)', true);
test_evaluation(cls, 'size(min-width: 100px)', true);
test_evaluation(cls, 'size(min-width: 101px)', false);
test_evaluation(cls, 'size(max-width: 100px)', true);
test_evaluation(cls, 'size(max-width: 99px)', false);
test_evaluation(cls, 'size(height < 200px)', false);
test_evaluation(cls, 'size(height >= 200px)', true);
test_evaluation(cls, 'size(min-height: 200px)', true);
test_evaluation(cls, 'size(min-height: 201px)', false);
test_evaluation(cls, 'size(max-height: 200px)', true);
test_evaluation(cls, 'size(max-height: 199px)', false);
test_evaluation(cls, `size(${logical_width}-size < 100px)`, false);
test_evaluation(cls, `size(${logical_width}-size >= 100px)`, true);
test_evaluation(cls, `size(min-${logical_width}-size: 100px)`, true);
test_evaluation(cls, `size(min-${logical_width}-size: 101px)`, false);
test_evaluation(cls, `size(max-${logical_width}-size: 100px)`, true);
test_evaluation(cls, `size(max-${logical_width}-size: 99px)`, false);
test_evaluation(cls, `size(${logical_height}-size < 200px)`, false);
test_evaluation(cls, `size(${logical_height}-size >= 200px)`, true);
test_evaluation(cls, `size(min-${logical_height}-size: 200px)`, true);
test_evaluation(cls, `size(min-${logical_height}-size: 201px)`, false);
test_evaluation(cls, `size(max-${logical_height}-size: 200px)`, true);
test_evaluation(cls, `size(max-${logical_height}-size: 199px)`, false);
test_evaluation(cls, 'size(orientation: landscape)', false);
test_evaluation(cls, 'size(orientation: portrait)', true);
test_evaluation(cls, 'size(aspect-ratio: 1/2)', true);
test_evaluation(cls, 'size(aspect-ratio: 2/1)', false);
}
</script>

View file

@ -0,0 +1,28 @@
<!doctype html>
<title>CSS Container Queries Test: recompute style inside a @container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container { container-type: size; }
@container size(min-width: 1px) {
#content { color: green; }
}
</style>
<div id="container">
<div id="content"></div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(content).color, "rgb(0, 128, 0)");
// Dirty style of an element inside the container:
content.style.backgroundColor = "lime";
// The container query should still evaluate correctly:
assert_equals(getComputedStyle(content).color, 'rgb(0, 128, 0)');
}, "Basic test for container query evaluation stability");
</script>

View file

@ -0,0 +1,3 @@
function assert_implements_container_queries() {
assert_implements(CSS.supports("container-type:size"), "Basic support for container queries required");
}

View file

@ -0,0 +1,22 @@
<!doctype html>
<title>@container changing display of SVG element should not crash</title>
<link rel="help" href="https://crbug.com/1245689">
<iframe id="frame" style="width: 200px"></iframe>
<script>
frame.srcdoc = `
<style>
#container {
container-type: inline-size;
}
@container size(min-width: 300px) {
.hide { display: none; }
}
</style>
<div id="container">
<div class="hide"><svg></svg></div>
</div>`;
requestAnimationFrame(() =>
requestAnimationFrame(() =>
requestAnimationFrame(() => frame.style.width = "400px")));
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
display: table;
}
}
</style>
<div id="container" style="columns:2; container-type:inline-size; width:600px;">
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
container.style.width = "400px";
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 500px) {
#target {
display: table;
}
}
</style>
<div id="container" style="columns:2; container-type:inline-size; width:400px;">
<div id="target"></div>
</div>
<script>
document.body.offsetTop;
container.style.width = "600px";
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 250px) {
#target {
display: table;
}
}
</style>
<div id="ancestor" style="columns:2; column-gap:0; width:600px;">
<div style="container-type:inline-size;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
ancestor.style.width = "400px";
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1276898">
<style>
@container size(max-width: 250px) {
#target {
display: table;
}
}
</style>
<div id="ancestor" style="columns:2; column-gap:0; width:400px;">
<div style="container-type:inline-size;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
ancestor.style.width = "600px";
</script>

View file

@ -0,0 +1,4 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>You should see the word PASS below.</p>
<table><td>PASS</td></table>

View file

@ -0,0 +1,16 @@
<!doctype html>
<title>CSS Container Queries Test: table inside @container changing display type</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="help" href="https://crbug.com/1284918">
<link rel="match" href="table-inside-container-changing-display-ref.html">
<p>You should see the word PASS below.</p>
<div id="container" style="width: 200px; height: 200px; container-type:inline-size;">
<div>
<table><td>PASS</td></table>
</div>
</div>
<script>
document.body.offsetTop;
document.querySelector("#container").style.display = "inline-block";
document.querySelector("table").style.color = "currentColor";
</script>

View file

@ -0,0 +1,3 @@
<!doctype html>
<html style="background:green">
<title>CSS Test Reference</title>

View file

@ -0,0 +1,20 @@
<!doctype html>
<title>CSS Container Queries Test: ::backdrop depending on @container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="match" href="top-layer-dialog-backdrop-ref.html">
<style>
html { background: green; }
#container { container-type: inline-size; }
@container size(max-width: 200px) {
::backdrop { display: none; }
#dialog { visibility: hidden; }
}
</style>
<div id="container">
<dialog id="dialog"></dialog>
</div>
<script>
dialog.showModal();
dialog.offsetTop;
container.style.width = "100px";
</script>

View file

@ -0,0 +1,33 @@
<!doctype html>
<title>CSS Container Queries Test: Top layer element as a @container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#parent { width: 100px; }
#dialog {
container-type: inline-size;
width: auto;
border: none;
}
#child { color: red; }
@container size(min-width: 200px) {
#child { color: green; }
}
</style>
<div id="parent">
<dialog id="dialog"><span id="child"></span></dialog>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(child).color, "rgb(255, 0, 0)");
}, "#dialog initially sized by #containing-block");
test(() => {
dialog.showModal();
assert_equals(getComputedStyle(child).color, "rgb(0, 128, 0)");
}, "#dialog sized by viewport");
</script>

View file

@ -0,0 +1,45 @@
<!doctype html>
<title>CSS Container Queries Test: @container with modal dialog child</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#container {
container-type: inline-size;
}
dialog {
color: red;
}
@container size(max-width: 200px) {
dialog { color: green; }
}
@container size(max-width: 100px) {
dialog { color: lime; }
}
</style>
<div id="container">
<dialog id="dialog"></dialog>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(dialog).color, "rgb(255, 0, 0)");
}, "#container initially wider than 200px");
test(() => {
container.style.width = "200px";
assert_equals(getComputedStyle(dialog).color, "rgb(0, 128, 0)");
}, "#container changed to 200px");
test(() => {
dialog.showModal();
assert_equals(getComputedStyle(dialog).color, "rgb(0, 128, 0)");
}, "Modal dialog still has parent as query container while in top layer");
test(() => {
container.style.width = "100px";
assert_equals(getComputedStyle(dialog).color, "rgb(0, 255, 0)");
}, "Container changes width while dialog is in top layer");
</script>

View file

@ -0,0 +1,45 @@
<!doctype html>
<title>CSS Container Queries Test: Nested top layer elements and @container</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
dialog { color: red; }
#container { width: 100px; }
#container, #outer { container-type: inline-size; }
@container size(min-width: 200px) {
#outer { width: 400px; color: lime; }
}
@container size(min-width: 400px) {
#inner { color: green; }
}
</style>
<div id="container">
<dialog id="outer">
<dialog id="inner"></dialog>
</dialog>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
assert_equals(getComputedStyle(outer).color, "rgb(255, 0, 0)");
assert_equals(getComputedStyle(inner).color, "rgb(255, 0, 0)");
}, "Dialogs initially not matching for container queries");
test(() => {
container.offsetTop;
outer.showModal();
inner.showModal();
assert_equals(getComputedStyle(outer).color, "rgb(255, 0, 0)");
assert_equals(getComputedStyle(inner).color, "rgb(255, 0, 0)");
}, "Dialogs still not matching after showModal");
test(() => {
container.offsetTop;
container.style.width = "200px";
assert_equals(getComputedStyle(outer).color, "rgb(0, 255, 0)");
assert_equals(getComputedStyle(inner).color, "rgb(0, 128, 0)");
}, "@container queries start matching");
</script>

View file

@ -0,0 +1,59 @@
<!doctype html>
<title>Container Queries - Scrollbars do not cause transitions</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/#starting">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#scrollable {
overflow: auto;
width: 100px;
height: 100px;
}
#container {
container-type: inline-size;
}
#target {
background-color: black;
}
/* Matches with or without a scrollbar: */
@container size(max-width: 100px) {
#target {
background-color: blue;
}
}
/* Matches only when there's a scrollbar: */
@container size(max-width: 99px) {
#target {
background-color: green;
font-size: 10px;
transition: 2s steps(2, start) background-color;
}
}
</style>
<div id=scrollable>
<div id=container>
<div id=target>
Foo bar foo bar foo
Foo bar foo bar foo
Foo bar foo bar foo
Foo bar foo bar foo
Foo bar foo bar foo
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
test(() => {
// Whether or not a scrollbar appeared is out of scope for this test.
// The only thing we care about is that no transition was triggered.
// Therefore we allow both 'green' and 'blue', but not any other values.
let has_scrollbar = target.offsetWidth < 100;
let expected = has_scrollbar ? 'rgb(0, 128, 0)' : 'rgb(0, 0, 255)';
assert_equals(getComputedStyle(target).backgroundColor, expected);
}, 'Scrollbars do not cause a transition of background-color');
</script>

View file

@ -0,0 +1,58 @@
<!doctype html>
<meta charset="utf-8">
<title>Container Queries - Style Change Event for transitions</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/#starting">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#animated-containers">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
.container { container-type: size }
#outer {
width: 100px;
color: green;
}
@container size(min-width: 200px) {
#inner { color: red }
}
@container size(min-width: 400px) {
#target {
color: green;
transition: color 1s step-start;
}
}
</style>
<div id="outer" class="container">
<div id="inner" class="container">
<div id="target">Green</div>
</div>
</div>
</div>
<script>
setup(() => assert_implements_container_queries());
const t = async_test("");
const event_handler = t.step_func_done((e) => {
assert_unreached("Transition event incorrectly triggered: " + e.type);
});
for (let event_name of ["transitionrun",
"transitionstart",
"transitionend",
"transitioncancel"]) {
target.addEventListener(event_name, event_handler);
}
outer.offsetTop;
// #target is green. Making the #outer container 200px will turn #inner and
// #target red through inheritance.
outer.style.width = "200px";
// Making #inner 400px will make #target green.
inner.style.width = "400px";
// Both changes above should happen in one style change event and should not
// trigger any transition events. Run two rAFs to make sure any events have
// time to trigger.
requestAnimationFrame(() => requestAnimationFrame(t.step_func_done(() => {
assert_equals(getComputedStyle(inner).color, "rgb(255, 0, 0)",
"@container queries supported");
})));
</script>

View file

@ -0,0 +1,171 @@
<!doctype html>
<title>Query against unsupported axis</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<script>
setup(() => assert_implements_container_queries());
</script>
<style>
#container {
width: 200px;
height: 100px;
container-type: inline-size;
}
</style>
<div id=container>
<div id=target>
Test
</div>
</div>
<style>
@container size(width > 0px) {
#target { --width:true; }
}
</style>
<script>
test(function(t) {
assert_equals(getComputedStyle(target).getPropertyValue('--width'), 'true');
}, 'size(width > 0px)');
</script>
<style>
@container size(height > 0px) {
#target { --height:true; }
}
</style>
<script>
test(function(t) {
// container-type:inline-size does not support queries along the block
// axis.
assert_equals(getComputedStyle(target).getPropertyValue('--height'), '');
}, 'size(height > 0px)');
</script>
<style>
@container size((height > 0px) or (width > 0px)) {
#target { --height-or-width:true; }
}
</style>
<script>
test(function(t) {
// (height > 0px) should evaluate to "unknown".
assert_equals(getComputedStyle(target).getPropertyValue('--height-or-width'), 'true');
}, 'size((height > 0px) or (width > 0px))');
</script>
<style>
@container size((width > 0px) or (height > 0px)) {
#target { --width-or-height:true; }
}
</style>
<script>
test(function(t) {
// (height > 0px) should evaluate to "unknown".
assert_equals(getComputedStyle(target).getPropertyValue('--width-or-height'), 'true');
}, 'size((width > 0px) or (height > 0px))');
</script>
<style>
@container size((orientation: landscape) or (width > 0px)) {
#target { --orientation-or-width:true; }
}
</style>
<script>
test(function(t) {
// (orientation: landscape) depends on both axes, and should evaluate
// to "unknown".
assert_equals(getComputedStyle(target).getPropertyValue('--orientation-or-width'), 'true');
}, 'size((orientation: landscape) or (width > 0px))');
</script>
<style>
@container size((width > 0px) or (orientation: landscape)) {
#target { --width-or-orientation:true; }
}
</style>
<script>
test(function(t) {
// (orientation: landscape) depends on both axes, and should evaluate
// to "unknown".
assert_equals(getComputedStyle(target).getPropertyValue('--width-or-orientation'), 'true');
}, 'size((width > 0px) or (orientation: landscape))');
</script>
<style>
@container size((height > 0px) or (orientation: landscape)) {
#target { --height-or-orientation:true; }
}
</style>
<script>
test(function(t) {
assert_equals(getComputedStyle(target).getPropertyValue('--height-or-orientation'), '');
}, 'size((height > 0px) or (orientation: landscape))');
</script>
<style>
@container size((height > 0px) or (orientation: landscape)) {
#target { --height-or-orientation2:true; }
}
</style>
<script>
test(function(t) {
// Adding full size containment via the 'contain' property does not
// make 'height' queryable. (Limited by container-type:inline-size).
t.add_cleanup(() => { target.style = ''; });
target.style.contain = 'size';
assert_equals(getComputedStyle(target).getPropertyValue('--height-or-orientation2'), '');
}, 'size((height > 0px) or (orientation: landscape)), with contain:size');
</script>
<style>
@container size(inline-size > 0px) {
#target { --inline-size:true; }
}
</style>
<script>
test(function(t) {
assert_equals(getComputedStyle(target).getPropertyValue('--inline-size'), 'true');
}, 'size(inline-size > 0px)');
</script>
<style>
@container size(block-size > 0px) {
#target { --block-size:true; }
}
</style>
<script>
test(function(t) {
// container-type:inline-size does not support queries along the block
// axis.
assert_equals(getComputedStyle(target).getPropertyValue('--block-size'), '');
}, 'size(block-size > 0px)');
</script>
<style>
@container size(block-size > 0px) {
#target { --block-size2:true; }
}
</style>
<script>
test(function(t) {
// Changing the writing-mode does not affect the evaluation of block-size.
t.add_cleanup(() => { target.style = ''; });
target.style.writingMode = 'vertical-rl';
assert_equals(getComputedStyle(target).getPropertyValue('--block-size2'), '');
}, 'size(block-size > 0px), with writing-mode:vertical-rl');
</script>

View file

@ -0,0 +1,59 @@
<!doctype html>
<title>CSS Container Queries Test: @container-dependent elements respond to viewport unit changes</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
iframe {
width: 100px;
height: 100px;
}
</style>
<iframe id="iframe" srcdoc="
<style>
#vw, #vh {
container-type: inline-size;
width: 100px;
}
@container size(min-width: 50vw) {
#vw span { color: green }
}
@container size(min-width: 100vw) {
#vw span { color: red }
}
@container size(min-width: 50vh) {
#vh span { color: green }
}
@container size(min-width: 100vh) {
#vh span { color: red }
}
</style>
<div id=vw><span>Green</span></div>
<div id=vh><span>Green</span></div>
"></iframe>
<script>
setup(() => assert_implements_container_queries());
function waitForLoad(w) {
return new Promise(resolve => w.addEventListener('load', resolve));
}
promise_test(async () => {
await waitForLoad(window);
const vw_child = iframe.contentDocument.querySelector("#vw > span");
const vh_child = iframe.contentDocument.querySelector("#vh > span");
assert_equals(getComputedStyle(vw_child).color, "rgb(255, 0, 0)", "vw before resize");
assert_equals(getComputedStyle(vh_child).color, "rgb(255, 0, 0)", "vh before resize");
iframe.style.width = "200px";
assert_equals(getComputedStyle(vw_child).color, "rgb(0, 128, 0)", "vw after width resize");
assert_equals(getComputedStyle(vh_child).color, "rgb(255, 0, 0)", "vh after width resize");
iframe.style.height = "200px";
assert_equals(getComputedStyle(vw_child).color, "rgb(0, 128, 0)", "vw after height resize");
assert_equals(getComputedStyle(vh_child).color, "rgb(0, 128, 0)", "vh after height resize");
});
</script>

View file

@ -0,0 +1,33 @@
<!doctype html>
<title>CSS Container Queries Test: viewport units</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#size-container">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/cq-testcommon.js"></script>
<style>
#vw { container-type: inline-size; width: 10vw; }
#vh { container-type: inline-size; width: 10vh; }
@container size(min-width: 10vw) {
#vw span { color: green }
}
@container size(min-width: 11vw) {
#vw span { color: red }
}
@container size(min-width: 10vh) {
#vh span { color: green }
}
@container size(min-width: 11vh) {
#vh span { color: red }
}
</style>
<div id="vw"><span>Green</span></div>
<div id="vh"><span>Green</span></div>
<script>
setup(() => assert_implements_container_queries());
const green = "rgb(0, 128, 0)";
test(() => assert_equals(getComputedStyle(vw.firstChild).color, green), "Match width with vw");
test(() => assert_equals(getComputedStyle(vh.firstChild).color, green), "Match width with vh");
</script>

View file

@ -0,0 +1,24 @@
<!doctype html>
<title>CSS Container Queries Test: whitespace changes in container which changes evaluation</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#container-queries">
<link rel="match" href="change-display-in-container-ref.html">
<style>
#container {
container-type: size;
width: 400px;
height: 200px;
}
@container size(min-width: 400px) {
span { color: red; }
}
</style>
<p>You should see the word PASS below.</p>
<div id="container"><span id="fail">FAIL</span> <span>PASS</span></div>
<script>
container.offsetTop;
container.style.width = "200px";
// The space text node between the two spans no longer takes up space when the
// first span is removed.
fail.remove();
</script>