Auto merge of #7137 - pcwalton:absolute-stacking-contexts, r=glennw

layout: Make absolutely-positioned elements with `z-index: auto` not stacking contexts.

Improves many sites.

Closes #7069.

r? @glennw

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7137)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-08-11 12:22:14 -06:00
commit 7ce47266ac
27 changed files with 71 additions and 87 deletions

View file

@ -181,25 +181,31 @@ impl DisplayList {
for item in items.iter() {
match *item {
DisplayItem::SolidColorClass(ref solid_color) => {
println!("{:?} SolidColor. {:?}", indentation, solid_color.base.bounds)
println!("{} SolidColor({},{},{},{}). {:?}",
indentation,
solid_color.color.r,
solid_color.color.g,
solid_color.color.b,
solid_color.color.a,
solid_color.base.bounds)
}
DisplayItem::TextClass(ref text) => {
println!("{:?} Text. {:?}", indentation, text.base.bounds)
println!("{} Text. {:?}", indentation, text.base.bounds)
}
DisplayItem::ImageClass(ref image) => {
println!("{:?} Image. {:?}", indentation, image.base.bounds)
println!("{} Image. {:?}", indentation, image.base.bounds)
}
DisplayItem::BorderClass(ref border) => {
println!("{:?} Border. {:?}", indentation, border.base.bounds)
println!("{} Border. {:?}", indentation, border.base.bounds)
}
DisplayItem::GradientClass(ref gradient) => {
println!("{:?} Gradient. {:?}", indentation, gradient.base.bounds)
println!("{} Gradient. {:?}", indentation, gradient.base.bounds)
}
DisplayItem::LineClass(ref line) => {
println!("{:?} Line. {:?}", indentation, line.base.bounds)
println!("{} Line. {:?}", indentation, line.base.bounds)
}
DisplayItem::BoxShadowClass(ref box_shadow) => {
println!("{:?} Box_shadow. {:?}", indentation, box_shadow.base.bounds)
println!("{} Box_shadow. {:?}", indentation, box_shadow.base.bounds)
}
}
}

View file

@ -1631,15 +1631,28 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
Some(outer_display_list_for_overflow_scroll)
}
_ => {
self.build_display_list_for_block_base(
&mut *display_list,
layout_context,
border_painting_mode,
BackgroundAndBorderLevel::RootOfStackingContext);
let establishes_stacking_context = self.fragment.establishes_stacking_context();
let background_and_border_level = if establishes_stacking_context {
BackgroundAndBorderLevel::RootOfStackingContext
} else {
BackgroundAndBorderLevel::Block
};
self.build_display_list_for_block_base(&mut *display_list,
layout_context,
border_painting_mode,
background_and_border_level);
None
}
};
if !self.fragment.establishes_stacking_context() {
display_list.form_pseudo_stacking_context_for_positioned_content();
self.base.display_list_building_result =
DisplayListBuildingResult::Normal(display_list);
return
}
if !self.will_get_layer() {
// We didn't need a layer.
self.base.display_list_building_result =

View file

@ -35,9 +35,9 @@ use std::fmt;
use std::sync::{Arc, Mutex};
use string_cache::Atom;
use style::computed_values::content::ContentItem;
use style::computed_values::{border_collapse, clear, mix_blend_mode, overflow_wrap, position};
use style::computed_values::{text_align, text_decoration, white_space, word_break};
use style::computed_values::transform_style;
use style::computed_values::{border_collapse, clear, mix_blend_mode, overflow_wrap, overflow_x};
use style::computed_values::{position, text_align, text_decoration, transform_style, white_space};
use style::computed_values::{word_break, z_index};
use style::properties::{self, ComputedValues, cascade_anonymous};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentageOrNone};
@ -2027,13 +2027,24 @@ impl Fragment {
return true
}
match self.style().get_box().position {
position::T::absolute | position::T::fixed => {
// FIXME(pcwalton): This should only establish a new stacking context when
// `z-index` is not `auto`. But this matches what we did before.
true
}
position::T::relative | position::T::static_ => {
// FIXME(pcwalton): Don't unconditionally form stacking contexts for `overflow_x: scroll`
// and `overflow_y: scroll`. This needs multiple layers per stacking context.
match (self.style().get_box().position,
self.style().get_box().z_index,
self.style().get_box().overflow_x,
self.style().get_box().overflow_y.0) {
(position::T::absolute,
z_index::T::Auto,
overflow_x::T::visible,
overflow_x::T::visible) |
(position::T::fixed,
z_index::T::Auto,
overflow_x::T::visible,
overflow_x::T::visible) => false,
(position::T::absolute, _, _, _) |
(position::T::fixed, _, _, _) => true,
(position::T::relative, _, _, _) |
(position::T::static_, _, _, _) => {
// FIXME(pcwalton): `position: relative` establishes a new stacking context if
// `z-index` is not `auto`. But this matches what we did before.
false

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<style>
body, html {
margin: 0;
padding: 0;
}
</style>
<div style="background: red; position: absolute; height: 40px; width: 40px; top: 10px; left: 10px;"></div>
<div style="background: green; position: relative; height: 40px; width: 40px; top: 20px; left: 20px;"></div>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html>
<style>
body, html {
margin: 0;
padding: 0;
}
</style>
<div style="background: red; position: absolute; height: 40px; width: 40px; top: 10px; left: 10px;"></div>
<div style="background: green; position: absolute; height: 40px; width: 40px; top: 20px; left: 20px;"></div>

View file

@ -11,6 +11,7 @@ fragment=top != ../html/acid2.html acid2_ref.html
== abs_rel_explicit_height.html abs_rel_explicit_height_ref.html
== absolute_inline_containing_block_a.html absolute_inline_containing_block_ref.html
== absolute_z_index_auto_paint_order_a.html absolute_z_index_auto_paint_order_ref.html
== acid1_a.html acid1_b.html
== acid2_noscroll.html acid2_ref_broken.html
== after_block_iteration.html after_block_iteration_ref.html

View file

@ -1,3 +0,0 @@
[background-intrinsic-010.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[border-005.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[border-006.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[border-008.htm]
type: reftest
expected: FAIL

View file

@ -1,5 +0,0 @@
[content-177.htm]
type: reftest
expected:
if os == "mac": PASS
FAIL

View file

@ -1,3 +0,0 @@
[margin-bottom-103.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[margin-bottom-104.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[margin-left-113.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[position-relative-016.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-019.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-020.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-031.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-032.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-043.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-044.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-055.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-056.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-067.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-068.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-079.htm]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[top-080.htm]
type: reftest
expected: FAIL