mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Treat % as 0 for the min-content contribution of replaced elements (#32103)
`width` and `max-width` typically treat expressions with percentages as their initial value, but for the min-content contribution of replaced elements, they should instead be treated as zero. https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
dd9164f49a
commit
1c321a17ac
6 changed files with 87 additions and 11 deletions
|
@ -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 */
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 {
|
||||
|
|
7
tests/wpt/meta/MANIFEST.json
vendored
7
tests/wpt/meta/MANIFEST.json
vendored
|
@ -581052,6 +581052,13 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"intrinsic-percent-replaced-028.html": [
|
||||
"f54245a1e1f0aabff40ed8823279b8c0bb48f93d",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"intrinsic-size-fallback-replaced.html": [
|
||||
"a3325b0aea01c008ec322a20e0f279d5bd765b1c",
|
||||
[
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[keyword-sizes-on-abspos.html]
|
||||
[.test 17]
|
||||
expected: FAIL
|
||||
|
||||
[.test 22]
|
||||
expected: FAIL
|
||||
|
||||
[.test 27]
|
||||
expected: FAIL
|
50
tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html
vendored
Normal file
50
tests/wpt/tests/css/css-sizing/intrinsic-percent-replaced-028.html
vendored
Normal file
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue