aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout_2020/flow/mod.rs1
-rw-r--r--components/layout_2020/formatting_contexts.rs1
-rw-r--r--components/layout_2020/sizing.rs30
-rw-r--r--tests/wpt/meta/MANIFEST.json7
-rw-r--r--tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini9
-rw-r--r--tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html50
6 files changed, 87 insertions, 11 deletions
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs
index c9a1cfe55f1..01d9b1efc6d 100644
--- a/components/layout_2020/flow/mod.rs
+++ b/components/layout_2020/flow/mod.rs
@@ -431,6 +431,7 @@ fn compute_inline_content_sizes_for_block_level_boxes(
containing_block,
&LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */
+ false, /* is_replaced */
false, /* is_table */
!matches!(base.style.pseudo(), Some(PseudoElement::ServoAnonymousBox)),
|_| None, /* TODO: support preferred aspect ratios on non-replaced boxes */
diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs
index 21383ca40b2..d04c69f939f 100644
--- a/components/layout_2020/formatting_contexts.rs
+++ b/components/layout_2020/formatting_contexts.rs
@@ -215,6 +215,7 @@ impl IndependentFormattingContext {
containing_block,
auto_minimum,
auto_block_size_stretches_to_containing_block,
+ self.is_replaced(),
is_table,
true, /* establishes_containing_block */
|padding_border_sums| self.preferred_aspect_ratio(padding_border_sums),
diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs
index c745081e862..46eda7ccbde 100644
--- a/components/layout_2020/sizing.rs
+++ b/components/layout_2020/sizing.rs
@@ -10,6 +10,7 @@ use std::ops::{Add, AddAssign};
use app_units::Au;
use serde::Serialize;
use style::properties::ComputedValues;
+use style::values::computed::LengthPercentage;
use style::Zero;
use crate::context::LayoutContext;
@@ -115,6 +116,7 @@ pub(crate) fn outer_inline(
containing_block: &IndefiniteContainingBlock,
auto_minimum: &LogicalVec2<Au>,
auto_block_size_stretches_to_containing_block: bool,
+ is_replaced: bool,
is_table: bool,
establishes_containing_block: bool,
get_preferred_aspect_ratio: impl FnOnce(&LogicalVec2<Au>) -> Option<AspectRatio>,
@@ -187,7 +189,7 @@ pub(crate) fn outer_inline(
),
})
};
- let (preferred_min_content, preferred_max_content, preferred_depends_on_block_constraints) =
+ let (mut preferred_min_content, preferred_max_content, preferred_depends_on_block_constraints) =
resolve_non_initial(content_box_sizes.inline.preferred)
.unwrap_or_else(|| resolve_non_initial(Size::FitContent).unwrap());
let (mut min_min_content, mut min_max_content, mut min_depends_on_block_constraints) =
@@ -196,7 +198,7 @@ pub(crate) fn outer_inline(
auto_minimum.inline,
false,
));
- let (max_min_content, max_max_content, max_depends_on_block_constraints) =
+ let (mut max_min_content, max_max_content, max_depends_on_block_constraints) =
resolve_non_initial(content_box_sizes.inline.max)
.map(|(min_content, max_content, depends_on_block_constraints)| {
(
@@ -207,6 +209,30 @@ pub(crate) fn outer_inline(
})
.unwrap_or_default();
+ // https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution
+ // > If the box is replaced, a cyclic percentage in the value of any max size property
+ // > or preferred size property (width/max-width/height/max-height), is resolved against
+ // > zero when calculating the min-content contribution in the corresponding axis.
+ //
+ // This means that e.g. the min-content contribution of `width: calc(100% + 100px)`
+ // should be 100px, but it's just zero on other browsers, so we do the same.
+ if is_replaced {
+ let has_percentage = |size: Size<LengthPercentage>| {
+ // We need a comment here to avoid breaking `./mach test-tidy`.
+ matches!(size, Size::Numeric(numeric) if numeric.has_percentage())
+ };
+ if content_box_sizes.inline.preferred.is_initial() &&
+ has_percentage(style.box_size(containing_block.writing_mode).inline)
+ {
+ preferred_min_content = Au::zero();
+ }
+ if content_box_sizes.inline.max.is_initial() &&
+ has_percentage(style.max_box_size(containing_block.writing_mode).inline)
+ {
+ max_min_content = Some(Au::zero());
+ }
+ }
+
// Regardless of their sizing properties, tables are always forced to be at least
// as big as their min-content size, so floor the minimums.
if is_table {
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index d97e68cb65e..d248c65d75b 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -581052,6 +581052,13 @@
{}
]
],
+ "intrinsic-percent-replaced-028.html": [
+ "f54245a1e1f0aabff40ed8823279b8c0bb48f93d",
+ [
+ null,
+ {}
+ ]
+ ],
"intrinsic-size-fallback-replaced.html": [
"a3325b0aea01c008ec322a20e0f279d5bd765b1c",
[
diff --git a/tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini b/tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini
deleted file mode 100644
index 508b6bddd70..00000000000
--- a/tests/wpt/meta/css/css-sizing/keyword-sizes-on-abspos.html.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[keyword-sizes-on-abspos.html]
- [.test 17]
- expected: FAIL
-
- [.test 22]
- expected: FAIL
-
- [.test 27]
- expected: FAIL
diff --git a/tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html b/tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html
new file mode 100644
index 00000000000..f54245a1e1f
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution">
+<meta name="assert" content="A preferred or max inline size property set to a percentage is treated as zero when computing the min-content contribution.">
+
+<style>
+.wrapper {
+ display: inline-block;
+ border: solid;
+ margin: 5px;
+}
+</style>
+
+<div style="width: 0px">
+ <!-- Set 'width' to a percentage -->
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 0%; max-width: 100px"></canvas>
+ </div>
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 50%; max-width: 100px"></canvas>
+ </div>
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 100%; max-width: 100px"></canvas>
+ </div>
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 200%; max-width: 100px"></canvas>
+ </div>
+
+ <!-- Set 'max-width' to a percentage -->
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 100px; max-width: 0%"></canvas>
+ </div>
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 100px; max-width: 50%"></canvas>
+ </div>
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 100px; max-width: 100%"></canvas>
+ </div>
+ <div class="wrapper" data-expected-client-width="0">
+ <canvas style="width: 100px; max-width: 200%"></canvas>
+ </div>
+</div>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+checkLayout(".wrapper");
+</script>