Z-index should be ignored for non-positioned stacking contexts

When a stacking-context is not positioned, its z-index should be
ignored. This is per CSS 2 9.9.1. The only exception to this is when
the z-index is applied to an element with display: flex | inline-flex.
inline-flex does not appear to be implemented at this time so we only
do this for flex.
This commit is contained in:
Martin Robinson 2015-10-14 15:13:59 -07:00
parent ef1f0479ad
commit f2a66af463
4 changed files with 36 additions and 5 deletions

View file

@ -1331,7 +1331,7 @@ impl FragmentDisplayListBuilding for Fragment {
Arc::new(StackingContext::new(display_list, Arc::new(StackingContext::new(display_list,
&border_box, &border_box,
&overflow, &overflow,
self.style().get_box().z_index.number_or_zero(), self.effective_z_index(),
filters, filters,
self.style().get_effects().mix_blend_mode, self.style().get_effects().mix_blend_mode,
transform, transform,

View file

@ -35,9 +35,9 @@ use std::fmt;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use string_cache::Atom; use string_cache::Atom;
use style::computed_values::content::ContentItem; use style::computed_values::content::ContentItem;
use style::computed_values::{border_collapse, clear, mix_blend_mode, overflow_wrap, overflow_x}; use style::computed_values::{border_collapse, clear, display, mix_blend_mode, overflow_wrap};
use style::computed_values::{position, text_align, text_decoration, transform_style, white_space}; use style::computed_values::{overflow_x, position, text_align, text_decoration, transform_style};
use style::computed_values::{word_break, z_index}; use style::computed_values::{white_space, word_break, z_index};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentageOrNone};
@ -2166,6 +2166,25 @@ impl Fragment {
} }
} }
// Get the effective z-index of this fragment. Z-indices only apply to positioned element
// per CSS 2 9.9.1 (http://www.w3.org/TR/CSS2/visuren.html#z-index), so this value may differ
// from the value specified in the style.
pub fn effective_z_index(&self) -> i32 {
match self.style().get_box().position {
position::T::static_ => {},
_ => return self.style().get_box().z_index.number_or_zero(),
}
if self.style().get_effects().transform.0.is_some() {
return self.style().get_box().z_index.number_or_zero();
}
match self.style().get_box().display {
display::T::flex => self.style().get_box().z_index.number_or_zero(),
_ => 0,
}
}
/// Computes the overflow rect of this fragment relative to the start of the flow. /// Computes the overflow rect of this fragment relative to the start of the flow.
pub fn compute_overflow(&self, pub fn compute_overflow(&self,
flow_size: &Size2D<Au>, flow_size: &Size2D<Au>,

View file

@ -20,5 +20,12 @@
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: fixed;"></div> <div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: fixed;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: 10px; position: absolute; top: 20px; z-index: 5;"> </div> <div class="gray box" style="margin-left: 20px; margin-top: 10px; position: absolute; top: 20px; z-index: 5;"> </div>
</div> </div>
<!-- The z-index of the second box should be ignored since it is not a positioned element.
so these boxes stack in tree order. -->
<div class="test grayest box">
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; opacity: 0.999; z-index: -1;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: -40px; opacity: 0.999;"> </div>
</div>
</body> </body>
</html> </html>

View file

@ -12,12 +12,17 @@
<body> <body>
<div class="test grayest box"> <div class="test grayest box">
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: absolute;"></div> <div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: absolute;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: 10px; position: relative; top: 10px; z-index: 5;"></div> <div class="gray box" style="margin-left: 20px; margin-top: 20px; position: relative; z-index: 5;"></div>
</div> </div>
<div class="test grayest box"> <div class="test grayest box">
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: absolute;"></div> <div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: absolute;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: 10px; position: absolute; top: 20px; z-index: 5;"></div> <div class="gray box" style="margin-left: 20px; margin-top: 10px; position: absolute; top: 20px; z-index: 5;"></div>
</div> </div>
<div class="test grayest box">
<div class="grayer box" style="margin-left: 10px; margin-top: 10px; position: absolute; opacity: 0.999;"></div>
<div class="gray box" style="margin-left: 20px; margin-top: 20px; position: relative; opacity: 0.999;"></div>
</div>
</body> </body>
</html> </html>