LibWeb: Implement CSS 'contain' property

This commit is contained in:
Psychpsyo 2025-01-18 20:39:26 +01:00 committed by Sam Atkins
parent c53c781745
commit 67ed676831
Notes: github-actions[bot] 2025-01-28 11:25:39 +00:00
154 changed files with 4200 additions and 117 deletions

View file

@ -1360,6 +1360,74 @@ Optional<CSS::Isolation> ComputedProperties::isolation() const
return keyword_to_isolation(value.to_keyword());
}
CSS::Containment ComputedProperties::contain() const
{
CSS::Containment containment = {};
auto const& value = property(CSS::PropertyID::Contain);
switch (value.to_keyword()) {
case Keyword::None:
// This value indicates that the property has no effect. The element renders as normal, with no containment effects applied.
return {};
case Keyword::Strict:
// This value computes to 'size layout paint style', and thus turns on all forms of containment for the element.
containment.size_containment = true;
containment.layout_containment = true;
containment.paint_containment = true;
containment.style_containment = true;
break;
case Keyword::Content:
// This value computes to 'layout paint style', and thus turns on all forms of containment except size containment for the element.
containment.layout_containment = true;
containment.paint_containment = true;
containment.style_containment = true;
break;
case Keyword::Size:
containment.size_containment = true;
break;
case Keyword::InlineSize:
containment.inline_size_containment = true;
break;
case Keyword::Layout:
containment.layout_containment = true;
break;
case Keyword::Style:
containment.style_containment = true;
break;
case Keyword::Paint:
containment.paint_containment = true;
break;
default:
if (value.is_value_list()) {
auto& values = value.as_value_list().values();
for (auto const& item : values) {
switch (item->to_keyword()) {
case Keyword::Size:
containment.size_containment = true;
break;
case Keyword::InlineSize:
containment.inline_size_containment = true;
break;
case Keyword::Layout:
containment.layout_containment = true;
break;
case Keyword::Style:
containment.style_containment = true;
break;
case Keyword::Paint:
containment.paint_containment = true;
break;
default:
dbgln("`{}` is not supported in `contain` (yet?)", item->to_string(CSSStyleValue::SerializationMode::Normal));
break;
}
}
}
}
return containment;
}
Optional<CSS::MaskType> ComputedProperties::mask_type() const
{
auto const& value = property(CSS::PropertyID::MaskType);

View file

@ -161,6 +161,7 @@ public:
Optional<CSS::WritingMode> writing_mode() const;
Optional<CSS::UserSelect> user_select() const;
Optional<CSS::Isolation> isolation() const;
CSS::Containment contain() const;
static Vector<CSS::Transformation> transformations_for_style_value(CSSStyleValue const& value);
Vector<CSS::Transformation> transformations() const;

View file

@ -66,6 +66,18 @@ struct ObjectPosition {
CSS::LengthPercentage offset_y { Percentage(50) };
};
// https://drafts.csswg.org/css-contain-2/#containment-types
struct Containment {
// FIXME: It'd be nice if this was a single-byte bitfield instead of some bools.
bool size_containment = false;
bool inline_size_containment = false;
bool layout_containment = false;
bool style_containment = false;
bool paint_containment = false;
bool is_empty() const { return !(size_containment || inline_size_containment || layout_containment || style_containment || paint_containment); }
};
class InitialValues {
public:
static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; }
@ -172,6 +184,7 @@ public:
static CSS::WritingMode writing_mode() { return CSS::WritingMode::HorizontalTb; }
static CSS::UserSelect user_select() { return CSS::UserSelect::Auto; }
static CSS::Isolation isolation() { return CSS::Isolation::Auto; }
static CSS::Containment contain() { return {}; }
// https://www.w3.org/TR/SVG/geometry.html
static LengthPercentage cx() { return CSS::Length::make_px(0); }
@ -428,6 +441,7 @@ public:
CSS::WritingMode writing_mode() const { return m_inherited.writing_mode; }
CSS::UserSelect user_select() const { return m_noninherited.user_select; }
CSS::Isolation isolation() const { return m_noninherited.isolation; }
CSS::Containment const& contain() const { return m_noninherited.contain; }
CSS::LengthBox const& inset() const { return m_noninherited.inset; }
const CSS::LengthBox& margin() const { return m_noninherited.margin; }
@ -681,6 +695,7 @@ protected:
CSS::UnicodeBidi unicode_bidi { InitialValues::unicode_bidi() };
CSS::UserSelect user_select { InitialValues::user_select() };
CSS::Isolation isolation { InitialValues::isolation() };
CSS::Containment contain { InitialValues::contain() };
Optional<CSS::Transformation> rotate;
Optional<CSS::Transformation> translate;
@ -855,6 +870,7 @@ public:
void set_writing_mode(CSS::WritingMode value) { m_inherited.writing_mode = value; }
void set_user_select(CSS::UserSelect value) { m_noninherited.user_select = value; }
void set_isolation(CSS::Isolation value) { m_noninherited.isolation = value; }
void set_contain(CSS::Containment value) { m_noninherited.contain = move(value); }
void set_fill(SVGPaint value) { m_inherited.fill = move(value); }
void set_stroke(SVGPaint value) { m_inherited.stroke = move(value); }

View file

@ -62,6 +62,11 @@ public:
bool is_table_cell() const { return is_internal() && internal() == DisplayInternal::TableCell; }
bool is_table_column_group() const { return is_internal() && internal() == DisplayInternal::TableColumnGroup; }
bool is_table_caption() const { return is_internal() && internal() == DisplayInternal::TableCaption; }
// https://drafts.csswg.org/css-display-3/#internal-table-element
bool is_internal_table() const
{
return is_internal() && (internal() == DisplayInternal::TableRowGroup || internal() == DisplayInternal::TableHeaderGroup || internal() == DisplayInternal::TableFooterGroup || internal() == DisplayInternal::TableRow || internal() == DisplayInternal::TableCell || internal() == DisplayInternal::TableColumnGroup || internal() == DisplayInternal::TableColumn);
}
bool is_none() const { return m_type == Type::Box && m_value.box == DisplayBox::None; }
bool is_contents() const { return m_type == Type::Box && m_value.box == DisplayBox::Contents; }

View file

@ -107,6 +107,16 @@
"none",
"all"
],
"contain": [
"none",
"strict",
"content",
"size",
"inline-size",
"layout",
"style",
"paint"
],
"content-visibility": [
"visible",
"auto",

View file

@ -210,6 +210,7 @@
"inline-end",
"inline-flex",
"inline-grid",
"inline-size",
"inline-start",
"inline-table",
"inset",
@ -235,6 +236,7 @@
"landscape",
"large",
"larger",
"layout",
"left",
"legacy",
"less",
@ -308,6 +310,7 @@
"p3",
"padding-box",
"paged",
"paint",
"paused",
"petite-caps",
"pixelated",
@ -366,6 +369,7 @@
"sideways-lr",
"sideways-rl",
"simplified",
"size",
"slashed-zero",
"slider-horizontal",
"slow",
@ -389,7 +393,9 @@
"static",
"sticky",
"stretch",
"strict",
"stroke-box",
"style",
"sub",
"subtractive",
"super",

View file

@ -923,6 +923,16 @@
"column-count"
]
},
"contain": {
"__comment": "FIXME: Some values of contain need to be mutually exclusive. The grammar this should adhere to is 'none | strict | content | [ [size | inline-size] || layout || style || paint ]'.",
"affects-stacking-context": true,
"animation-type": "none",
"inherited": false,
"initial": "none",
"valid-types": [
"contain"
]
},
"content": {
"animation-type": "discrete",
"inherited": false,

View file

@ -1190,9 +1190,21 @@ static void propagate_scrollbar_width_to_viewport(Element& root_element, Layout:
viewport_computed_values.set_scrollbar_width(root_element_computed_values.scrollbar_width());
}
// https://drafts.csswg.org/css-overflow-3/#overflow-propagation
static void propagate_overflow_to_viewport(Element& root_element, Layout::Viewport& viewport)
{
// https://drafts.csswg.org/css-overflow-3/#overflow-propagation
// https://drafts.csswg.org/css-contain-2/#contain-property
// Additionally, when any containments are active on either the HTML <html> or <body> elements, propagation of
// properties from the <body> element to the initial containing block, the viewport, or the canvas background, is
// disabled. Notably, this affects:
// - 'overflow' and its longhands (see CSS Overflow 3 §3.3 Overflow Viewport Propagation)
if (root_element.is_html_html_element() && !root_element.computed_properties()->contain().is_empty())
return;
auto* body_element = root_element.first_child_of_type<HTML::HTMLBodyElement>();
if (body_element && !body_element->computed_properties()->contain().is_empty())
return;
// UAs must apply the overflow-* values set on the root element to the viewport
// when the root elements display value is not none.
auto overflow_origin_node = root_element.layout_node();

View file

@ -2741,6 +2741,148 @@ bool Element::is_relevant_to_the_user()
return false;
}
// https://drafts.csswg.org/css-contain-2/#skips-its-contents
bool Element::skips_its_contents()
{
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-hidden
// The element skips its contents.
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Hidden)
return true;
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
// If the element is not relevant to the user, it also skips its contents.
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto && !this->is_relevant_to_the_user()) {
return true;
}
return false;
}
// https://drafts.csswg.org/css-contain-2/#containment-size
bool Element::has_size_containment() const
{
// However, giving an element size containment has no effect if any of the following are true:
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
if (!layout_node())
return false;
// - if its inner display type is 'table'
if (layout_node()->display().is_table_inside())
return false;
// - if its principal box is an internal table box
if (layout_node()->display().is_internal_table())
return false;
// - if its principal box is an internal ruby box or a non-atomic inline-level box
// FIXME: Implement this.
if (computed_properties()->contain().size_containment)
return true;
return false;
}
// https://drafts.csswg.org/css-contain-2/#containment-inline-size
bool Element::has_inline_size_containment() const
{
// Giving an element inline-size containment has no effect if any of the following are true:
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
if (!layout_node())
return false;
// - if its inner display type is 'table'
if (layout_node()->display().is_table_inside())
return false;
// - if its principal box is an internal table box
if (layout_node()->display().is_internal_table())
return false;
// - if its principal box is an internal ruby box or a non-atomic inline-level box
// FIXME: Implement this.
if (computed_properties()->contain().inline_size_containment)
return true;
return false;
}
// https://drafts.csswg.org/css-contain-2/#containment-layout
bool Element::has_layout_containment() const
{
// However, giving an element layout containment has no effect if any of the following are true:
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
if (!layout_node())
return false;
// - if its principal box is an internal table box other than 'table-cell'
if (layout_node()->display().is_internal_table() && !layout_node()->display().is_table_cell())
return false;
// - if its principal box is an internal ruby box or a non-atomic inline-level box
// FIXME: Implement this.
if (computed_properties()->contain().layout_containment)
return true;
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
// Changes the used value of the 'contain' property so as to turn on layout containment, style containment, and
// paint containment for the element.
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto)
return true;
return false;
}
// https://drafts.csswg.org/css-contain-2/#containment-style
bool Element::has_style_containment() const
{
// However, giving an element style containment has no effect if any of the following are true:
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
if (!layout_node())
return false;
if (computed_properties()->contain().style_containment)
return true;
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
// Changes the used value of the 'contain' property so as to turn on layout containment, style containment, and
// paint containment for the element.
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto)
return true;
return false;
}
// https://drafts.csswg.org/css-contain-2/#containment-paint
bool Element::has_paint_containment() const
{
// However, giving an element paint containment has no effect if any of the following are true:
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
if (!layout_node())
return false;
// - if its principal box is an internal table box other than 'table-cell'
if (layout_node()->display().is_internal_table() && !layout_node()->display().is_table_cell())
return false;
// - if its principal box is an internal ruby box or a non-atomic inline-level box
// FIXME: Implement this
if (computed_properties()->contain().paint_containment)
return true;
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
// Changes the used value of the 'contain' property so as to turn on layout containment, style containment, and
// paint containment for the element.
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto)
return true;
return false;
}
bool Element::id_reference_exists(String const& id_reference) const
{
return document().get_element_by_id(id_reference);
@ -3154,6 +3296,12 @@ void Element::resolve_counters(CSS::ComputedProperties& style)
for (auto const& counter : counter_reset)
ensure_counters_set().instantiate_a_counter(counter.name, unique_id(), counter.is_reversed, counter.value);
// FIXME: Take style containment into account
// https://drafts.csswg.org/css-contain-2/#containment-style
// Giving an element style containment has the following effects:
// 1. The 'counter-increment' and 'counter-set' properties must be scoped to the elements sub-tree and create a
// new counter.
// 3. Counter values are incremented (counter-increment).
auto counter_increment = style.counter_data(CSS::PropertyID::CounterIncrement);
for (auto const& counter : counter_increment)

View file

@ -398,6 +398,16 @@ public:
void determine_proximity_to_the_viewport();
bool is_relevant_to_the_user();
// https://drafts.csswg.org/css-contain-2/#skips-its-contents
bool skips_its_contents();
// https://drafts.csswg.org/css-contain-2/#containment-types
bool has_size_containment() const;
bool has_inline_size_containment() const;
bool has_layout_containment() const;
bool has_style_containment() const;
bool has_paint_containment() const;
protected:
Element(Document&, DOM::QualifiedName);
virtual void initialize(JS::Realm&) override;

View file

@ -6,6 +6,7 @@
#include <LibWeb/Bindings/HTMLHtmlElementPrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/HTML/HTMLBodyElement.h>
#include <LibWeb/HTML/HTMLHtmlElement.h>
#include <LibWeb/Layout/Node.h>
@ -28,6 +29,18 @@ void HTMLHtmlElement::initialize(JS::Realm& realm)
bool HTMLHtmlElement::should_use_body_background_properties() const
{
// https://drafts.csswg.org/css-contain-2/#contain-property
// Additionally, when any containments are active on either the HTML <html> or <body> elements, propagation of
// properties from the <body> element to the initial containing block, the viewport, or the canvas background, is
// disabled. Notably, this affects:
// - 'background' and its longhands (see CSS Backgrounds 3 §2.11.2 The Canvas Background and the HTML <body> Element)
if (!computed_properties()->contain().is_empty())
return false;
auto* body_element = first_child_of_type<HTML::HTMLBodyElement>();
if (body_element && !body_element->computed_properties()->contain().is_empty())
return false;
auto background_color = layout_node()->computed_values().background_color();
auto const& background_layers = layout_node()->background_layers();

View file

@ -28,6 +28,37 @@ Box::~Box()
{
}
Optional<CSSPixels> Box::natural_width() const
{
// https://drafts.csswg.org/css-contain-2/#containment-size
// Replaced elements must be treated as having a natural width and height of 0 and no natural aspect
// ratio.
if (dom_node() && dom_node()->is_element() && as<DOM::Element>(dom_node())->has_size_containment())
return 0;
return m_natural_width;
}
Optional<CSSPixels> Box::natural_height() const
{
// https://drafts.csswg.org/css-contain-2/#containment-size
// Replaced elements must be treated as having a natural width and height of 0 and no natural aspect
// ratio.
if (dom_node() && dom_node()->is_element() && as<DOM::Element>(dom_node())->has_size_containment())
return 0;
return m_natural_height;
}
Optional<CSSPixelFraction> Box::natural_aspect_ratio() const
{
// https://drafts.csswg.org/css-contain-2/#containment-size
// Replaced elements must be treated as having a natural width and height of 0 and no natural aspect
// ratio.
if (dom_node() && dom_node()->is_element() && as<DOM::Element>(dom_node())->has_size_containment())
return {};
return m_natural_aspect_ratio;
}
void Box::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);

View file

@ -25,9 +25,9 @@ public:
Painting::PaintableBox* paintable_box();
// https://www.w3.org/TR/css-images-3/#natural-dimensions
Optional<CSSPixels> natural_width() const { return m_natural_width; }
Optional<CSSPixels> natural_height() const { return m_natural_height; }
Optional<CSSPixelFraction> natural_aspect_ratio() const { return m_natural_aspect_ratio; }
Optional<CSSPixels> natural_width() const;
Optional<CSSPixels> natural_height() const;
Optional<CSSPixelFraction> natural_aspect_ratio() const;
bool has_natural_width() const { return natural_width().has_value(); }
bool has_natural_height() const { return natural_height().has_value(); }

View file

@ -94,7 +94,14 @@ bool FormattingContext::creates_block_formatting_context(Box const& box)
if (box.display().is_flow_root_inside())
return true;
// FIXME: Elements with contain: layout, content, or paint.
// https://drafts.csswg.org/css-contain-2/#containment-types
// 1. The layout containment box establishes an independent formatting context.
// 4. The paint containment box establishes an independent formatting context.
if (box.dom_node() && box.dom_node()->is_element()) {
auto element = as<DOM::Element>(box.dom_node());
if (element->has_layout_containment() || element->has_paint_containment())
return true;
}
if (box.parent()) {
auto parent_display = box.parent()->display();

View file

@ -89,6 +89,17 @@ bool Node::can_contain_boxes_with_position_absolute() const
if (computed_values().scale().has_value())
return true;
// https://drafts.csswg.org/css-contain-2/#containment-types
// 4. The layout containment box establishes an absolute positioning containing block and a fixed positioning
// containing block.
// 4. The paint containment box establishes an absolute positioning containing block and a fixed positioning
// containing block.
if (dom_node() && dom_node()->is_element()) {
auto element = as<DOM::Element>(dom_node());
if (element->has_layout_containment() || element->has_paint_containment())
return true;
}
return false;
}
@ -220,6 +231,15 @@ bool Node::establishes_stacking_context() const
if (computed_values().isolation() == CSS::Isolation::Isolate)
return true;
// https://drafts.csswg.org/css-contain-2/#containment-types
// 5. The layout containment box creates a stacking context.
// 3. The paint containment box creates a stacking context.
if (dom_node() && dom_node()->is_element()) {
auto element = as<DOM::Element>(dom_node());
if (element->has_layout_containment() || element->has_paint_containment())
return true;
}
return computed_values().opacity() < 1.0f;
}

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1129563">
<body style="contain: size layout;">
<div id="target" style="contain: size layout;"></div>
<div id="child"></div>
</body>
<script>
document.body.offsetTop;
const target = document.getElementById('target');
const child = document.getElementById('child');
target.appendChild(child);
</script>

View file

@ -0,0 +1,26 @@
<style>
* {
counter-reset: reversed(counter_3) reversed(counter_4) 64 reversed(counter_5) -8772;
contain: layout paint style inline-size !important;
}
</style>
<script>
window.addEventListener("load", () => {
let a = document.documentElement
let b = document.getElementById("o1")
let c = document.getElementById("o3")
let d = new Range()
document.documentElement.style.display = "none"
document.documentElement.getBoundingClientRect()
document.documentElement.style.display = ""
d.setStartAfter(document.getElementById("o2"))
try { document.prepend("", document.documentElement) } catch (e) {}
d.surroundContents(b)
try { b.prepend(a, c) } catch (e) {}
b.scrollIntoView({ })
a.style.display = "none"
})
</script>
<br id="o1">
<li id="o2">
<input id="o3">

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1928724">
<style>
*:only-child {
contain: size layout paint;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", () => {
a.getBoundingClientRect();
a.appendChild(c);
b.scrollBy();
})
</script>
<body>
<svg>
<animateMotion id="b">
</animateMotion>
<foreignObject id="a">
<article>
<data id="c">

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
<link rel="help" href="https://crbug.com/1214198">
<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org">
<style>
.contain {
contain: strict;
display: block;
width: 100px;
height: 100px;
}
</style>
<body>
<div id="outer" class="contain">
<div>
<div id="inner" class="contain"></div>
</div>
</div>
<script>
document.body.offsetTop;
inner.appendChild(document.createTextNode('inner-child'));
outer.appendChild(document.createTextNode('outer-child'));
</script>
</body>

View file

@ -0,0 +1,15 @@
<!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=1340168">
<div style="contain:size layout;">
<div id="klabb" style="display:inline-block; contain:size layout;">t</div>
<br>
<div id="babb" style="display:inline-block; width:10px; height:10px;"></div>
</div>
<script>
document.body.offsetTop;
klabb.innerHTML = ":-)";
klabb.style.height = "100px";
document.body.offsetTop;
babb.style.width = "20px";
</script>

View file

@ -0,0 +1,18 @@
<!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=1386673">
<div style="contain:layout size;">
<div style="display:inline-block;">
<div style="contain:layout size;">
<div id="firstVictim"></div>
</div>
</div>
<div style="position:absolute;">
<div id="secondVictim"></div>
</div>
</div>
<script>
document.body.offsetTop;
firstVictim.style.display = "none";
secondVictim.style.display = "none";
</script>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1439692">
<style>
body, fieldset { contain: strict; }
</style>
<script>
function crash() {
document.body.offsetTop;
document.body.appendChild(document.createElement("fieldset"));
}
</script>
<body onload="crash()">

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<div style="position: relative; width: 100px; height: 100px; overflow: hidden;">
<div id="target" style="contain: size layout;">
<canvas id="inner" width="0"></canvas>
</div>
</div>
<script>
document.body.offsetTop;
document.getElementById('inner').width = '100';
document.getElementById('target').style.contain = 'initial';
</script>

View file

@ -0,0 +1,39 @@
/**
* Remove the `reftest-wait` class on the document element.
* The reftest runner will wait with taking a screenshot while
* this class is present.
*
* See https://web-platform-tests.org/writing-tests/reftests.html#controlling-when-comparison-occurs
*/
function takeScreenshot() {
document.documentElement.classList.remove("reftest-wait");
}
/**
* Call `takeScreenshot()` after a delay of at least |timeout| milliseconds.
* @param {number} timeout - milliseconds
*/
function takeScreenshotDelayed(timeout) {
setTimeout(function () {
takeScreenshot();
}, timeout);
}
/**
* Ensure that a precondition is met before waiting for a screenshot.
* @param {bool} condition - Fail the test if this evaluates to false
* @param {string} msg - Error message to write to the screenshot
*/
function failIfNot(condition, msg) {
const fail = () => {
(document.body || document.documentElement).textContent = `Precondition Failed: ${msg}`;
takeScreenshot();
};
if (!condition) {
if (document.readyState == "interactive") {
fail();
} else {
document.addEventListener("DOMContentLoaded", fail, false);
}
}
}

View file

@ -0,0 +1,19 @@
"use strict";
/**
* Waits until we have at least one frame rendered, regardless of the engine.
*
* @returns {Promise}
*/
function waitForAtLeastOneFrame() {
return new Promise(resolve => {
// Different web engines work slightly different on this area but waiting
// for two requestAnimationFrames() to happen, one after another, should be
// sufficient to ensure at least one frame has been generated anywhere.
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
resolve();
});
});
});
}

View file

@ -0,0 +1,9 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>You should see a wide orange rectangle to the left of the third float, overlapping the float.</p>
<div style="width:400px;position:relative">
<div style="float:right;width:200px;height:100px;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="position:absolute;left:0;top:200px;width:200px;height:20px;background-color:orange"></div>
</div>

View file

@ -0,0 +1,9 @@
<!doctype html>
<title>CSS Test Reference</title>
<p>You should see a wide orange rectangle to the left of the first float, overlapping the float.</p>
<div style="width:400px;position:relative">
<div style="float:right;width:200px;height:100px;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="position:absolute;left:0;top:0;width:300px;height:20px;background-color:orange"></div>
</div>

View file

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Test</title>
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<style>
#a {
background: blue;
margin: 10px;
width: 50px;
height: 50px;
}
#b {
width: 50px;
height: 40px;
background: green;
}
#b-padding {
height: 10px;
}
#c {
width: 50px;
height: 10px;
background: lightblue;
}
</style>
</head>
<body>
<div id="a">
<div id="b-padding"></div>
<div id="b"></div>
<div id="c"></div>
</div>
</body>
</html>

View file

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<style>
.abspos-box {
position: absolute;
width: 200px;
height: 200px;
}
/* The boxes should stack in the order that I've listed their CSS classes
here. The class names' first word (outside/before/inside/after) refers
to the boxes' DOM position, and "background"/"midground"/"foreground"
refers to their z-index values. */
.before-IB-background {
background: darkmagenta;
z-index: -1;
top: 50px;
left: 50px;
}
.after-IB-background {
background: magenta;
z-index: -1;
top: 70px;
left: 70px;
}
.outside-span-midground {
background: darkkhaki;
top: 90px;
left: 90px;
}
.inside-IB-midground {
background: khaki;
top: 110px;
left: 110px;
}
.before-IB-foreground {
background: darkcyan;
z-index: 1;
top: 130px;
left: 130px;
}
.after-IB-foreground {
background: cyan;
z-index: 1;
top: 150px;
left: 150px;
}
</style>
</head>
<body>
<!-- The expectation here is that 'abspos-box' elements will all interact in
the same top-level stacking context. That means the box ordering should
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
with the boxes stacked (visually) from top-left to bottom-right. -->
<div class="abspos-box outside-span-midground"></div>
<!-- Note: this file is identical to the testcase,
except for the lack of "contain: layout" on this span. -->
<span>
<div class="abspos-box before-IB-background"></div>
<div class="abspos-box before-IB-foreground"></div>
<!-- This unstyled div crates the IB split: -->
<div>
<div class="abspos-box inside-IB-midground"></div>
</div>
<div class="abspos-box after-IB-background"></div>
<div class="abspos-box after-IB-foreground"></div>
</span>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<style>
#a {
display: contents;
width: 100px;
height: 100px;
background: green;
margin: 50px;
}
#b {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="a">
<div>
<div id="b"></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<style>
#a {
display: contents;
width: 100px;
height: 100px;
background: red;
margin: 50px;
}
#b {
position: fixed;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="a">
<div>
<div id="b"></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>CSS Containment Test: Scrolling overflow works when paint is contained"</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-paint">
<meta name="assert" content="Scrolling overflow works when paint is contained.">
<script src="../../common/reftest-wait.js"></script>
<script src="../../common/rendering-utils.js"></script>
<style>
.content {
height: 100vh;
width: 100%;
}
</style>
<body>
<div class="content"></div>
<script>
waitForAtLeastOneFrame().then(() => {
document.body.scrollTop = 100;
takeScreenshot();
});
</script>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<style>
#a {
width: 100px;
height: 100px;
background: green;
margin: 50px;
}
</style>
</head>
<body>
<div id="a"></div>
</body>
</html>

View file

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<style>
.abspos-box {
position: absolute;
width: 200px;
height: 200px;
}
/* The boxes should stack in the order that I've listed their CSS classes
here. The class names' first word (outside/before/inside/after) refers
to the boxes' DOM position, and "background"/"midground"/"foreground"
refers to their z-index values. */
.before-IB-background {
background: darkmagenta;
z-index: -1;
top: 50px;
left: 50px;
}
.after-IB-background {
background: magenta;
z-index: -1;
top: 70px;
left: 70px;
}
.outside-span-midground {
background: darkkhaki;
top: 90px;
left: 90px;
}
.inside-IB-midground {
background: khaki;
top: 110px;
left: 110px;
}
.before-IB-foreground {
background: darkcyan;
z-index: 1;
top: 130px;
left: 130px;
}
.after-IB-foreground {
background: cyan;
z-index: 1;
top: 150px;
left: 150px;
}
</style>
</head>
<body>
<!-- The expectation here is that 'abspos-box' elements will all interact in
the same top-level stacking context. That means the box ordering should
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
with the boxes stacked (visually) from top-left to bottom-right. -->
<div class="abspos-box outside-span-midground"></div>
<!-- Note: this file is identical to the testcase,
except for the lack of "contain: paint" on this span. -->
<span>
<div class="abspos-box before-IB-background"></div>
<div class="abspos-box before-IB-foreground"></div>
<!-- This unstyled div crates the IB split: -->
<div>
<div class="abspos-box inside-IB-midground"></div>
</div>
<div class="abspos-box after-IB-background"></div>
<div class="abspos-box after-IB-foreground"></div>
</span>
</body>
</html>

View file

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<style>
div {
position: relative;
width: 100px;
}
#div1,
#div3 {
background-color: #cfc;
height: 100px;
}
#div1 {
z-index: 5;
}
#div2 {
display: contents;
background-color: #fdd;
height: 100px;
top: -20px;
}
#div2_1 {
background-color: #ffc;
z-index: 6;
top: -10px;
height: 100px;
}
#div2_2 {
z-index: 3;
position: absolute;
top: -15px;
width: 40px;
height: 300px;
background-color: #ddf;
}
#div3 {
z-index: 2;
top: -50px;
}
</style>
</head>
<body>
<div id="div1"></div>
<div id="div2">
<div id="div2_1"></div>
<div id="div2_2"></div>
</div>
<div id="div3"></div>
</body>
</html>

View file

@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<style>
div {
position: relative;
width: 100px;
}
#div1,
#div3 {
background-color: #cfc;
}
#div1 {
z-index: 5;
}
#div2 {
z-index: 1;
background-color: #fdd;
height: 100px;
top: -20px;
}
#div2_1 {
background-color: #ffc;
z-index: 6;
top: -10px;
}
#div2_2 {
z-index: 3;
position: absolute;
top: -15px;
width: 40px;
height: 100px;
background-color: #ddf;
}
#div3 {
z-index: 2;
top: -50px;
}
</style>
</head>
<body>
<div id="div1">
<br/><br/>
</div>
<div id="div2">
<div id="div2_1">
<br/><br/>
</div>
<div id="div2_2">
</div>
</div>
<div id="div3">
<br/><br/>
</div>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Reference: Size containment replaced elements intrinsic size</title>
<style>
body > div, video, audio, img, canvas, svg, iframe {
border: 3px solid orange;
contain: size;
margin-bottom: 15px;
width: 0px;
height: 0px;
float: left;
clear: both;
}
</style>
<div>abc</div>
<video></video><br>
<video controls></video><br>
<img src="support/60x60-green.png"><br>
<picture>
<source srcset="support/60x60-green.png">
<img>
</picture><br>
<canvas></canvas><br>
<svg></svg><br>
<iframe></iframe>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Reference: Size containment replaced elements intrinsic size</title>
<style>
body > div, video, audio, img, canvas, svg, iframe {
position: absolute;
border: 3px solid orange;
contain: size;
margin-bottom: 15px;
width: 0px;
height: 0px;
float: left;
clear: both;
}
</style>
<div>abc</div>
<video></video><br>
<video controls></video><br>
<img src="support/60x60-green.png"><br>
<picture>
<source srcset="support/60x60-green.png">
<img>
</picture><br>
<canvas></canvas><br>
<svg></svg><br>
<iframe></iframe>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Reference: Size containment replaced elements intrinsic size</title>
<style>
div, video, audio, img, canvas, svg, iframe {
border: 3px solid orange;
margin-bottom: 15px;
width: 25px;
height: 35px;
float: left;
clear: both;
}
</style>
<div>abc</div>
<video></video><br>
<video controls></video><br>
<img src="support/60x60-green.png"><br>
<picture>
<source srcset="support/60x60-green.png">
<img>
</picture><br>
<canvas></canvas><br>
<svg></svg><br>
<iframe></iframe>

View file

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<style>
select {
color: transparent;
}
.minWidth {
min-width: 100px;
}
.width {
width: 100px;
}
.floatLWidth {
float: left;
width: 100px;
}
</style>
</head>
<body>
<select multiple class="floatLWidth">
</select>
<br style="clear:both;">
<select multiple class="minWidth">
</select>
<br>
<select multiple class="width">
</select>
</body>
</html>

View file

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<style>
caption {
border: 1em solid green;
}
</style>
</head>
<body>
<table>
<caption></caption>
</table>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test referemce</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
</style>
<p>Test passes if there is no red.

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div#green-square
{
background-color: green;
height: 100px;
width: 100px;
}
div#result
{
font-size: 3em;
}
</style>
<p>Test passes if there is a filled green square, no red and the number 17.
<div id="green-square"></div>
<div id="result">17</div>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CSS Containment Test: Removing layout containment and contained positioned elements</title>
<style>
.container {
width: 300px;
height: 300px;
}
.box {
width: 100px;
height: 100px;
background-color: green;
}
.fixed {
position: fixed;
top: 0;
left: 0;
}
.abspos {
position: absolute;
top: 0;
right: 0;
}
</style>
<div class="container">
<div class="fixed box"></div>
<div class="abspos box"></div>
</div>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment fixed positioned descendants</title>
<style>
#green {
background: green;
width: 100px;
height: 100px;
}
body {
height: 3000px;
margin: 0px;
}
#spacer {
height: 200px;
}
</style>
<script>
function runTest() {
document.documentElement.scrollTop += 200;
}
</script>
<body onload="runTest()">
<div id="spacer"></div>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="green"></div>
</body>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
table
{
background-color: blue;
border-spacing: 2px;
height: 206px;
table-layout: fixed;
width: 206px;
}
td
{
background-color: white;
padding: 0px;
vertical-align: baseline;
}
span
{
background-color: green;
color: white;
font-family: monospace;
vertical-align: top;
}
</style>
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
<table>
<tr><td>&nbsp;<td>&nbsp;
<tr><td>&nbsp;<td><span>PASS</span>
</table>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
color: transparent;
float: left;
font-size: 16px;
padding: 8px;
}
div#blue-rectangle
{
background-color: blue;
margin: 8px;
width: 6em;
}
div#orange-rectangle
{
background-color: orange;
width: 12em;
}
</style>
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
<div id="blue-rectangle">Some text in a blue rectangle.</div>
<div id="orange-rectangle">Some text in an orange rectangle. Some text in an orange rectangle. Some text in an orange rectangle.</div>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
font-family: monospace;
font-size: 100px;
height: 3em;
overflow: scroll;
width: 4ch;
}
</style>
<body>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
font-family: monospace;
font-size: 100px;
height: 2.8ch;
overflow: scroll;
width: 4ch;
}
</style>
<body>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<body>
<p>Test passes if there is no red.

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
color: transparent;
float: left;
font-size: 16px;
padding: 8px;
}
div#blue-rectangle
{
background-color: blue;
margin: 8px;
width: 6em;
}
div#orange-rectangle
{
background-color: orange;
height: 0px;
width: 12em;
}
</style>
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
<div id="blue-rectangle">Some text in a blue rectangle.</div>
<div id="orange-rectangle">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.</div>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
background-color: green;
height: 100px;
left: 100px;
position: relative;
top: 100px;
width: 100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.
<div></div>

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
p
{
margin-bottom: 30px;
}
div
{
height: 30px;
}
div.orange
{
background-color: orange;
}
div.blue
{
background-color: blue;
}
div#lime
{
background-color: lime;
}
</style>
<p>Test passes if there are 5 horizontal stripes across the page in this order (from top to bottom): an orange stripe, a blue stripe, a bright green stripe, a blue stripe and then an orange stripe.
<div class="orange"></div>
<div class="blue"></div>
<div id="lime"></div>
<div class="blue"></div>
<div class="orange"></div>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Reference file</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<style>
.wrapper {
border: solid thick;
margin: 1em;
}
</style>
<p>Test passes if it has the same output than the reference.</p>
<div class="wrapper">
<div style="margin: 2em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
</div>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Reference file</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<style>
.wrapper {
border: solid thick;
margin: 1em;
}
</style>
<p>Test passes if it has the same output than the reference.</p>
<div class="wrapper">
<div style="margin: 1em 0;">This text should have 1em top and bottom margins.</div>
</div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<p>This test passes if the painted blue area is <strong>exactly as tall as</strong> the orange square.
<div><img src="../support/swatch-blue.png" width="100" height="100" alt="Image download support must be enabled"> <img src="../support/swatch-orange.png" width="100" height="100" alt="Image download support must be enabled"></div>

View file

@ -0,0 +1,25 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>test reference</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<style>
div { font-size: 50px; }
.green { background: green; }
.grid {
display: grid;
grid-template-columns: min-content max-content;
}
</style>
<p>This test passes if there are two green rectangles and no red.
<div class=grid>
<div style="grid-area: 1/1">&nbsp;</div>
<div style="grid-area: 2/2"id=test class="grid">
<div>&nbsp;</div>
<div class=green></div>
<div class=green></div>
<div>&nbsp;</div>
</div>
</div>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
font-size: 3em;
}
</style>
<p>Test passes if there is the number 14.
<div>14</div>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference Test</title>
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
<style>
div
{
font-size: 3em;
}
</style>
<p>Test passes if there is the number 13.
<div>13</div>

View file

@ -0,0 +1,8 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test reference</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<p>Test passes if the text below is "1 1.2" (not including the quotation marks).<p>
<div>1 1.2</div>

View file

@ -0,0 +1,8 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test reference</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<p>Test passes if the text below is "1 2" (not including the quotation marks).<p>
<div>1 2</div>

View file

@ -0,0 +1,15 @@
<!doctype html>
<meta charset="UTF-8">
<title>CSS Test Reference</title>
<style>
.list-item {
margin-left: 40px;
}
</style>
<div class="list-item">
[1] A1
<div class="list-item">[1] B1</div>
<div class="list-item">[2] B2</div>
</div>
<div class="list-item">[2] A2</div>
<div class="list-item">[3] A3</div>

View file

@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<title>Reference rendering - passes if there is the word "PASS" below</title>
<style>
div { overflow: hidden; }
</style>
</head>
<body>
<p>Test passes if there is the word "PASS" below.</p>
<div>PASS</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B

View file

@ -0,0 +1,4 @@
<!DOCTYPE html>
<title>CSS Reftest Reference</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<p>There should be nothing below.</p>

View file

@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>Reference rendering - passes if there is the word "PASS" below</title>
<link rel="author" title="Opera" href="https://www.opera.com/">
</head>
<body>
<p>Test passes if there is the word "PASS" below.</p>
<div>PASS</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

View file

@ -0,0 +1,39 @@
/**
* Remove the `reftest-wait` class on the document element.
* The reftest runner will wait with taking a screenshot while
* this class is present.
*
* See https://web-platform-tests.org/writing-tests/reftests.html#controlling-when-comparison-occurs
*/
function takeScreenshot() {
document.documentElement.classList.remove("reftest-wait");
}
/**
* Call `takeScreenshot()` after a delay of at least |timeout| milliseconds.
* @param {number} timeout - milliseconds
*/
function takeScreenshotDelayed(timeout) {
setTimeout(function() {
takeScreenshot();
}, timeout);
}
/**
* Ensure that a precondition is met before waiting for a screenshot.
* @param {bool} condition - Fail the test if this evaluates to false
* @param {string} msg - Error message to write to the screenshot
*/
function failIfNot(condition, msg) {
const fail = () => {
(document.body || document.documentElement).textContent = `Precondition Failed: ${msg}`;
takeScreenshot();
};
if (!condition) {
if (document.readyState == "interactive") {
fail();
} else {
document.addEventListener("DOMContentLoaded", fail, false);
}
}
}

View file

@ -0,0 +1,19 @@
"use strict";
/**
* Waits until we have at least one frame rendered, regardless of the engine.
*
* @returns {Promise}
*/
function waitForAtLeastOneFrame() {
return new Promise(resolve => {
// Different web engines work slightly different on this area but waiting
// for two requestAnimationFrames() to happen, one after another, should be
// sufficient to ensure at least one frame has been generated anywhere.
window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => {
resolve();
});
});
});
}

View file

@ -0,0 +1,26 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: layout containment on body prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="layout containment on body prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
contain: layout;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,26 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: size containment on body prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="size containment on body prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
contain: size;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,26 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: style containment on body prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="style containment on body prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-2/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
contain: style;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: a block with 'contain: content' alongside a float</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#contain-property">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-ifc-022-ref.html">
<style>
div
{
color: transparent;
font-size: 16px;
padding: 8px;
}
div#floated-left
{
background-color: blue;
float: left;
margin: 8px;
width: 6em;
}
div#with-contain-content
{
background-color: orange;
width: 12em;
contain: content;
}
</style>
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
<div id="floated-left">Some text in a blue rectangle.</div>
<div id="with-contain-content">Some text in an orange rectangle. Some text in an orange rectangle. Some text in an orange rectangle.</div>

View file

@ -0,0 +1,52 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: element with 'contain: content' and absolutely positioned descendants</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="This test checks that an element with 'contain: content' acts as containing block for its absolutely positioned descendants.">
<style>
div
{
width: 100px;
}
div#contain-content
{
background-color: red;
contain: content;
height: 100px;
}
div.abspos
{
background-color: green;
height: 50px;
position: absolute;
right: 0;
}
div#first-abspos
{
top: 0px;
}
div#second-abspos
{
bottom: 0px;
}
</style>
<body>
<p>Test passes if there is a filled green square and <strong>no red</strong>.
<div id="contain-content">
<div id="first-abspos" class="abspos"></div>
<div id="second-abspos" class="abspos"></div>
</div>

View file

@ -0,0 +1,62 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: 'contain: content' applies to 'table-cell' elements</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-cell-001-ref.html">
<meta content="In this test, the td#contain should act as the containing block for div#abs-pos ." name="assert">
<style>
table
{
background-color: blue;
border-spacing: 2px;
height: 206px;
table-layout: fixed;
width: 206px;
}
td
{
background-color: white;
padding: 0px;
vertical-align: top;
}
td#contain
{
contain: content;
}
span
{
background-color: red;
color: yellow;
font-family: monospace;
vertical-align: top;
}
div#abs-pos
{
background-color: green;
color: white;
font-family: monospace;
left: 0px;
position: absolute;
top: 0px;
}
</style>
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
<table>
<tr><td>&nbsp;<td>&nbsp;
<tr><td>&nbsp;<td id="contain"><span>FAIL</span><div id="abs-pos">PASS</div>
</table>

View file

@ -0,0 +1,28 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: layout containment on html prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="layout containment on html prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
}
html {
contain: layout;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,29 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: paint containment on html prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="paint containment on html prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
}
html {
height: 400px;
contain: paint;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,28 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: size containment on html prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="size containment on html prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
}
html {
contain: size;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,28 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: style containment on html prevents overflow propagation</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="style containment on html prevents overflow propagation">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-2/#contain-property">
<style>
html, body, p, div {
margin: 0;
width: 200px;
height: 200px;
}
div { background: red; }
body {
overflow: hidden;
}
html {
contain: style;
}
</style>
<p>Test passes if there is no red.
<div></div>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-2/#algo-stretch">
<link rel="match" href="../../../../expected/wpt-import//css/reference/ref-filled-green-100px-square-only.html">
<meta name="assert" content="grid with inline-size containment, and min-height will still distribute extra space to auto rows">
<style>
grid {
display: grid;
min-height: 100px;
grid-template-rows: auto;
contain: inline-size;
}
.absolute {
position: absolute;
}
.align-end {
align-self: end;
}
.item {
width: 100px;
height: 50px;
background-color: green;
}
</style>
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<grid>
<div class="absolute item"></div>
<div class="item align-end"></div>
</grid>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<title>contain:inline-size on table</title>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#containment-inline-size">
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<!-- Note that size containment doesn't apply to tables:
https://www.w3.org/TR/css-contain-1/#containment-size -->
<div style="width:100px; height:100px; background:red;">
<div style="display:table; contain:inline-size; width:fit-content; background:green;">
<div style="width:100px; height:100px;"></div>
</div>
</div>

View file

@ -0,0 +1,23 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: layout containment on non-atomic inlines</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="layout containment does not apply to non atomic inlines">
<link rel="match" href="../../../../expected/wpt-import/css/reference/pass_if_pass_below.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<style>
#pa {
contain: layout;
height: 100vh; /*If layout containment applies, the span becomes a BFC, height applies, and knocks SS off the page */
}
#ss {
vertical-align: bottom;
}
</style>
<p>Test passes if there is the word "PASS" below.</p>
<div><span id="pa">PA</span><span id="ss">SS</span></div>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment absolutely positioned descendants</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
<meta name=assert content="Layout containment makes an element to act as containing block for absolutely positioned descendants.">
<style>
#contain-layout {
contain: layout;
width: 100px;
height: 100px;
background: red;
}
#abspos {
position: absolute;
bottom: 0;
right: 0;
background: green;
width: 100px;
height: 100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="contain-layout">
<div id="abspos"></div>
</div>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>CSS Containment Test: Layout containment on table-caption</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
<meta name=assert content="Layout containment does apply to table-caption elements.">
<style>
#table-caption {
display: table-caption;
contain: layout;
width: 100px;
height: 100px;
background: red;
}
#abspos {
position: absolute;
bottom: 0;
right: 0;
background: green;
width: 100px;
height: 100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="table-caption">
<div id="abspos"></div>
</div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment stacking context</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/reference/pass_if_pass_below.html">
<meta name=assert content="Layout containment elements create a stacking context.">
<style>
div {
contain: layout;
background: white;
}
span {
position: relative;
z-index: -1;
}
</style>
<p>Test passes if there is the word "PASS" below.</p>
<div><span>PASS</span></div>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment stacking context</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/reference/nothing.html">
<meta name=assert content="Elements in which layout containment doesn't apply, do not create a stacking context.">
<style>
rt {
display: ruby-text;
contain: layout;
background: white;
overflow: hidden;
}
span {
position: relative;
z-index: -1;
}
</style>
<p>There should be nothing below.</p>
<ruby><rt><span>FAIL</span></rt></ruby>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment inside a fit-content element</title>
<link rel="help" href="https://crbug.com/1268449">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
<meta name=assert
content="Layout containment inside a fit-content element should update size when the content is changed">
<style>
#contain-parent {
width: fit-content;
}
#contain-layout {
contain: layout;
background: green;
}
#content {
width: 50px;
height: 100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="contain-parent">
<div id="contain-layout">
<div id="content"></div>
</div>
</div>
<script>
window.requestAnimationFrame(() => {
document.body.offsetTop;
document.getElementById('content').style.width = '100px';
document.body.offsetTop;
});
</script>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset=utf-8>
<title>CSS Containment Test: Removing layout containment and contained positioned elements</title>
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-020-ref.html">
<meta name=assert content="Removing layout containment relayouts contained positioned elements correctly.">
<style>
#container {
width: 300px;
height: 300px;
contain: layout;
}
.box {
width: 100px;
height: 100px;
background-color: green;
}
.fixed {
position: fixed;
top: 0;
left: 0;
}
.abspos {
position: absolute;
top: 0;
right: 0;
}
</style>
<div id="container">
<div class="fixed box"></div>
<div class="abspos box"></div>
</div>
<script>
requestAnimationFrame(() => {
container.style.contain = "none";
document.documentElement.removeAttribute("class");
});
</script>

View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: 'contain: layout' applies to 'table-cell' elements</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-cell-001-ref.html">
<meta content="In this test, the div#contain should act as the containing block for div#abs-pos ." name="assert">
<style>
div#table
{
background-color: blue;
border-spacing: 2px;
display: table;
height: 206px;
table-layout: fixed;
width: 206px;
}
div.row
{
display: table-row;
}
div.cell
{
background-color: white;
display: table-cell;
vertical-align: top;
}
div#contain
{
contain: layout;
}
span
{
background-color: red;
color: yellow;
font-family: monospace;
vertical-align: top;
}
div#abs-pos
{
background-color: green;
color: white;
font-family: monospace;
left: 0px;
position: absolute;
top: 0px;
}
</style>
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
<div id="table">
<div class="row"><div class="cell">&nbsp;</div><div class="cell">&nbsp;</div></div>
<div class="row"><div class="cell">&nbsp;</div><div class="cell" id="contain"><span>FAIL</span><div id="abs-pos">PASS</div></div></div>
</div>

View file

@ -0,0 +1,62 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: 'contain: layout' applies to 'table-cell' elements</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-cell-001-ref.html">
<meta content="In this test, the td#contain should act as the containing block for div#abs-pos ." name="assert">
<style>
table
{
background-color: blue;
border-spacing: 2px;
height: 206px;
table-layout: fixed;
width: 206px;
}
td
{
background-color: white;
padding: 0px;
vertical-align: top;
}
td#contain
{
contain: layout;
}
span
{
background-color: red;
color: yellow;
font-family: monospace;
vertical-align: top;
}
div#abs-pos
{
background-color: green;
color: white;
font-family: monospace;
left: 0px;
position: absolute;
top: 0px;
}
</style>
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
<table>
<tr><td>&nbsp;<td>&nbsp;
<tr><td>&nbsp;<td id="contain"><span>FAIL</span><div id="abs-pos">PASS</div>
</table>

View file

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: layout' element should contain absolute position elements.</title>
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-paint-containing-block-absolute-001-ref.html">
<style>
#a {
contain: layout;
width: 100px;
height: 100px;
background: red;
margin: 50px;
}
#b {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="a">
<div>
<div id="b"></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: layout' with a vertical margin child. Margin collapse should not occur, and neither should overflow clipping.</title>
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-formatting-context-margin-001-ref.html">
<style>
#a {
contain:layout;
background: blue;
margin: 10px;
width: 50px;
height: 50px;
}
#b {
width: 50px;
height: 40px;
background: green;
margin-top: 10px;
}
#c {
background: lightblue;
width: 50px;
height: 10px;
}
</style>
</head>
<body>
<div id="a">
<div id="b"></div>
<div id="c"></div>
</div>
</body>
</html>

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: 'contain: layout' and creation of an independent formating context: text no longer flowing around a float</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-ifc-022-ref.html">
<meta content="This test checks that an element with 'contain: layout' will make such element create its own formatting context. In this test, the element with 'contain: layout' acts as if it has its own formatting context independent from div#floated-left element. In other words, the div#with-contain-layout is no longer required to flow its content around the div#floated-left element and current line boxes next to the float are no longer shortened to make room for the margin box of the float." name="assert">
<style>
div
{
color: transparent;
font-size: 16px;
padding: 8px;
}
div#floated-left
{
background-color: blue;
float: left;
margin: 8px;
width: 6em;
}
div#with-contain-layout
{
background-color: orange;
contain: layout;
width: 12em;
}
</style>
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
<!--
or
<p>Test passes if the orange rectangle and blue rectangle are side by side.
or
<p>Test passes if the orange rectangle and blue rectangle are apart from each other.
-->
<div id="floated-left">Some text in a blue rectangle.</div>
<div id="with-contain-layout">Some text in an orange rectangle. Some text in an orange rectangle. Some text in an orange rectangle.</div>

View file

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: layout' should have no effect on non-atomic inline
(including its block part, if there's a block-in-inline split)</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-ignored-cases-ib-split-001-ref.html">
<style>
.abspos-box {
position: absolute;
width: 200px;
height: 200px;
}
/* The boxes should stack in the order that I've listed their CSS classes
here. The class names' first word (outside/before/inside/after) refers
to the boxes' DOM position, and "background"/"midground"/"foreground"
refers to their z-index values. */
.before-IB-background {
background: darkmagenta;
z-index: -1;
top: 50px;
left: 50px;
}
.after-IB-background {
background: magenta;
z-index: -1;
top: 70px;
left: 70px;
}
.outside-span-midground {
background: darkkhaki;
top: 90px;
left: 90px;
}
.inside-IB-midground {
background: khaki;
top: 110px;
left: 110px;
}
.before-IB-foreground {
background: darkcyan;
z-index: 1;
top: 130px;
left: 130px;
}
.after-IB-foreground {
background: cyan;
z-index: 1;
top: 150px;
left: 150px;
}
</style>
</head>
<body>
<!-- The expectation here is that 'abspos-box' elements will all interact in
the same top-level stacking context. That means the box ordering should
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
with the boxes stacked (visually) from top-left to bottom-right. -->
<div class="abspos-box outside-span-midground"></div>
<span style="contain: layout">
<div class="abspos-box before-IB-background"></div>
<div class="abspos-box before-IB-foreground"></div>
<!-- This unstyled div crates the IB split: -->
<div>
<div class="abspos-box inside-IB-midground"></div>
</div>
<div class="abspos-box after-IB-background"></div>
<div class="abspos-box after-IB-foreground"></div>
</span>
</body>
</html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: layout' element should not contain absolute/fixed position elements when no principal box is generated.</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-ignored-cases-no-principal-box-002-ref.html">
<style>
#a {
contain: layout;
display: contents;
width: 100px;
height: 100px;
background: red;
margin: 50px;
}
#b {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="a">
<div>
<div id="b"></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: layout' element should not contain absolute/fixed position elements when no principal box is generated.</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-ignored-cases-no-principal-box-003-ref.html">
<style>
#a {
contain: layout;
display: contents;
width: 100px;
height: 100px;
background: red;
margin: 50px;
}
#b {
position: fixed;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="a">
<div>
<div id="b"></div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment independent formatting context</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-paint-independent-formatting-context-001-ref.html">
<meta name=assert content="Layout containment elements establish an independent formatting context. The test checks that this feature of layout containment applies to blocks.">
<style>
.wrapper {
border: solid thick;
margin: 1em;
}
</style>
<p>Test passes if it has the same output than the reference.</p>
<div class="wrapper">
<div style="margin: 1em 0; contain: layout;">
<div style="margin: 1em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
</div>
</div>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment independent formatting context</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-paint-independent-formatting-context-001-ref.html">
<meta name=assert content="Layout containment elements establish an independent formatting context. The test checks that this feature of layout containment applies to inline blocks.">
<style>
.wrapper {
border: solid thick;
margin: 1em;
}
</style>
<p>Test passes if it has the same output than the reference.</p>
<div class="wrapper">
<span style="display: inline-block; margin: 1em 0; vertical-align: top; contain: layout;">
<div style="margin: 1em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
</span>
</div>

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Containment Test: 'contain: layout' and ink overflow</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-overflow-3/#ink-overflow">
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-ink-overflow-014-ref.html">
<meta content="This test checks that when the contents of an element with 'contain: layout' overflows, its contents must be treated as ink overflow. In this test, the content overflows the div#inner. If such content was treated as 'overflow: visible', then the div#outer would 'pick up' such content and would make it reachable and accessible via its own generated scrollbar. But the overflowed content must be treated as ink overflow and is therefore treated as a graphical effect that is beyond the scrolling mechanism and outside the scrolling mechanism." name="assert">
<style>
div#outer
{
font-family: monospace;
font-size: 100px;
height: 2.8ch;
line-height: 1.5; /* computes to 150px */
width: 4ch;
overflow: scroll;
}
div#inner
{
color: red;
contain: layout;
height: 0;
}
</style>
<!--
150px : height of 1 line box
-->
<body onload="document.getElementById('outer').scrollLeft = 250; document.getElementById('outer').scrollTop = 150;">
<p>Test passes if there is no red.
<div id="outer">
<div id="inner">&nbsp;<br>FAIL</div>
</div>

Some files were not shown because too many files have changed in this diff Show more