mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Respect min/max constraints in the block axis of block containers (#33203)
Consider a block container that establishes an inline formatting context and has a definite `block-size` which is clamped by `min-block-size` or `max-block-size`. We were already sizing such container correctly, however, its contents were resolving their percentages against the unclamped `block-size` value. This patch fixes the `ContainingBlock` that we pass to the contents so that they resolve percentages correctly. Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
fef44620cc
commit
5d43d88b6c
4 changed files with 60 additions and 19 deletions
|
@ -127,7 +127,7 @@ use crate::fragment_tree::{
|
||||||
use crate::geom::{LogicalRect, LogicalVec2, PhysicalRect, ToLogical};
|
use crate::geom::{LogicalRect, LogicalVec2, PhysicalRect, ToLogical};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::ContentSizes;
|
||||||
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin};
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
|
|
||||||
// From gfxFontConstants.h in Firefox.
|
// From gfxFontConstants.h in Firefox.
|
||||||
|
@ -1945,14 +1945,17 @@ impl IndependentFormattingContext {
|
||||||
IndependentFormattingContext::NonReplaced(non_replaced) => {
|
IndependentFormattingContext::NonReplaced(non_replaced) => {
|
||||||
let box_size = non_replaced
|
let box_size = non_replaced
|
||||||
.style
|
.style
|
||||||
.content_box_size(layout.containing_block, &pbm);
|
.content_box_size(layout.containing_block, &pbm)
|
||||||
|
.map(|v| v.map(Au::from));
|
||||||
let max_box_size = non_replaced
|
let max_box_size = non_replaced
|
||||||
.style
|
.style
|
||||||
.content_max_box_size(layout.containing_block, &pbm);
|
.content_max_box_size(layout.containing_block, &pbm)
|
||||||
|
.map(|v| v.map(Au::from));
|
||||||
let min_box_size = non_replaced
|
let min_box_size = non_replaced
|
||||||
.style
|
.style
|
||||||
.content_min_box_size(layout.containing_block, &pbm)
|
.content_min_box_size(layout.containing_block, &pbm)
|
||||||
.auto_is(Length::zero);
|
.map(|v| v.map(Au::from))
|
||||||
|
.auto_is(Au::zero);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
|
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
|
||||||
let tentative_inline_size = box_size.inline.auto_is(|| {
|
let tentative_inline_size = box_size.inline.auto_is(|| {
|
||||||
|
@ -1969,10 +1972,13 @@ impl IndependentFormattingContext {
|
||||||
// always results in that size.
|
// always results in that size.
|
||||||
let inline_size = tentative_inline_size
|
let inline_size = tentative_inline_size
|
||||||
.clamp_between_extremums(min_box_size.inline, max_box_size.inline);
|
.clamp_between_extremums(min_box_size.inline, max_box_size.inline);
|
||||||
|
let block_size = box_size
|
||||||
|
.block
|
||||||
|
.map(|v| v.clamp_between_extremums(min_box_size.block, max_box_size.block));
|
||||||
|
|
||||||
let containing_block_for_children = ContainingBlock {
|
let containing_block_for_children = ContainingBlock {
|
||||||
inline_size: inline_size.into(),
|
inline_size,
|
||||||
block_size: box_size.block.map(|t| t.into()),
|
block_size,
|
||||||
style: &non_replaced.style,
|
style: &non_replaced.style,
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -2001,17 +2007,15 @@ impl IndependentFormattingContext {
|
||||||
Some(inline) => (inline, independent_layout.content_block_size),
|
Some(inline) => (inline, independent_layout.content_block_size),
|
||||||
None => {
|
None => {
|
||||||
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
|
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
|
||||||
let tentative_block_size = box_size
|
let block_size = block_size.auto_is(|| {
|
||||||
.block
|
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
||||||
.auto_is(|| independent_layout.content_block_size.into());
|
// In this case “applying the rules above again” with a non-auto block-size
|
||||||
|
// always results in that size.
|
||||||
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
independent_layout
|
||||||
// In this case “applying the rules above again” with a non-auto block-size
|
.content_block_size
|
||||||
// always results in that size.
|
.clamp_between_extremums(min_box_size.block, max_box_size.block)
|
||||||
let block_size = tentative_block_size
|
});
|
||||||
.clamp_between_extremums(min_box_size.block, max_box_size.block);
|
(inline_size, block_size)
|
||||||
|
|
||||||
(inline_size.into(), block_size.into())
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
tests/wpt/meta/MANIFEST.json
vendored
13
tests/wpt/meta/MANIFEST.json
vendored
|
@ -81619,6 +81619,19 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"max-height-applies-to-017.html": [
|
||||||
|
"3543b19ee33dbbd93e3b8455458123bf298bd4a1",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/CSS2/reference/ref-filled-green-100px-square.xht",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"max-height-percentage-001.xht": [
|
"max-height-percentage-001.xht": [
|
||||||
"5ac6f609e9c68384771a207119363215ad8149ca",
|
"5ac6f609e9c68384771a207119363215ad8149ca",
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[max-height-applies-to-014.xht]
|
|
||||||
expected: FAIL
|
|
26
tests/wpt/tests/css/CSS2/normal-flow/max-height-applies-to-017.html
vendored
Normal file
26
tests/wpt/tests/css/CSS2/normal-flow/max-height-applies-to-017.html
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>CSS Test: Max-Height applied to element with 'display' set to 'inline-block'</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||||
|
<link rel="help" href="http://www.w3.org/TR/CSS21/visudet.html#min-max-heights">
|
||||||
|
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<meta name="assert" content="The percentage in #child should resolve against the 100px maximum of #parent, not against 200px.">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#parent {
|
||||||
|
display: inline-block;
|
||||||
|
height: 200px;
|
||||||
|
max-height: 100px;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
#child {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100px;
|
||||||
|
height: 100%;
|
||||||
|
background: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div id="parent">
|
||||||
|
<span id="child"></span>
|
||||||
|
</div>
|
Loading…
Add table
Add a link
Reference in a new issue