
What No One Told You About Z-Index - philipwalton
http://philipwalton.com/articles/what-no-one-told-you-about-z-index/
======
eranation
Don't we love CSS? it's so easy to do both complex things like 3D animations
but also simple things like position something centered horizontally or
vertically by just saying align:center, oh, sorry, it's margin: 0 auto, right,
no? it's left:50% with a relative inside an absolute div, or was that an
absolute div inside a relative span?

ok so doing it vertically is really easy, it's valign:middle, oh, wait, I'm
confusing yucky table layout, it's much simpler, it's, ehm, line-height or
something, or vertical-align, but only for text, sorry, silly of me, I just do
top:50 and the relative inside absolute trick again (or vice versa, one sec
let me check in JSFiddle),

Ok aligning might not be a good example, but it's so easy to have something
snap to something else, like this DIV top right corner should always be on the
buttom left of that other div, oh, can't do without some jQuery code? of
course you can, let me go to codepen and show you for a sec, ok, never mind
that, at least it's so easy to columns (more than exactly 3) that one of them
is fixed width and the others are variable width, that's why we have
float:left, float:right and well, nevermind.

But I can have a left navigation bar that will stretch to the bottom, or have
a footer that will stay down when resizing, it's all easy and done without any
workarounds or tricks or endless trips to stackoverflow or using zurb
foundation / bootstrap.

So I'm surprised that a simple thing like putting something on top of the
other got to be so complicated, well, you can't have it all, nothing is
perfect

</rant>

~~~
moultano
Does anyone have any insight as to why it is this way? To me it seems insane,
but I don't trust my own judgement in domains like this because I've never
built anything comparable. Are there really good reasons for CSS to be the way
it is?

~~~
mcgwiz
Let's clarify the question.

"Does anyone have any insight as to why vertical centering of dynamic-height
content is the way it is?"

Yes. The original standards committee created a layout model (block, inline,
and inline-block elements) that (they felt) adequately balanced language
complexity with features. It's easy to idiomatically achieve vertical
centering. <http://jsfiddle.net/aMMxj/10/>

"Does anyone have any insight as to why people that code CSS complain about it
so much?"

This is a much deeper question, but one that I think is far more informative.
Having done front-end engineering for 10 years, across industries, and in very
pricey and exclusive consultancies, I have never found another engineer who
had read the bulk of the CSS spec, or even a book about it, for that matter.

Developers, the ones with the mind and experience to bring technical
discipline to CSS and create a set of idiomatic patterns (both low-level and
high-level), treat CSS as a second-rate citizen. The bulk of the rest of the
CSS userbase consists of visual design types (coming from print or graphic
design), where the tools of the trade are physical pen and paper, or something
from Adobe Creative Suite. The remaining portion of the userbase are equally
non-technical hobbyists.

This is the real problem of CSS. Those that have the mindset to devise
idiomatic conventions to the community don't think the language is worth it.
At best, you have semi-experienced developers duct-taping various non-
idiomatic ideas together and giving it a fancy name.

~~~
sandGorgon
genuine question as a non front end engineer- do you recommend reading the CSS
spec as a reference guide? im basically asking whether someone learning to be
good in CSS should read the spec or pick up one of the recommended books (that
appear from time to time on HN).

For example, i never had to read the spec for ruby to get jruby to work.

~~~
mcgwiz
There may or may not be Great CSS books out there, but in 10 years, I never
found any. They invariably teach you recipes, but not how to to think in the
terms the language was designed.

The ruby community is one of the most active and rigorously analyzed in
contemporary programming. Blog articles are well vetted, and Google search can
reliably point you to decent articles. Further, ruby belongs to a class of
languages (interpreted, general purpose, imperative/OO) that is very well
understood. Languages from this broader ecosystem include python, perl and
even JavaScript, all contributing to a deeper analysis of each.

CSS is a stylesheet system. There are no other popular systems in use. The
comparison _could_ be made to Microsoft Word's style system (which has a very
different conceptual model). Such a comparison could yield interesting ideas.
But such a comparison is never made. Other stylesheet languages for structured
documents include the unknown FOSI and DSSSL. When was the last time anyone
cited those referenced in a blog post, tutorial, or book about CSS?

I'm not saying the specs are a good teaching device either. But teaching and
precise description are different ends. Regardless, because there doesn't
exist a good community (incl blogs, books, personalities) to fall back on, the
specs are your best bet. Ultimately, they (along with other implementations)
are what inform browser implementations.

~~~
michielvoo
Would you consider writing a post that explains the high-level (conceptual)
differences between CSS, DSSL, FOSI and Word?

------
taylorfausak
The key takeaway:

    
    
      > New stacking contexts can be formed [… w]hen an element has an 
      > opacity value less than 1.
    

I had no idea that was the case. The CSS 2.1 spec [1] notes that "other
properties may introduce stacking contexts, for example 'opacity'". The CSS 3
spec [2] elaborates:

    
    
      > Since an element with opacity less than 1 is composited from a
      > single offscreen image, content outside of it cannot be layered
      > in z-order between pieces of content inside of it.
    

[1]: <http://www.w3.org/TR/CSS2/visuren.html#z-index> [2]:
[http://www.w3.org/TR/2010/PR-
css3-color-20101028/#transparen...](http://www.w3.org/TR/2010/PR-
css3-color-20101028/#transparency)

~~~
pattern
My main takeaway was the following:

    
    
        Z-index only works on positioned elements. If you
        try to set a z-index on an element with no position
        specified, it will do nothing.
    

I know I have scratched my head in the past trying to get z-index do what I
want, and this knowledge probably would have helped!

~~~
Hansi
Agree, I remember that it took me a while to figure this out when I first
tried playing with z-indexes.

------
crazygringo
Serious question: why do stacking contexts exist? They seem to defeat the
whole purpose of z-indexes, which is a global way of determining what shows up
in front of what else.

I'm trying to wrap my head around them -- I guess the main takeaway is, if you
don't ever want to have to deal with them, then don't ever use nested elements
where both have z-indexes?

~~~
caf
It seems to be to make pages more composable - so at the top level you can
specify what order block A and B are stacked, and _within_ A and B you can
independently specify what order the blocks that make those up are stacked.

This way you can change the relative order of A and B without worrying about
how those blocks are internally structured, and whether they use z-index
themselves.

~~~
cousin_it
That's an interesting rationale, but pages will never be composable as long as
CSS is _cascading_.

~~~
Someone
That is being worked on: <http://www.w3.org/TR/2012/WD-shadow-dom-20120522/>:

 _"7 Styles

To enforce upper-boundary encapsulation, CSS rules declared by the document
must not apply in a shadow DOM subtree, unless the apply-author-styles flag is
set for this subtree. The flag signals that document CSS rules are applicable
in the shadow DOM subtree.

Conversely, to enforce lower-boundary encapsulation, CSS rules declared in a
shadow DOM subtree must not apply in the document tree."_

------
baby
Long text for just a few explanation. As a developer I hate reading those kind
of tips since it doesn't go straight to the point. Here's my tl;dr :

> the stacking order is the same as the order of appearance in the HTML

Actually this is false, as last in code is displayed on top

> When you introduce the position property into the mix, any positioned
> elements (and their children) are displayed in front of any non-positioned
> elements

Use a "position:" and it will go on top of div not using it.

> z-index only works on positioned elements

use "position:" to use "z-index" otherwise it won't work.

> ...

I felt like the rest was unnecessary unless you plan to play a lot with
z-index. Then you can get a better tutorial/article/documentation on it.

~~~
thiagobrandam
> Actually this is false, as last in code is displayed on top

If it's a stack, then the last one _is_ displayed on top.

~~~
baby
That goes without saying.

------
archagon
I've always wanted to get into web design, but every time I read an article
like this, I get scared. Sometimes it seems like the web is nothing but hacks
piled on top of hacks...

------
flexxaeon
(I'm guessing that) since opacity is a "postprocessing operation"[1] it has to
'redraw' the entire div which causes it to fall back to it's parent order in
the stack.

But I'm not sure if this is a fair assessment, as you're applying opacity to
the div instead of the span.red, the element where the rule was applied. When
adding opacity to the span the z-index stays intact

[1] <http://www.w3.org/TR/css3-color/#transparency>

~~~
ricardobeat
That's the underlying reason - the same is true for position, if they didn't
create new contexts rendering would be an impossible mess.

Adding opacity to the span has no effect because it already has
position:absolute.

------
ricardobeat
TL;DR an opacity value < 1 creates a new stacking context.

------
garand
To solve the issue of z-index only working on positioned elements, what I do
on all new projects is set the following:

    
    
      * {
        position:relative;
      }
    

This does two things. Allows me to set z-index values without hassle, and also
allows me to set top/bottom left/right values.

Refer to my GitHub repo for the code for my base structure for new projects.

<https://github.com/garand/base>

~~~
ricardobeat
This does _three_ things: third is _severely slows down page rendering_.

~~~
harlanlewis
I can't find any information about `position:relative` impacting page render
performance. Please share.

Given my experience of low impact on render performance of vanilla properties
like this (transitions are a whole 'nother story), I'm much more concerned
with whether this is of benefit to developer happiness.

You'll never be able to use `position:absolute` for anything outside of the
context of an element's parent, and opting out of this back to default
behavior is much more painful than opting in with a better-scoped `.feature *
{position:relative}`.

Every new developer will need to wrap their head around nonstandard page flow,
and customizations like this have a way of accumulating into a very
intimidating environment. As a general rule, I don't want to inherit anything
silent and clever without very compelling reasons (* {box-sizing:border-box}
passes this test because it makes so many things so much easier).

~~~
garand

      You'll never be able to use `position:absolute` for anything outside of the context of an element's parent.
    

While true, I find that the instances that I need something to be absolutely
positioned outside of it's context are few and far between. Also, it is quite
easy to set position static on the parent elements.

    
    
      Every new developer will need to wrap their head around nonstandard page flow
    

I work with a team that is on board with this, so it hasn't been an issue yet.

Also, refer to this: [http://css-tricks.com/things-it-might-be-funuseful-to-
try-th...](http://css-tricks.com/things-it-might-be-funuseful-to-try-the-
universal-selector-on/)

------
RyanZAG
This seems more like a bug in opacity than anything. Logically, opacity should
have no impact at all on layout positioning, only on blending. So this is more
of a workaround created to speed up processing of elements with opacity less
than 1 that introduces a design bug in the spec.

~~~
mikegirouard
I'm no expert on the matter, as I just learned about this about 90 seconds
ago… but here's my guess:

My understanding of it is that if an element has < 1 opacity, something
different needs to occur to properly render that element. For an opacity of
.99, not much visually, but if the opacity is .5 how will it know what
elements to display under the partially opaque item?

I'd be curious to see some source code to know for sure, but that's my best
guess.

~~~
michielvoo
Here is the explanation:

[http://www.w3.org/TR/2010/PR-
css3-color-20101028/#transparen...](http://www.w3.org/TR/2010/PR-
css3-color-20101028/#transparency)

The CSS3 spec describes that the element with opacity < 1 should be composited
off screen. Therefor, an element with opacity < 1 must create a stacking
context, because its content layers cannot 'intertwine' with other layers not
inside the element.

Let's say you'd have a rule that pokes a hole in a layer. If that layer
contains several pieces of paper, then the spec would say to take the layer
with those pieces of paper aside, poke a hole though all of them, then place
the layer back where you found it. This way, other layers on the page are not
damaged. /end analogy.

------
Fletch137
If the model were to stay the same, I'd like to see something like stacking-
context:break to start a new stacking context with the targeted element as
parent, stacking-context:inherit for children. Same as we have now, but with
the option for manual control.

------
grecy
Also, don't expect Z-Index to work in IE6 with <select>. It's broken

~~~
rorrr
Anybody still supports IE6? I forgot it like a bad dream.

~~~
grecy
I'm sitting here on XP developing solely for IE6.

It _is_ a bad dream.

~~~
roel_v
Look at it from the bright side: at least you have a stable target ;)

------
rralian
This article should really be titled "What No One Told You About Opacity". I
think all the z-index stuff is pretty well-understood. At least by people who
consider themselves pretty good at css.

------
faramarz
But I got the same result by assigning z-index 2 and 3 to the other colors.

So the results is the same, but the method is incorrect? does it matter? hmm

<http://codepen.io/anon/pen/DlyAv>

~~~
aroman
I don't really want to add to the dogpile of comments explaining why you
missed the point, but the blog post pretty clearly states what the criteria
for the "challenge" were:

"Here's the challenge: try to see if you can make the red <span> element stack
behind the blue and green <span> elements without breaking any of the
following rules:

Do not alter the HTML markup in any way. Do not add/change the z-index
property of any element. Do not add/change the position property of any
element."

~~~
recursive
He didn't change the markup. He changed the CSS. He didn't add a property to
an element. He added a property to a rule.

~~~
mistercow
He didn't add a property to a rule. He entered text in the CSS editor.

He didn't enter text in the CSS editor. He pressed some buttons on a keyboard.

We could keep at this for a while, if you want.

