I was trying to reproduce this tutorial for a responsive menu. It all worked well, but I tried to keep the menu fixed on the top of the page for one of my projects. Unfortunately the hidden menu when fixed, do not change the z-index after the hover.
#icon_cont ul{
background-color: #cccccc;
margin-top: 75px;
z-index:-2; /**THIS DOES NOT APPLY**/
position: absolute;
top:100%;
padding: 0;
right: 0;
}
I tried in every way but it didn't work at all.
You can see in this example that when the container has relative position, it works, but when it's with the fixed position, the menu does not stay behind the other elements.
Appreciate, any help!
The reason is because you're applying postion: fixed; to the element. Fixing a position pushes to the front of the z-index stack. Here are the basic rules for understanding how the stacking order works:
The stacking context’s root element
Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
Non-positioned elements (ordered by appearance in the HTML)
Positioned elements (and their children) with a z-index value of auto (ordered by appearance in the HTML)
Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
(Taken from Philip Walton's invaluable post, "What No One Told You About Z-Index")
When you apply position: fixed; to an element, it sits in front of all relatively position items. Z-index values are relative to their "stack", not globally.
Every stacking context has a single HTML element as its root element. When a new stacking context is formed on an element, that stacking context confines all of its child elements to a particular place in the stacking order. That means that if an element is contained in a stacking context at the bottom of the stacking order, there is no way to get it to appear in front of another element in a different stacking context that is higher in the stacking order, even with a z-index of a billion!
New stacking contexts can be formed on an element in one of three ways:
When an element is the root element of a document (the <html> element)
When an element has a position value other than static and a z-index value other than auto
When an element has an opacity value less than 1
(Emphasis mine)
Related
I am a little confused about using z-index to decide stack order.
I do not quite understand how browsers treat elements with the position property in conjunction to those without it.
Is there a general rule to decide the stack order of elements whether it has explicitly positioned elements or not?
Examples of different situations are appreciated. Generally speaking:
mixed sibling <div>s with position set and without position set.
nested <div>s mixed with sibling <div>s with position set and without position set.
Basics of the CSS z-index property
A Simple Concept
The z-index property is based on a simple concept: Elements with higher values will sit in front of elements with lower values along the z-axis. So if you apply z-index: 1 to div.box1, and div.box2 has a z-index: 0, then div.box1 will overlay div.box2.
In terms of the z-axis, it refers to depth on a three-dimensional plane. On your computer it can be interpreted as the plane on which objects move closer and farther from you. (Learn more about the Cartesian coordinate system.)
Source: Wikipedia
z-index works on positioned elements
Unless you're dealing with flex items or grid items, the z-index property works only on positioned elements. This means you can use z-index on elements with position: absolute, position: relative, position: fixed or position: sticky. If the element has position: static (the default value), or some other positioning scheme like a float, then z-index will have no effect.
As noted, although z-index, as defined in CSS 2.1, applies only to positioned elements, flex items and grid items can create a stacking context even when position is static.
4.3. Flex Item Z-Ordering
Flex items paint exactly the same as inline blocks, except that order-modified document order is used in place of raw
document order, and z-index values other than auto create a stacking context even if position is static.
5.4. Z-axis Ordering: the z-index property
The painting order of grid items is exactly the same as inline blocks, except that order-modified document order is
used in place of raw document order, and z-index values other than auto create a stacking context even if
position is static.
Here's a demonstration of z-index working on non-positioned flex items: https://jsfiddle.net/m0wddwxs/
Stacking Contexts
Once an element is positioned and a z-index is applied, a stacking context is created.
(Also see: Full list of circumstances where a stacking context is created.)
The stacking context is a set of rules for managing the positioned element with z-index, and its descendants. These rules govern the placement of child elements in the stacking order and the scope of the property's influence.
Essentially, the stacking context limits the z-index scope to the element itself, and its child elements cannot affect the stacking order of elements in another stacking context.
If you've ever tried to apply increasingly higher z-index values only to find that the element never moves out in front, you could be trying to overlay an element in a different stacking context.
Groups of elements with a common parent that move forward or backward
together in the stacking order make up what is known as a stacking
context. A full understanding of stacking contexts is key to really
grasping how z-index and the stacking order work.
Every stacking context has a single HTML element as its root element.
When a new stacking context is formed on an element, that stacking
context confines all of its child elements to a particular place in
the stacking order. That means that if an element is contained in a
stacking context at the bottom of the stacking order, there is no way
to get it to appear in front of another element in a different
stacking context that is higher in the stacking order, even with a
z-index of a billion!
~ What No One Told You About Z-Index
Stacking Order
CSS adheres to a stacking order when laying out elements on a page. These are the stacking rules when there is no z-index specified, from farthest to closest:
Backgrounds and borders of the root element
Non-positioned, non-floating block elements, in the order they appear in the source code
Non-positioned floating elements, in the order they appear in the source code
Inline elements
Positioned elements, in the order they appear in the source code
If a z-index property is applied, the stacking order is modified:
Backgrounds and borders of the root element
Positioned elements with a z-index of less than 0
Non-positioned, non-floating block elements, in the order they appear in the source code
Non-positioned floating elements, in the order they appear in the source code
Inline elements
Positioned elements, in the order they appear in the source code
Positioned elements with z-index of greater than 0
Source: W3C
Bottom line: Once you understand stacking contexts, z-index is easy.
For examples of z-index in action see: How z-index works!
For a brief but highly informative article explaining z-index (including how opacity affects the stacking order) see: What No One Told You About Z-Index
For a complete rundown on z-index, with many examples and illustrations, see: MDN Understanding CSS z-index
And for a deep dive into stacking contexts read: W3C Elaborate description of Stacking Contexts
i have made a scrolling manu and when I try to select it the list of the menu goes behind of an object (a simple music player). How can i put that object in lower level? I know I should use z-index command but i don't know the value. I tried them all.
z-index:0;
z-index:1;
z-index:auto;
Whatelse can I use?
It's worth noting that z-index is only obeyed on positioned elements (absolute, relative, or fixed). If you put a z-index on a non-positioned (static) element, it will be ignored.
The value of z-index is any integer or auto;
z-index only works on explicitly positioned elements with a position of absolute, relative or fixed.
additionally, their 'stacking context' is relative to their position in the DOM. two sibling elements are in the same stacking context, but their children elements are in a new stacking context (so if you have two sibling parents with z-index: 1, and one of them has an immediate child with z-index: 1 and the other has an immediate child with z-index: 2, the latter will have the higher z-index because its stacking context is 1-2 versus 1-1. However if for example you have two parent sibling elements where one has a higher z-index than the other, no descendant of the parent with the lower z-index will ever have a higher z-index than children of the parent with the higher z-index, even if you set the former's children to z-index: 500 or something like that. Basically stacking contexts exist at each level of the DOM and their effects cascade to all of the lower stacking contexts generated by their descendants.
z-index is tricky to master and requires a lot of attention to the markup and DOM structure. you need to post all of the relevant CSS and HTML in order for us to help you.
You can read some more about z-index on Mozilla Developer Network
Say that I have a fixed position header (position: fixed) at the top-right corner with a sloped <h1> element (tranform: rotate(33.3deg)). How can I have the main content scroll under the <h1> element but over the parent <header> element?
I've tried using the straight-forward z-index rule, it works in firefox, but not chrome.
So in short:
header {
position: fixed;
top: 0;
right: 0;
z-index: 0;
}
header h1 {
transform: rotate(33.3deg);
z-index: 9;
}
This works in Firefox but in Chrome the child <h1> goes under the content along with the parent <header>
It is important to sandwich the header around the content in this matter because the transform: rotate() rule will create a HUGE box around the transformed child to fit it all inside, rendering hyperlinks unclickable for example.
I can't reproduce the behavior you described. When I pasted your code into JSbin (and added some text and background for visual aids, see demo 1), the header with the h1 as a whole is displayed above the content in both Chrome (27 and 30 beta) and Firefox (22). With z-index: -1 for header (see demo 2), they both go below the content (but above the body background). It is the expected behavior according to the CSS 2.1 spec:
Each box belongs to one stacking context. Each positioned box in a
given stacking context has an integer stack level, which is its
position on the z-axis relative other stack levels within the same
stacking context. Boxes with greater stack levels are always formatted
in front of boxes with lower stack levels. Boxes may have negative
stack levels. Boxes with the same stack level in a stacking context
are stacked back-to-front according to document tree order.
The root element forms the root stacking context. Other stacking
contexts are generated by any positioned element ... having a computed value of 'z-index' other than
'auto'. ... In future levels of CSS, other properties may introduce
stacking contexts (transform property does this — Ilya).
Within each stacking context, the following layers are painted in
back-to-front order:
the background and borders of the element forming the stacking
context.
the child stacking contexts with negative stack levels (most
negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including
inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned
descendants with stack level 0.
the child stacking contexts with positive stack levels (least
positive first).
So the only solution I can see is to make the 'sandvich' from the sibling elements (or element and pseudo-element), not from the position parent and its child (see demo 3).
I have an<article> element inside a <div> and article has a position: relative;.
I moved it up 95px (bottom: 95px;) but the space it took up in its original place remained there. How can I make that disappear? When I do the same with article positioned as absolute, there is no problem. But I need to stick this to the middle too and margin: auto won't work with position:absolute.
http://jsfiddle.net/xnvMD/2/
I have an<article> element inside a <div> and article has a position: relative;.
I moved it up 95px (bottom: 95px;) but the space it took up in its original place remained there.
Well, this is how relative positioning is supposed to work – http://www.w3.org/TR/CSS21/visuren.html#choose-position:
“When a box B is relatively positioned, the position of the following box is calculated as though B were not offset.”
So the original space required by a relatively positioned element gets reserverd.
How can I make that disappear? When I do the same with article positioned as absolute, there is no problem. But I need to stick this to the middle too and margin: auto won't work with position:absolute.
Have you tried just using a negative margin-top to “move” the element upwards? This should work in all browsers (that are not from the stone age). And you can still set the horizontal margins to auto to have your element centered.
.trdown {
/* everything else besides position and bottom stays */
margin:-85px auto 0 auto;
}
(If this destroys the spacing at the bottom of the container element that you want to keep, then give that a padding-bottom as well.)
Instead of the relative position, use a negative top margin. Something like this:
margin:-95px auto 0 auto;
As CBroe has already pointed out, to get the arrow to show up over the image above, you'll need to add back the position:relative (but not the bottom) when you set the z-index.
position:relative;
z-index:1;
Technically you don't even need the z-index.
If you're curious why this works the way it does, you need to understand the rules for painting order in CSS. The full details are fairly complicated, but the basics are outlined in the section on the z-index property.
Within each stacking context, the following layers are painted in back-to-front order:
the background and borders of the element forming the stacking context.
the child stacking contexts with negative stack levels (most negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
the child stacking contexts with positive stack levels (least positive first).
By default, images (which classify as inline-level, non-positioned descendants) are at level 5, which is above your article element (a non-inline-level descendant) at level 3.
By adding a postion:relative to the article element, you've made it a positioned descendant, level 6, and thus moved it higher up the stack and above the image again.
Note that if your article had contained any inline content of its own, that would have displayed above the img element (they're both inline, but the article's inline content comes later in the tree order), but the article background and borders would still have painted below.
I dont have enough reputation to add a comment without first adding an answer. Without seeing code like Cody added it's difficult to help.
I think you're not entirely sure how positioning works. When an element is set to position: absolute, it's then positioned in relation to the first parent element it has that doesn't have position: static. If there's no such element, the element with position: absolute gets positioned relative to <html> (from Codecademy)
If you give an element relative positioning and tell it to have a margin-top of 10px, it doesn't move down ten pixels from any particular thing—it moves down ten pixels from where it otherwise would have been.
Remember, that if your using margin-auto on an element inside of another element, it will center inside of that element, as opposed to the document. Div's by default are the entire width of the page though.
I have a webpage that I need to modify, the background, which is currently absolute positioned with z-index to push it back, needs to stay put when scrolling, i need to change it to fixed, yet doing so seems to break z-index and push the content below it vertically. Any ideas?
edit:
OK I managed to get it to work in FF, but IE is still broken...
Maybe look at the rules below for how elements are stacked.
The Stacking order and stacking context rules below are from this link
Stacking Order within a Stacking Context
The order of elements:
The stacking context’s root element (the <html> element is the only stacking context by default, but any element can be a root element for a stacking context, see rules below)
You cannot put a child element behind a root stacking context element
Positioned elements (and their children) with negative z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
Non-positioned elements (ordered by appearance in the HTML)
Positioned elements (and their children) with a z-index value of auto (ordered by appearance in the HTML)
Positioned elements (and their children) with positive z-index values (higher values are stacked in front of lower values; elements with the same value are stacked according to appearance in the HTML)
When a Stacking Context is Formed
When an element is the root element of a document (the <html> element)
When an element has a position value other than static and a z-index value other than auto
When an element has an opacity value less than 1
Several newer CSS properties also create stacking contexts. These include: transforms, filters, css-regions, paged media, and possibly others. See https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
As a general rule, it seems that if a CSS property requires rendering in an offscreen context, it must create a new stacking context.
Made a quick test. In its simplest form z-index doesn't break when using position: fixed;.
Perhaps you can put the background that is already there in a wrapper for the whole page and use the gradient background on the body instead.
Depending on the gradient, you can also try using a css3 gradient on the background of the body (or simply multiple backgrounds...) and use css3pie to make it work in IE.