mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Implement the aspect-ratio
property for replaced elements (#32800)
* Add WPT tests for box-sizing with aspect-ratio Signed-off-by: valadaptive <valadaptive@protonmail.com> * Implement `aspect-ratio` for replaced elements There are two regressions because we don't implement `object-fit`, and one because we don't properly represent non-available <img>s with `alt` attributes. Signed-off-by: valadaptive <valadaptive@protonmail.com> --------- Signed-off-by: valadaptive <valadaptive@protonmail.com>
This commit is contained in:
parent
e425ad0cb7
commit
60e65c175d
26 changed files with 314 additions and 62 deletions
|
@ -14,6 +14,7 @@ use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
|
||||||
use pixels::Image;
|
use pixels::Image;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use servo_arc::Arc as ServoArc;
|
use servo_arc::Arc as ServoArc;
|
||||||
|
use style::logical_geometry::Direction;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::servo::url::ComputedUrl;
|
use style::servo::url::ComputedUrl;
|
||||||
use style::values::computed::image::Image as ComputedImage;
|
use style::values::computed::image::Image as ComputedImage;
|
||||||
|
@ -359,12 +360,18 @@ impl ReplacedContent {
|
||||||
) -> LogicalVec2<Au> {
|
) -> LogicalVec2<Au> {
|
||||||
let mode = style.writing_mode;
|
let mode = style.writing_mode;
|
||||||
let intrinsic_size = self.flow_relative_intrinsic_size(style);
|
let intrinsic_size = self.flow_relative_intrinsic_size(style);
|
||||||
let intrinsic_ratio = self.inline_size_over_block_size_intrinsic_ratio(style);
|
let intrinsic_ratio = style.preferred_aspect_ratio(
|
||||||
|
self.inline_size_over_block_size_intrinsic_ratio(style),
|
||||||
|
containing_block,
|
||||||
|
);
|
||||||
|
|
||||||
let box_size = box_size.unwrap_or(
|
let box_size = box_size.unwrap_or(
|
||||||
style
|
style
|
||||||
.content_box_size(containing_block, pbm)
|
.content_box_size(containing_block, pbm)
|
||||||
.map(|v| v.map(Au::from)),
|
// We need to clamp to zero here to obtain the proper aspect
|
||||||
|
// ratio when box-sizing is border-box and the inner box size
|
||||||
|
// would otherwise be negative.
|
||||||
|
.map(|v| v.map(|v| Au::from(v).max(Au::zero()))),
|
||||||
);
|
);
|
||||||
let max_box_size = style
|
let max_box_size = style
|
||||||
.content_max_box_size(containing_block, pbm)
|
.content_max_box_size(containing_block, pbm)
|
||||||
|
@ -393,8 +400,8 @@ impl ReplacedContent {
|
||||||
LogicalVec2 { inline, block }
|
LogicalVec2 { inline, block }
|
||||||
},
|
},
|
||||||
(AuOrAuto::LengthPercentage(inline), AuOrAuto::Auto) => {
|
(AuOrAuto::LengthPercentage(inline), AuOrAuto::Auto) => {
|
||||||
let block = if let Some(i_over_b) = intrinsic_ratio {
|
let block = if let Some(ratio) = intrinsic_ratio {
|
||||||
inline.scale_by(1.0 / i_over_b)
|
ratio.compute_dependent_size(Direction::Block, inline)
|
||||||
} else if let Some(block) = intrinsic_size.block {
|
} else if let Some(block) = intrinsic_size.block {
|
||||||
block
|
block
|
||||||
} else {
|
} else {
|
||||||
|
@ -403,8 +410,8 @@ impl ReplacedContent {
|
||||||
LogicalVec2 { inline, block }
|
LogicalVec2 { inline, block }
|
||||||
},
|
},
|
||||||
(AuOrAuto::Auto, AuOrAuto::LengthPercentage(block)) => {
|
(AuOrAuto::Auto, AuOrAuto::LengthPercentage(block)) => {
|
||||||
let inline = if let Some(i_over_b) = intrinsic_ratio {
|
let inline = if let Some(ratio) = intrinsic_ratio {
|
||||||
block.scale_by(i_over_b)
|
ratio.compute_dependent_size(Direction::Inline, block)
|
||||||
} else if let Some(inline) = intrinsic_size.inline {
|
} else if let Some(inline) = intrinsic_size.inline {
|
||||||
inline
|
inline
|
||||||
} else {
|
} else {
|
||||||
|
@ -416,10 +423,10 @@ impl ReplacedContent {
|
||||||
let inline_size =
|
let inline_size =
|
||||||
match (intrinsic_size.inline, intrinsic_size.block, intrinsic_ratio) {
|
match (intrinsic_size.inline, intrinsic_size.block, intrinsic_ratio) {
|
||||||
(Some(inline), _, _) => inline,
|
(Some(inline), _, _) => inline,
|
||||||
(None, Some(block), Some(i_over_b)) => {
|
(None, Some(block), Some(ratio)) => {
|
||||||
// “used height” in CSS 2 is always gonna be the intrinsic one,
|
// “used height” in CSS 2 is always gonna be the intrinsic one,
|
||||||
// since it is available.
|
// since it is available.
|
||||||
block.scale_by(i_over_b)
|
ratio.compute_dependent_size(Direction::Inline, block)
|
||||||
},
|
},
|
||||||
// FIXME
|
// FIXME
|
||||||
//
|
//
|
||||||
|
@ -442,9 +449,9 @@ impl ReplacedContent {
|
||||||
};
|
};
|
||||||
let block_size = if let Some(block) = intrinsic_size.block {
|
let block_size = if let Some(block) = intrinsic_size.block {
|
||||||
block
|
block
|
||||||
} else if let Some(i_over_b) = intrinsic_ratio {
|
} else if let Some(ratio) = intrinsic_ratio {
|
||||||
// “used width” in CSS 2 is what we just computed above
|
// “used width” in CSS 2 is what we just computed above
|
||||||
inline_size.scale_by(1.0 / i_over_b)
|
ratio.compute_dependent_size(Direction::Block, inline_size)
|
||||||
} else {
|
} else {
|
||||||
default_object_size().block
|
default_object_size().block
|
||||||
};
|
};
|
||||||
|
@ -459,7 +466,7 @@ impl ReplacedContent {
|
||||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
||||||
// “However, for replaced elements with an intrinsic ratio and both
|
// “However, for replaced elements with an intrinsic ratio and both
|
||||||
// 'width' and 'height' specified as 'auto', the algorithm is as follows”
|
// 'width' and 'height' specified as 'auto', the algorithm is as follows”
|
||||||
if let (AuOrAuto::Auto, AuOrAuto::Auto, Some(i_over_b)) =
|
if let (AuOrAuto::Auto, AuOrAuto::Auto, Some(ratio)) =
|
||||||
(box_size.inline, box_size.block, intrinsic_ratio)
|
(box_size.inline, box_size.block, intrinsic_ratio)
|
||||||
{
|
{
|
||||||
let LogicalVec2 {
|
let LogicalVec2 {
|
||||||
|
@ -495,26 +502,28 @@ impl ReplacedContent {
|
||||||
// Row 2.
|
// Row 2.
|
||||||
(Violation::Above(max_inline_size), Violation::None) => LogicalVec2 {
|
(Violation::Above(max_inline_size), Violation::None) => LogicalVec2 {
|
||||||
inline: max_inline_size,
|
inline: max_inline_size,
|
||||||
block: max_inline_size
|
block: ratio
|
||||||
.scale_by(1.0 / i_over_b)
|
.compute_dependent_size(Direction::Block, max_inline_size)
|
||||||
.max(min_box_size.block),
|
.max(min_box_size.block),
|
||||||
},
|
},
|
||||||
// Row 3.
|
// Row 3.
|
||||||
(Violation::Below(min_inline_size), Violation::None) => LogicalVec2 {
|
(Violation::Below(min_inline_size), Violation::None) => LogicalVec2 {
|
||||||
inline: min_inline_size,
|
inline: min_inline_size,
|
||||||
block: min_inline_size
|
block: ratio
|
||||||
.scale_by(1.0 / i_over_b)
|
.compute_dependent_size(Direction::Block, min_inline_size)
|
||||||
.clamp_below_max(max_box_size.block),
|
.clamp_below_max(max_box_size.block),
|
||||||
},
|
},
|
||||||
// Row 4.
|
// Row 4.
|
||||||
(Violation::None, Violation::Above(max_block_size)) => LogicalVec2 {
|
(Violation::None, Violation::Above(max_block_size)) => LogicalVec2 {
|
||||||
inline: max_block_size.scale_by(i_over_b).max(min_box_size.inline),
|
inline: ratio
|
||||||
|
.compute_dependent_size(Direction::Inline, max_block_size)
|
||||||
|
.max(min_box_size.inline),
|
||||||
block: max_block_size,
|
block: max_block_size,
|
||||||
},
|
},
|
||||||
// Row 5.
|
// Row 5.
|
||||||
(Violation::None, Violation::Below(min_block_size)) => LogicalVec2 {
|
(Violation::None, Violation::Below(min_block_size)) => LogicalVec2 {
|
||||||
inline: min_block_size
|
inline: ratio
|
||||||
.scale_by(i_over_b)
|
.compute_dependent_size(Direction::Inline, min_block_size)
|
||||||
.clamp_below_max(max_box_size.inline),
|
.clamp_below_max(max_box_size.inline),
|
||||||
block: min_block_size,
|
block: min_block_size,
|
||||||
},
|
},
|
||||||
|
@ -524,14 +533,16 @@ impl ReplacedContent {
|
||||||
// Row 6.
|
// Row 6.
|
||||||
LogicalVec2 {
|
LogicalVec2 {
|
||||||
inline: max_inline_size,
|
inline: max_inline_size,
|
||||||
block: max_inline_size
|
block: ratio
|
||||||
.scale_by(1.0 / i_over_b)
|
.compute_dependent_size(Direction::Block, max_inline_size)
|
||||||
.max(min_box_size.block),
|
.max(min_box_size.block),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Row 7.
|
// Row 7.
|
||||||
LogicalVec2 {
|
LogicalVec2 {
|
||||||
inline: max_block_size.scale_by(i_over_b).max(min_box_size.inline),
|
inline: ratio
|
||||||
|
.compute_dependent_size(Direction::Inline, max_block_size)
|
||||||
|
.max(min_box_size.inline),
|
||||||
block: max_block_size,
|
block: max_block_size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,8 +552,8 @@ impl ReplacedContent {
|
||||||
if min_inline_size.0 * block_size.0 <= min_block_size.0 * inline_size.0 {
|
if min_inline_size.0 * block_size.0 <= min_block_size.0 * inline_size.0 {
|
||||||
// Row 8.
|
// Row 8.
|
||||||
LogicalVec2 {
|
LogicalVec2 {
|
||||||
inline: min_block_size
|
inline: ratio
|
||||||
.scale_by(i_over_b)
|
.compute_dependent_size(Direction::Inline, min_block_size)
|
||||||
.clamp_below_max(max_box_size.inline),
|
.clamp_below_max(max_box_size.inline),
|
||||||
block: min_block_size,
|
block: min_block_size,
|
||||||
}
|
}
|
||||||
|
@ -550,8 +561,8 @@ impl ReplacedContent {
|
||||||
// Row 9.
|
// Row 9.
|
||||||
LogicalVec2 {
|
LogicalVec2 {
|
||||||
inline: min_inline_size,
|
inline: min_inline_size,
|
||||||
block: min_inline_size
|
block: ratio
|
||||||
.scale_by(1.0 / i_over_b)
|
.compute_dependent_size(Direction::Block, min_inline_size)
|
||||||
.clamp_below_max(max_box_size.block),
|
.clamp_below_max(max_box_size.block),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use app_units::Au;
|
||||||
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
||||||
use style::computed_values::position::T as ComputedPosition;
|
use style::computed_values::position::T as ComputedPosition;
|
||||||
use style::computed_values::transform_style::T as ComputedTransformStyle;
|
use style::computed_values::transform_style::T as ComputedTransformStyle;
|
||||||
use style::logical_geometry::WritingMode;
|
use style::logical_geometry::{Direction, WritingMode};
|
||||||
use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity;
|
use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity;
|
||||||
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||||
use style::properties::longhands::column_span::computed_value::T as ColumnSpan;
|
use style::properties::longhands::column_span::computed_value::T as ColumnSpan;
|
||||||
|
@ -15,7 +15,9 @@ use style::values::computed::image::Image as ComputedImageLayer;
|
||||||
use style::values::computed::{Length, LengthPercentage, NonNegativeLengthPercentage, Size};
|
use style::values::computed::{Length, LengthPercentage, NonNegativeLengthPercentage, Size};
|
||||||
use style::values::generics::box_::Perspective;
|
use style::values::generics::box_::Perspective;
|
||||||
use style::values::generics::length::MaxSize;
|
use style::values::generics::length::MaxSize;
|
||||||
|
use style::values::generics::position::{GenericAspectRatio, PreferredRatio};
|
||||||
use style::values::specified::{box_ as stylo, Overflow};
|
use style::values::specified::{box_ as stylo, Overflow};
|
||||||
|
use style::values::CSSFloat;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
use webrender_api as wr;
|
use webrender_api as wr;
|
||||||
|
|
||||||
|
@ -143,6 +145,43 @@ impl PaddingBorderMargin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolved `aspect-ratio` property with respect to a specific element. Depends
|
||||||
|
/// on that element's `box-sizing` (and padding and border, if that `box-sizing`
|
||||||
|
/// is `border-box`).
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub(crate) struct AspectRatio {
|
||||||
|
/// If the element that this aspect ratio belongs to uses box-sizing:
|
||||||
|
/// border-box, and the aspect-ratio property does not contain "auto", then
|
||||||
|
/// the aspect ratio is in respect to the border box. This will then contain
|
||||||
|
/// the summed sizes of the padding and border. Otherwise, it's 0.
|
||||||
|
box_sizing_adjustment: LogicalVec2<Au>,
|
||||||
|
/// The ratio itself (inline over block).
|
||||||
|
i_over_b: CSSFloat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AspectRatio {
|
||||||
|
/// Given one side length, compute the other one.
|
||||||
|
pub(crate) fn compute_dependent_size(
|
||||||
|
&self,
|
||||||
|
ratio_dependent_axis: Direction,
|
||||||
|
ratio_determining_size: Au,
|
||||||
|
) -> Au {
|
||||||
|
match ratio_dependent_axis {
|
||||||
|
// Calculate the inline size from the block size
|
||||||
|
Direction::Inline => {
|
||||||
|
(ratio_determining_size + self.box_sizing_adjustment.block).scale_by(self.i_over_b) -
|
||||||
|
self.box_sizing_adjustment.inline
|
||||||
|
},
|
||||||
|
// Calculate the block size from the inline size
|
||||||
|
Direction::Block => {
|
||||||
|
(ratio_determining_size + self.box_sizing_adjustment.inline)
|
||||||
|
.scale_by(1.0 / self.i_over_b) -
|
||||||
|
self.box_sizing_adjustment.block
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) trait ComputedValuesExt {
|
pub(crate) trait ComputedValuesExt {
|
||||||
fn box_offsets(
|
fn box_offsets(
|
||||||
&self,
|
&self,
|
||||||
|
@ -198,6 +237,11 @@ pub(crate) trait ComputedValuesExt {
|
||||||
&self,
|
&self,
|
||||||
fragment_flags: FragmentFlags,
|
fragment_flags: FragmentFlags,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
fn preferred_aspect_ratio(
|
||||||
|
&self,
|
||||||
|
natural_aspect_ratio: Option<CSSFloat>,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
) -> Option<AspectRatio>;
|
||||||
fn background_is_transparent(&self) -> bool;
|
fn background_is_transparent(&self) -> bool;
|
||||||
fn get_webrender_primitive_flags(&self) -> wr::PrimitiveFlags;
|
fn get_webrender_primitive_flags(&self) -> wr::PrimitiveFlags;
|
||||||
}
|
}
|
||||||
|
@ -535,6 +579,75 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve the preferred aspect ratio according to the given natural aspect
|
||||||
|
/// ratio and the `aspect-ratio` property.
|
||||||
|
/// See <https://drafts.csswg.org/css-sizing-4/#aspect-ratio>.
|
||||||
|
fn preferred_aspect_ratio(
|
||||||
|
&self,
|
||||||
|
natural_aspect_ratio: Option<CSSFloat>,
|
||||||
|
containing_block: &ContainingBlock,
|
||||||
|
) -> Option<AspectRatio> {
|
||||||
|
let GenericAspectRatio {
|
||||||
|
auto,
|
||||||
|
ratio: mut preferred_ratio,
|
||||||
|
} = self.clone_aspect_ratio();
|
||||||
|
|
||||||
|
// For all cases where a ratio is specified:
|
||||||
|
// "If the <ratio> is degenerate, the property instead behaves as auto."
|
||||||
|
if matches!(preferred_ratio, PreferredRatio::Ratio(ratio) if ratio.is_degenerate()) {
|
||||||
|
preferred_ratio = PreferredRatio::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
match (auto, preferred_ratio) {
|
||||||
|
// The value `auto`. Either the ratio was not specified, or was
|
||||||
|
// degenerate and set to PreferredRatio::None above.
|
||||||
|
//
|
||||||
|
// "Replaced elements with a natural aspect ratio use that aspect
|
||||||
|
// ratio; otherwise the box has no preferred aspect ratio. Size
|
||||||
|
// calculations involving the aspect ratio work with the content box
|
||||||
|
// dimensions always."
|
||||||
|
(_, PreferredRatio::None) => natural_aspect_ratio.map(|natural_ratio| AspectRatio {
|
||||||
|
i_over_b: natural_ratio,
|
||||||
|
box_sizing_adjustment: LogicalVec2::zero(),
|
||||||
|
}),
|
||||||
|
// "If both auto and a <ratio> are specified together, the preferred
|
||||||
|
// aspect ratio is the specified ratio of width / height unless it
|
||||||
|
// is a replaced element with a natural aspect ratio, in which case
|
||||||
|
// that aspect ratio is used instead. In all cases, size
|
||||||
|
// calculations involving the aspect ratio work with the content box
|
||||||
|
// dimensions always."
|
||||||
|
(true, PreferredRatio::Ratio(preferred_ratio)) => match natural_aspect_ratio {
|
||||||
|
Some(natural_ratio) => Some(AspectRatio {
|
||||||
|
i_over_b: natural_ratio,
|
||||||
|
box_sizing_adjustment: LogicalVec2::zero(),
|
||||||
|
}),
|
||||||
|
None => Some(AspectRatio {
|
||||||
|
i_over_b: (preferred_ratio.0).0 / (preferred_ratio.1).0,
|
||||||
|
box_sizing_adjustment: LogicalVec2::zero(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
|
||||||
|
// "The box’s preferred aspect ratio is the specified ratio of width
|
||||||
|
// / height. Size calculations involving the aspect ratio work with
|
||||||
|
// the dimensions of the box specified by box-sizing."
|
||||||
|
(false, PreferredRatio::Ratio(preferred_ratio)) => {
|
||||||
|
// If the `box-sizing` is `border-box`, use the padding and
|
||||||
|
// border when calculating the aspect ratio.
|
||||||
|
let box_sizing_adjustment = match self.clone_box_sizing() {
|
||||||
|
BoxSizing::ContentBox => LogicalVec2::zero(),
|
||||||
|
BoxSizing::BorderBox => {
|
||||||
|
self.padding_border_margin(containing_block)
|
||||||
|
.padding_border_sums
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Some(AspectRatio {
|
||||||
|
i_over_b: (preferred_ratio.0).0 / (preferred_ratio.1).0,
|
||||||
|
box_sizing_adjustment,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether or not this style specifies a non-transparent background.
|
/// Whether or not this style specifies a non-transparent background.
|
||||||
fn background_is_transparent(&self) -> bool {
|
fn background_is_transparent(&self) -> bool {
|
||||||
let background = self.get_background();
|
let background = self.get_background();
|
||||||
|
|
14
tests/wpt/meta/MANIFEST.json
vendored
14
tests/wpt/meta/MANIFEST.json
vendored
|
@ -556187,6 +556187,20 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"aspect-ratio": {
|
"aspect-ratio": {
|
||||||
|
"box-sizing-dimensions.html": [
|
||||||
|
"126c3e30583edc1fb61ed5dab62187e64b597500",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"box-sizing-squashed.html": [
|
||||||
|
"542dabe1b5c11784257018b6352151d9940f59bf",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"fractional-aspect-ratio.html": [
|
"fractional-aspect-ratio.html": [
|
||||||
"7186f35f8a2e62d6bae515ab0453c2af5041c23b",
|
"7186f35f8a2e62d6bae515ab0453c2af5041c23b",
|
||||||
[
|
[
|
||||||
|
|
12
tests/wpt/meta/css/css-sizing/aspect-ratio/box-sizing-dimensions.html.ini
vendored
Normal file
12
tests/wpt/meta/css/css-sizing/aspect-ratio/box-sizing-dimensions.html.ini
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[box-sizing-dimensions.html]
|
||||||
|
[.item 5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 7]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 8]
|
||||||
|
expected: FAIL
|
18
tests/wpt/meta/css/css-sizing/aspect-ratio/box-sizing-squashed.html.ini
vendored
Normal file
18
tests/wpt/meta/css/css-sizing/aspect-ratio/box-sizing-squashed.html.ini
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[box-sizing-squashed.html]
|
||||||
|
[.item 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 12]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 13]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 14]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 15]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.item 16]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-aspect-ratio-015.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-aspect-ratio-016.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-aspect-ratio-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-aspect-ratio-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-009.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-012.html]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/css-sizing/aspect-ratio/replaced-element-024.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-sizing/aspect-ratio/replaced-element-024.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[replaced-element-024.html]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-025.html]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/css-sizing/aspect-ratio/replaced-element-026.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-sizing/aspect-ratio/replaced-element-026.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[replaced-element-026.html]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-027.html]
|
|
||||||
expected: FAIL
|
|
3
tests/wpt/meta/css/css-sizing/aspect-ratio/replaced-element-028.html.ini
vendored
Normal file
3
tests/wpt/meta/css/css-sizing/aspect-ratio/replaced-element-028.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[replaced-element-028.html]
|
||||||
|
[CSS aspect-ratio: img]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-031.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-032.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-033.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[replaced-element-036.html]
|
|
||||||
[display:block img should be 200px high]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[display:inline-block img should be 200px high]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[replaced-element-dynamic-aspect-ratio.html]
|
|
||||||
expected: FAIL
|
|
51
tests/wpt/tests/css/css-sizing/aspect-ratio/box-sizing-dimensions.html
vendored
Normal file
51
tests/wpt/tests/css/css-sizing/aspect-ratio/box-sizing-dimensions.html
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS aspect-ratio: uses content box when "auto" is present and box-sizing dimensions when it is absent</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
|
||||||
|
<meta name="assert" content='CSS aspect-ratio: uses content box when "auto" is present and box-sizing dimensions when it is absent.'>
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
border: 20px solid blue;
|
||||||
|
width: 100px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aspect {
|
||||||
|
aspect-ratio: 2 / 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aspect-auto {
|
||||||
|
aspect-ratio: auto 2 / 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-box {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.non-replaced {
|
||||||
|
background: green;
|
||||||
|
border: 20px solid blue;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.item')">
|
||||||
|
|
||||||
|
<img class="item aspect" src="./support/20x50-green.png" width="20" height="50" data-expected-width="140" data-expected-height="90">
|
||||||
|
|
||||||
|
<img class="item aspect border-box" src="./support/20x50-green.png" width="20" height="50" data-expected-width="100" data-expected-height="50">
|
||||||
|
|
||||||
|
<img class="item aspect-auto" src="./support/20x50-green.png" width="20" height="50" data-expected-width="140" data-expected-height="290">
|
||||||
|
|
||||||
|
<img class="item aspect-auto border-box" src="./support/20x50-green.png" width="20" height="50" data-expected-width="100" data-expected-height="190">
|
||||||
|
|
||||||
|
<div class="item non-replaced aspect" data-expected-width="140" data-expected-height="90"></div>
|
||||||
|
|
||||||
|
<div class="item non-replaced aspect border-box" data-expected-width="100" data-expected-height="50"></div>
|
||||||
|
|
||||||
|
<div class="item non-replaced aspect-auto" data-expected-width="140" data-expected-height="90"></div>
|
||||||
|
|
||||||
|
<div class="item non-replaced aspect-auto border-box" data-expected-width="100" data-expected-height="70"></div>
|
62
tests/wpt/tests/css/css-sizing/aspect-ratio/box-sizing-squashed.html
vendored
Normal file
62
tests/wpt/tests/css/css-sizing/aspect-ratio/box-sizing-squashed.html
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS aspect-ratio: correct ratio maintained when box-sizing: border-box and one axis is clamped to 0</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
|
||||||
|
<meta name="assert" content='CSS aspect-ratio: correct ratio maintained when box-sizing: border-box and one axis is clamped to 0.'>
|
||||||
|
<style>
|
||||||
|
.item {
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 20px solid blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.horizontal {
|
||||||
|
aspect-ratio: 2 / 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical {
|
||||||
|
aspect-ratio: 1 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.non-replaced {
|
||||||
|
background: green;
|
||||||
|
/* Break the items apart to make them individually distinguishable */
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.item')">
|
||||||
|
|
||||||
|
<img class="item horizontal" style="width: 50px; height: auto" src="./support/20x50-green.png" width="20" height="50" data-expected-width="50" data-expected-height="40">
|
||||||
|
|
||||||
|
<img class="item horizontal" style="width: auto; height: 20px" src="./support/20x50-green.png" width="20" height="50" data-expected-width="80" data-expected-height="40">
|
||||||
|
|
||||||
|
<img class="item horizontal" style="max-width: 50px; height: auto" src="./support/20x50-green.png" width="20" height="50" data-expected-width="40" data-expected-height="40">
|
||||||
|
|
||||||
|
<img class="item horizontal" style="width: auto; max-height: 20px" src="./support/20x50-green.png" width="20" height="50" data-expected-width="80" data-expected-height="40">
|
||||||
|
|
||||||
|
<img class="item vertical" style="height: 50px; width: auto" src="./support/20x50-green.png" width="20" height="50" data-expected-width="40" data-expected-height="50">
|
||||||
|
|
||||||
|
<img class="item vertical" style="height: auto; width: 20px" src="./support/20x50-green.png" width="20" height="50" data-expected-width="40" data-expected-height="80">
|
||||||
|
|
||||||
|
<img class="item vertical" style="max-height: 50px; width: auto" src="./support/20x50-green.png" width="20" height="50" data-expected-width="40" data-expected-height="50">
|
||||||
|
|
||||||
|
<img class="item vertical" style="height: auto; max-width: 20px" src="./support/20x50-green.png" width="20" height="50" data-expected-width="40" data-expected-height="80">
|
||||||
|
|
||||||
|
<div class="non-replaced item horizontal" style="width: 50px; height: auto" width="20" height="50" data-expected-width="50" data-expected-height="40"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item horizontal" style="width: auto; height: 20px" width="20" height="50" data-expected-width="80" data-expected-height="40"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item horizontal" style="max-width: 50px; height: auto" width="20" height="50" data-expected-width="50" data-expected-height="40"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item horizontal" style="width: auto; max-height: 20px" width="20" height="50" data-expected-width="80" data-expected-height="40"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item vertical" style="height: 50px; width: auto" width="20" height="50" data-expected-width="40" data-expected-height="50"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item vertical" style="height: auto; width: 20px" width="20" height="50" data-expected-width="40" data-expected-height="80"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item vertical" style="max-height: 50px; width: auto" width="20" height="50" data-expected-width="40" data-expected-height="50"></div>
|
||||||
|
|
||||||
|
<div class="non-replaced item vertical" style="height: auto; max-width: 20px" width="20" height="50" data-expected-width="40" data-expected-height="80"></div>
|
Loading…
Add table
Add a link
Reference in a new issue