mirror of
https://github.com/servo/servo.git
synced 2025-07-24 07:40:27 +01:00
layout: Don't try to vertically align absolutely positioned children of
table rows. Improves http://reddit.com/r/aww.
This commit is contained in:
parent
781a077145
commit
18cf103ee0
4 changed files with 111 additions and 34 deletions
|
@ -12,7 +12,7 @@ use context::{LayoutContext, SharedLayoutContext};
|
|||
use cssparser::Color;
|
||||
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
|
||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
||||
use flow::{self, Flow, FlowClass, OpaqueFlow};
|
||||
use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow};
|
||||
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
|
||||
use gfx::display_list::StackingContext;
|
||||
use gfx_traits::print_tree::PrintTree;
|
||||
|
@ -81,42 +81,53 @@ impl TableCellFlow {
|
|||
pub fn valign_children(&mut self) {
|
||||
// Note to the reader: this code has been tested with negative margins.
|
||||
// We end up with a "end" that's before the "start," but the math still works out.
|
||||
let first_start = flow::base(self).children.front().map(|kid| {
|
||||
let mut extents = None;
|
||||
for kid in flow::base(self).children.iter() {
|
||||
let kid_base = flow::base(kid);
|
||||
flow::base(kid).position.start.b
|
||||
- kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context()
|
||||
});
|
||||
if let Some(mut first_start) = first_start {
|
||||
let mut last_end = first_start;
|
||||
for kid in flow::base(self).children.iter() {
|
||||
let kid_base = flow::base(kid);
|
||||
let start = kid_base.position.start.b
|
||||
- kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context();
|
||||
let end = kid_base.position.start.b + kid_base.position.size.block
|
||||
+ kid_base.collapsible_margins.block_end_margin_for_noncollapsible_context();
|
||||
if start < first_start {
|
||||
first_start = start;
|
||||
}
|
||||
if end > last_end {
|
||||
last_end = end;
|
||||
}
|
||||
if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
continue
|
||||
}
|
||||
let kids_size = last_end - first_start;
|
||||
let self_size = flow::base(self).position.size.block -
|
||||
self.block_flow.fragment.border_padding.block_start_end();
|
||||
let kids_self_gap = self_size - kids_size;
|
||||
|
||||
// This offset should also account for vertical_align::T::baseline.
|
||||
// Need max cell ascent from the first row of this cell.
|
||||
let offset = match self.block_flow.fragment.style().get_box().vertical_align {
|
||||
vertical_align::T::middle => kids_self_gap / 2,
|
||||
vertical_align::T::bottom => kids_self_gap,
|
||||
_ => Au(0),
|
||||
};
|
||||
if offset != Au(0) {
|
||||
for kid in flow::mut_base(self).children.iter_mut() {
|
||||
flow::mut_base(kid).position.start.b = flow::mut_base(kid).position.start.b + offset;
|
||||
let start = kid_base.position.start.b -
|
||||
kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context();
|
||||
let end = kid_base.position.start.b + kid_base.position.size.block +
|
||||
kid_base.collapsible_margins.block_end_margin_for_noncollapsible_context();
|
||||
match extents {
|
||||
Some((ref mut first_start, ref mut last_end)) => {
|
||||
if start < *first_start {
|
||||
*first_start = start
|
||||
}
|
||||
if end > *last_end {
|
||||
*last_end = end
|
||||
}
|
||||
}
|
||||
None => extents = Some((start, end)),
|
||||
}
|
||||
}
|
||||
let (first_start, last_end) = match extents {
|
||||
Some(extents) => extents,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let kids_size = last_end - first_start;
|
||||
let self_size = flow::base(self).position.size.block -
|
||||
self.block_flow.fragment.border_padding.block_start_end();
|
||||
let kids_self_gap = self_size - kids_size;
|
||||
|
||||
// This offset should also account for vertical_align::T::baseline.
|
||||
// Need max cell ascent from the first row of this cell.
|
||||
let offset = match self.block_flow.fragment.style().get_box().vertical_align {
|
||||
vertical_align::T::middle => kids_self_gap / 2,
|
||||
vertical_align::T::bottom => kids_self_gap,
|
||||
_ => Au(0),
|
||||
};
|
||||
if offset == Au(0) {
|
||||
return
|
||||
}
|
||||
|
||||
for kid in flow::mut_base(self).children.iter_mut() {
|
||||
let mut kid_base = flow::mut_base(kid);
|
||||
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
kid_base.position.start.b += offset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5232,6 +5232,18 @@
|
|||
"url": "/_mozilla/css/table_valign_presentational_hint_a.html"
|
||||
}
|
||||
],
|
||||
"css/table_vertical_align_absolute_a.html": [
|
||||
{
|
||||
"path": "css/table_vertical_align_absolute_a.html",
|
||||
"references": [
|
||||
[
|
||||
"/_mozilla/css/table_vertical_align_absolute_ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
"url": "/_mozilla/css/table_vertical_align_absolute_a.html"
|
||||
}
|
||||
],
|
||||
"css/table_vertical_align_margin_padding.html": [
|
||||
{
|
||||
"path": "css/table_vertical_align_margin_padding.html",
|
||||
|
@ -19038,6 +19050,18 @@
|
|||
"url": "/_mozilla/css/table_valign_presentational_hint_ref.html"
|
||||
}
|
||||
],
|
||||
"css/table_vertical_align_absolute_a.html": [
|
||||
{
|
||||
"path": "css/table_vertical_align_absolute_a.html",
|
||||
"references": [
|
||||
[
|
||||
"/_mozilla/css/table_vertical_align_absolute_ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
"url": "/_mozilla/css/table_vertical_align_absolute_a.html"
|
||||
}
|
||||
],
|
||||
"css/table_vertical_align_margin_padding.html": [
|
||||
{
|
||||
"path": "css/table_vertical_align_margin_padding.html",
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="match" href="table_vertical_align_absolute_ref.html">
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
}
|
||||
tr {
|
||||
vertical-align: bottom;
|
||||
height: 300px;
|
||||
}
|
||||
tr::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
background: blue;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<table><tr><td>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
}
|
||||
div {
|
||||
position: absolute;
|
||||
background: blue;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue