Skip to content

Commit 6c5859c

Browse files
lillesChromium LUCI CQ
authored and
Chromium LUCI CQ
committed
Do not propagate body styles when html root or body is contained
Per resolution in [1]. Added behind a flag since this is a web facing change which needs an intent to ship. [1] w3c/csswg-drafts#5913 Bug: 1215265 Change-Id: I50f142245cdb55b422f8a6f3d9690444bf3648aa Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2897247 Reviewed-by: Anders Hartvoll Ruud Commit-Queue: Rune Lillesveen Cr-Commit-Position: refs/heads/master@{#890175}
1 parent 9199627 commit 6c5859c

17 files changed

+155
-122
lines changed

third_party/blink/renderer/core/css/resolver/style_adjuster.cc

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "third_party/blink/renderer/core/frame/web_feature.h"
4747
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
4848
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
49+
#include "third_party/blink/renderer/core/html/html_body_element.h"
4950
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
5051
#include "third_party/blink/renderer/core/html/html_image_element.h"
5152
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
@@ -95,17 +96,24 @@ bool IsEditableElement(Element* element, const ComputedStyle& style) {
9596

9697
TouchAction AdjustTouchActionForElement(TouchAction touch_action,
9798
const ComputedStyle& style,
99+
const ComputedStyle& parent_style,
98100
Element* element) {
99-
// if body is the viewport defining element then ScrollsOverflow should
100-
// return false as body should have overflow-x/overflow-y set to visible
101-
Element* body = element ? element->GetDocument().body() : nullptr;
102-
bool is_body_and_viewport =
103-
element && element == body &&
104-
body == element->GetDocument().ViewportDefiningElement();
105-
bool is_child_document =
106-
element && element == element->GetDocument().documentElement() &&
107-
element->GetDocument().LocalOwner();
108-
if ((!is_body_and_viewport && style.ScrollsOverflow()) || is_child_document)
101+
Element* document_element = element->GetDocument().documentElement();
102+
bool scrolls_overflow = style.ScrollsOverflow();
103+
if (element && element == element->GetDocument().FirstBodyElement()) {
104+
// Body scrolls overflow if html root overflow is not visible or the
105+
// propagation of overflow is stopped by containment.
106+
if (parent_style.IsOverflowVisibleAlongBothAxes()) {
107+
if (!RuntimeEnabledFeatures::CSSContainedBodyPropagationEnabled() ||
108+
(!parent_style.ShouldApplyAnyContainment(*document_element) &&
109+
!style.ShouldApplyAnyContainment(*element))) {
110+
scrolls_overflow = false;
111+
}
112+
}
113+
}
114+
bool is_child_document = element && element == document_element &&
115+
element->GetDocument().LocalOwner();
116+
if (scrolls_overflow || is_child_document)
109117
return touch_action | TouchAction::kPan | TouchAction::kInternalPanXScrolls;
110118
return touch_action;
111119
}
@@ -607,8 +615,8 @@ static void AdjustEffectiveTouchAction(ComputedStyle& style,
607615
// The panning-restricted cancellation should also apply to iframes, so we
608616
// allow (panning & local touch action) on the first descendant element of a
609617
// iframe element.
610-
inherited_action =
611-
AdjustTouchActionForElement(inherited_action, style, element);
618+
inherited_action = AdjustTouchActionForElement(inherited_action, style,
619+
parent_style, element);
612620

613621
TouchAction enforced_by_policy = TouchAction::kNone;
614622
if (element->GetDocument().IsVerticalScrollEnforced())

third_party/blink/renderer/core/css/resolver/style_resolver.cc

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,17 +1715,38 @@ bool PropagateScrollSnapStyleToViewport(
17151715

17161716
} // namespace
17171717

1718+
bool StyleResolver::ShouldStopBodyPropagation(const Element& body_or_html) {
1719+
DCHECK(!body_or_html.NeedsReattachLayoutTree())
1720+
<< "This method relies on LayoutObject to be attached and up-to-date";
1721+
DCHECK(IsA(body_or_html) ||
1722+
IsA(body_or_html));
1723+
LayoutObject* layout_object = body_or_html.GetLayoutObject();
1724+
if (!layout_object)
1725+
return true;
1726+
if (!RuntimeEnabledFeatures::CSSContainedBodyPropagationEnabled())
1727+
return false;
1728+
bool contained = layout_object->ShouldApplyAnyContainment();
1729+
DCHECK_EQ(contained,
1730+
layout_object->StyleRef().ShouldApplyAnyContainment(body_or_html))
1731+
<< "Applied containment must give the same result from LayoutObject and "
1732+
"ComputedStyle";
1733+
return contained;
1734+
}
1735+
17181736
void StyleResolver::PropagateStyleToViewport() {
17191737
DCHECK(GetDocument().InStyleRecalc());
1720-
HTMLBodyElement* body = GetDocument().FirstBodyElement();
17211738
Element* document_element = GetDocument().documentElement();
1722-
17231739
const ComputedStyle* document_element_style =
17241740
document_element && document_element->GetLayoutObject()
17251741
? document_element->GetComputedStyle()
17261742
: nullptr;
1727-
const ComputedStyle* body_style =
1728-
body && body->GetLayoutObject() ? body->GetComputedStyle() : nullptr;
1743+
const ComputedStyle* body_style = nullptr;
1744+
if (HTMLBodyElement* body = GetDocument().FirstBodyElement()) {
1745+
if (!ShouldStopBodyPropagation(*document_element) &&
1746+
!ShouldStopBodyPropagation(*body)) {
1747+
body_style = body->GetComputedStyle();
1748+
}
1749+
}
17291750

17301751
const ComputedStyle& viewport_style =
17311752
GetDocument().GetLayoutView()->StyleRef();
@@ -1792,22 +1813,18 @@ void StyleResolver::PropagateStyleToViewport() {
17921813

17931814
// Overflow
17941815
{
1795-
const ComputedStyle* overflow_style = nullptr;
1796-
if (Element* viewport_element = GetDocument().ViewportDefiningElement()) {
1797-
if (viewport_element == body) {
1798-
overflow_style = body_style;
1799-
} else {
1800-
DCHECK_EQ(viewport_element, document_element);
1801-
overflow_style = document_element_style;
1802-
1803-
// The body element has its own scrolling box, independent from the
1804-
// viewport. This is a bit of a weird edge case in the CSS spec that we
1805-
// might want to try to eliminate some day (eg. for ScrollTopLeftInterop
1806-
// - see http://crbug.com/157855).
1807-
if (body_style && body_style->IsScrollContainer()) {
1808-
UseCounter::Count(GetDocument(),
1809-
WebFeature::kBodyScrollsInAdditionToViewport);
1810-
}
1816+
const ComputedStyle* overflow_style = document_element_style;
1817+
if (body_style &&
1818+
document_element_style->IsOverflowVisibleAlongBothAxes()) {
1819+
overflow_style = body_style;
1820+
1821+
// The body element has its own scrolling box, independent from the
1822+
// viewport. This is a bit of a weird edge case in the CSS spec that we
1823+
// might want to try to eliminate some day (eg. for ScrollTopLeftInterop
1824+
// - see http://crbug.com/157855).
1825+
if (body_style && body_style->IsScrollContainer()) {
1826+
UseCounter::Count(GetDocument(),
1827+
WebFeature::kBodyScrollsInAdditionToViewport);
18111828
}
18121829
}
18131830

third_party/blink/renderer/core/css/resolver/style_resolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected {
161161
const CSSPropertyName&,
162162
const CSSValue&);
163163

164+
// Check if the BODY or HTML element's display or containment stops
165+
// propagation of BODY style to HTML and viewport.
166+
static bool ShouldStopBodyPropagation(const Element& body_or_html);
167+
164168
scoped_refptr StyleForInterpolations(
165169
Element& element,
166170
ActiveInterpolationsMap& animations);

third_party/blink/renderer/core/dom/document.cc

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3287,20 +3287,37 @@ Element* Document::ViewportDefiningElement() const {
32873287
// If a BODY element sets non-visible overflow, it is to be propagated to the
32883288
// viewport, as long as the following conditions are all met:
32893289
// (1) The root element is HTML.
3290-
// (2) It is the primary BODY element (we only assert for this, expecting
3291-
// callers to behave).
3290+
// (2) It is the primary BODY element.
32923291
// (3) The root element has visible overflow.
3292+
// (4) The root or BODY elements do not apply any containment.
32933293
// Otherwise it's the root element's properties that are to be propagated.
3294+
3295+
// This method is called in the middle of a lifecycle update, for instance
3296+
// from a LayoutObject which is created but not yet inserted into the box
3297+
// tree, which is why we have to do the decision based on the ComputedStyle
3298+
// and not the LayoutObject style and the containment checks below also.
3299+
32943300
Element* root_element = documentElement();
3295-
HTMLBodyElement* body_element = FirstBodyElement();
32963301
if (!root_element)
32973302
return nullptr;
32983303
const ComputedStyle* root_style = root_element->GetComputedStyle();
32993304
if (!root_style || root_style->IsEnsuredInDisplayNone())
33003305
return nullptr;
3301-
if (body_element && root_style->IsOverflowVisibleAlongBothAxes())
3302-
return body_element;
3303-
return root_element;
3306+
if (!root_style->IsOverflowVisibleAlongBothAxes())
3307+
return root_element;
3308+
HTMLBodyElement* body_element = FirstBodyElement();
3309+
if (!body_element)
3310+
return root_element;
3311+
const ComputedStyle* body_style = body_element->GetComputedStyle();
3312+
if (!body_style || body_style->IsEnsuredInDisplayNone())
3313+
return root_element;
3314+
if (RuntimeEnabledFeatures::CSSContainedBodyPropagationEnabled()) {
3315+
if (root_style->ShouldApplyAnyContainment(*root_element) ||
3316+
body_style->ShouldApplyAnyContainment(*body_element)) {
3317+
return root_element;
3318+
}
3319+
}
3320+
return body_element;
33043321
}
33053322

33063323
Document* Document::open(v8::Isolate* isolate,

third_party/blink/renderer/core/html/html_html_element.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,12 @@ scoped_refptr HTMLHtmlElement::LayoutStyleForElement(
134134
scoped_refptr<const ComputedStyle> style) {
135135
DCHECK(style);
136136
DCHECK(GetDocument().InStyleRecalc());
137+
DCHECK(GetLayoutObject());
138+
if (StyleResolver::ShouldStopBodyPropagation(*this))
139+
return style;
137140
if (const Element* body_element = GetDocument().FirstBodyElement()) {
141+
if (StyleResolver::ShouldStopBodyPropagation(*body_element))
142+
return style;
138143
if (const ComputedStyle* body_style = body_element->GetComputedStyle()) {
139144
if (NeedsLayoutStylePropagation(*style, *body_style))
140145
return CreateLayoutStyle(*style, *body_style);

third_party/blink/renderer/platform/runtime_enabled_features.json5

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,13 @@
487487
name: "CSSColorTypedOM",
488488
status: "experimental",
489489
},
490+
{
491+
// Stop propagation from BODY to HTML and viewport if HTML or BODY
492+
// elements have any containment applied.
493+
// https://drafts.csswg.org/css-contain-2/#contain-property
494+
name: "CSSContainedBodyPropagation",
495+
status: "test",
496+
},
490497
{
491498
name: "CSSContainerQueries",
492499
},

third_party/blink/web_tests/TestExpectations

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -685,39 +685,6 @@ crbug.com/882385 external/wpt/css/css-contain/quote-scoping-002.html [ Failure ]
685685
crbug.com/882385 external/wpt/css/css-contain/quote-scoping-003.html [ Failure ]
686686
crbug.com/882385 external/wpt/css/css-contain/quote-scoping-004.html [ Failure ]
687687

688-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-001.html [ Failure ]
689-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-002.html [ Failure ]
690-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-003.html [ Failure ]
691-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-004.html [ Failure ]
692-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-001.html [ Failure ]
693-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-002.html [ Failure ]
694-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-003.html [ Failure ]
695-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-004.html [ Failure ]
696-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-001.html [ Failure ]
697-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-002.html [ Failure ]
698-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-003.html [ Failure ]
699-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-004.html [ Failure ]
700-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-001.html [ Failure ]
701-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-002.html [ Failure ]
702-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-003.html [ Failure ]
703-
crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-004.html [ Failure ]
704-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-001.html [ Failure ]
705-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-002.html [ Failure ]
706-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-003.html [ Failure ]
707-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-004.html [ Failure ]
708-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-001.html [ Failure ]
709-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-002.html [ Failure ]
710-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-003.html [ Failure ]
711-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-004.html [ Failure ]
712-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-001.html [ Failure ]
713-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-002.html [ Failure ]
714-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-003.html [ Failure ]
715-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-004.html [ Failure ]
716-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-001.html [ Failure ]
717-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-002.html [ Failure ]
718-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-003.html [ Failure ]
719-
crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-004.html [ Failure ]
720-
721688
# [css-align]
722689

723690
crbug.com/599828 external/wpt/css/css-flexbox/abspos/flex-abspos-staticpos-align-content-001.html [ Failure ]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Backgrounds and Borders Test: Do not propagate body background when html root is containedtitle>
4+
<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#special-backgrounds">
5+
<link rel="match" href="../reference/blank.html">
6+
<style>
7+
html { contain: paint; }
8+
body { background: red; }
9+
style>
10+
<body>body>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Test Referencetitle>
4+
<div style="overflow:scroll">PASS if BODY has scrollbars, but not viewport.div>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Test: HTML root containment stops overflow propagation from BODYtitle>
4+
<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
5+
<link rel="match" href="overflow-body-propagation-011-ref.html">
6+
<style>
7+
html {
8+
contain: paint;
9+
}
10+
body {
11+
overflow: scroll;
12+
}
13+
style>
14+
<body>PASS if BODY has scrollbars, but not viewport.body>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Test Referencetitle>
4+
<body style="margin:0">This text should be left aligned.body>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Writing Modes Test: Do not propagate direction from body when html root is containedtitle>
4+
<link rel="help" href="https://drafts.csswg.org/css-writing-modes/#principal-flow">
5+
<link rel="match" href="direction-propagation-body-contain-root-ref.html">
6+
<style>
7+
html { contain: paint; }
8+
body { direction: rtl; display: inline; }
9+
style>
10+
<body>body>
11+
<script>
12+
document.documentElement.insertBefore(document.createTextNode("This text should be left aligned."), document.body);
13+
script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Test Referencetitle>
4+
<div style="writing-mode:vertical-rl">This text should run vertically on the left sidebody>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
>
2+
<meta charset="utf-8">
3+
<title>CSS Writing Modes Test: Do not propagate writing-mode from body when html root is containedtitle>
4+
<link rel="help" href="https://drafts.csswg.org/css-writing-modes/#principal-flow">
5+
<link rel="match" href="wm-propagation-body-contain-root-ref.html">
6+
<style>
7+
html { contain: paint; }
8+
body { writing-mode: vertical-rl; }
9+
style>
10+
<body>This text should run vertically on the left sidebody>

third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/body-background-propagation-ref.html

Lines changed: 0 additions & 3 deletions
This file was deleted.

third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/body-background-propagation.html

Lines changed: 0 additions & 15 deletions
This file was deleted.

third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/html-root-container-writing-mode.html

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)