I've been trying to use the z-index css attribute to make one element always be in front of another, but it isn't working. The z-index of one element is clearly greater than that of the other, but it is still positioned behind the other element. Could it be because one of the elements (the one showing up in front) is an iframe? Does anyone have any other advice?
For those that arrive here later, the correct answer is to put position: relative; or any of the other position props on the problematic elements.
My recommendation would be to put this on every element involved with the problem:
position: relative;
z-index: 0;
and then increase the z-index on the back-most element(s) that are in front of the iframe.
If you do that, you will start winning pretty quick.
In my testing here, z-index only works if you have position explicitly set. Test it by modulating your z-index values and then trying to highlight the text on the screen via mouse-clicking. You should see evidence of layers acting either as desired or horribly incorrect.
I find it works great if you press F12 (to open dev pane, in Chrome) and then click the Inspect Button at the top-left or press CTRL + SHIFT + C. Then you can mouseover everything and see what their stacking context is relative to adjacent elements.
UX BONUS TIP: Remember, users may want to copy text, so make sure they can select it.
If you are having problems, most likely you are either:
missing position: relative; on an element's parent, or
missing z-index: 0; somewhere
Remember that the z-index index only counts on absolute elements. Both elements should has the position:absolute. More info in the CSS 2.1 Specification
Related
I have an absolutely positioned flyout table, that is hidden (display:none;) by default,
and appears (display:block;) on hovering over its heading.
It appears above everything else on the page, which is what I want.
The exception are elements with an opacity value below 1.
They appear above the hover table.
Why is that, and how could I avoid it?
JSFiddle
This is working "as it should", but to get your desired result, use z-index: 1 on your position: absolute element.
I did some more digging into this because I was curious as to why it was happening. There are two important things:
elements with position: absolute and a z-index: auto stay in the same stacking context.
an element with an opacity less than 1 creates a new stacking context.
I found this answer helpful as it goes into more depth about why this happens.
You can easily avoid it by adding z-index: 1; to table.hidden
Code pen showcasing problem.
https://s.codepen.io/NoMan2000/debug/rdPEYJ/xnrabdnqJadA
I apologize for the rather gnarly HTML, but this is output from a next.js project so the bloated mess is part and parcel of that.
Anyway, the problem can be seen in the element #header-menu-buttonList. The idea is pretty simple, a menu that goes underneath the main grid element. But for whatever reason, it just sits there on the page.
You can pick it up in the debug tools and see that it has a width and a height. Messing with its z-index doesn't make the object visible, only removing the position: absolute makes it visible on the page, but that opens up a whole host of other issues.
So, anyone know:
1.) Why the heck it's doing that?
2.) How to either fix it or work around it?
Thanks for the rubber-ducking. :)
So the issue is that the parent element is positioned absolutely, and the child element is positioned absolutely. I'm not up to snuff on all my CSS rules, but this appears to keep it in the DOM but not render it visible.
The solution is to set the child #header-menu-buttonList to position: static and the parent #header-menu-button to position:absolute.
I'm having trouble with the order of layered DIV elements. I have a DIV .lens-flare that's at the bottom of the hierarchy in HTML. Yet when I transform: translate the position so it encompasses the entire parent DIV, it shows above elements that are above it in the hierarchy.
So I tried setting z-indexes, and then turned my translate into translate3d. Still I'm not able to get .lens-flare underneath .top-nav-bar, .nav-bar, or .cta.
Currently I have a pointer-events: none applied so I can at least click on the things underneath. But how can i actually move the .lens-flare layer under everything else successfully?
Here's my CodePen for the project
Elements rendered later are considered being closer to the screen than the elements rendered before them.
Z-index is the answer if you want to change this, you just need to remember z-index works only with elements that are positioned.
.lens-flare
position: relative
z-index: 1
.nav-bar, .top-nav-bar, .cta
position: relative
z-index: 2
Your corrected codepen: http://codepen.io/sEvher/pen/doyWoW
So I know there are a plethora of questions about position fixed/relative/absolute in relation with z-index, but I still couldn't figure out my question using those.
Essentially I have a header that is fixed. It works perfectly fine, everything goes behind it when scrolling down the page.
I recently wanted to add links to div ids, but in order to account for the header, I had to add the following code where link is the parent element, and then linkTo is the class of something with an ID that we actually link to. This functionality works completely, providing the correct offset so that the header is above the div we want.
.link {position: relative;}
.linkTo {position: absolute; top: -80px;}
The problem with this, is that for some reason now my div is behind everything on the page. I can still see it but the text and images are in front.
I've tried adding z-index to my header (of like 9999) but it isn't working. I don't understand why adding position relative would mess up the order of how things are displayed.
I'd like to provide an example, but my code is rather large. If this isn't enough I can try to make a jfiddle later.
Add position: relative; z-index:9999 to the parent element it will keep this element stick inside the menu.
As Ganesh said, adding position: relative to the parent element of the header was the starting step. After that adding z-index to the same parent element fixed the problem completely.
Check for a lower z-index on a parent element, it appears to override the z-index of children.
I've run into z-index issues in the past with drop down menus and jquery UI tabs. I thought it had something to do with the stacking effects created us rules like opacity or transition, but for me the problem was a parent element having a lower z-index than a child element.
I'm running into some extremely strange behaviors, and non-consistant across every browser i've tested.
I've a pretty complex layout, but the main issue lies here:
<div id="drop">
<div id="header"></div>
</div>
#drop has position:absolute and z-index:100
#header has position:fixed; top:60px;
As I start scrolling down Chrome ignores the position:fixed rule. If I remove either of the two styles above from #drop then Chrome starts respecting the position:fixed rule.
can't get it working on Ubuntu Chrome 23.0.1271.97 and see the same behavior on Mac Chrome 25.0.1364.99. My friend uses Ubuntu Chrome 25.0.1364.68 beta and it works correctly for him. I've tested it on firefox and it kinda works (with other symptoms)
Has anyone heard of this error? or can anyone even reproduce it?
edit
I'm using openlayers map as another div with position:fixed if I delete that layer or at least change it to display:none then this weird bug goes away.
edit
Noticed that during the presence of this bug, if I change the zoom level back and forth, then the position adjusts itself to the proper behavior. To me, this indicates a webkit issue that fails to execute some internal callback function on scroll.
Another extremely strange thing is that I have a few links inside of #header and they work if I just click the expected location, even though the the div does not appear there. Overall I've noticed that it's only the rendering that's broken. If at any point of time I force the browser to re-render by resizing the window, or changing zoom, or just doing Select-All, then the header bar jumps to the proper position, but does not remain fixed.
You mentioned in the comments that OpenLayers uses CSS transforms. That being the case:
the element with fixed positioning will become relative to the element with the transform - not relative to the viewport
Take a look at the spec: The Transform Rendering Model
Specifying a value other than ‘none’ for the ‘transform’ property
establishes a new local coordinate system at the element that it is
applied to.
.wpr
{
width: 200px;
height:1000px;
background: pink;
position:relative;
margin: 0 200px;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.fixed
{
width: 200px;
height:200px;
margin: 50px;
position: fixed;
top:0;
left:0;
background: aqua;
}
<div class="wpr">
<div class="fixed"></div>
</div>
As the accepted answer says, this is the intended behavior, and is spec-compliant. Another important component of this is what it means to be using CSS transforms.
In your case, it was due to OpenLayers, but this applies to anyone using will-change: transform as well (probably a lot of the people visiting this question). This has been brought up on the Chromium bug tracker here, and marked as WontFix, because (as I said) it's intended behavior. The official comment is this:
This behavior is required by the spec
(http://dev.w3.org/csswg/css-will-change/): "If any non-initial value
of a property would cause the element to generate a containing block
for fixed-position elements, specifying that property in will-change
must cause the element to generate a containing block for
fixed-position elements."
The idea is that once will-change:transform is specified, you should
be able to add/remove/change transforms cheaply, without needing
fixed-position descendants to get re-layed-out.
Note that using other values of will-change (e.g. opacity, top) will
not change the positioning of fixed-position descendants.
As far as I am aware, the only solution is to make the child of the will-change element a sibling instead, to prevent the attribute from cascading.
As a side note, in my specific case, I was able to fix it by being more specific with the will-change attribute. Instead of using it on the div containing the performance-jarring element that required GPU offloading, I used it directly on the offending element. This was due to my original bad code, though, so it won't work for most cases.
You will have to place header outside the parent container drop to make it work.
I had slightly similar issues days back.For instance,if you set z-index of header,it will be attain the z-index of the parent dropcontainer.The z-index of header will be useless because it is already inside a container which has another z-index.
The same logic of z-index applies to position.
I want to add another possible solution because I was struggling with chrome ignoring position:fixed for quite some time until I finally found the culprit:
-webkit-perspective: 1000;
It was coming from a plugin I was using and causes ALL position:fixed elements to be ignored.
Hope it helps someone.
I think this is impossible, i don't think if two positions can be placed at the same place without one to collapse. But i think its better to use Avail height in javascript, i mean if you wanna an outer div to hold inner div, and outer div must cover the whole screen, use Availheight in js, this will get the screen height and then apply if, thereafter set all the divs in fixed position.
Add this to parent:
position: fixed;
...and this to the child:
position: sticky;
First of all, put something in your div as empty ones behave really weird. Then, what do you expect by putting a fixed into an absolute? Obviously, nobody knows what is the reference point of your fixed div. Should it be its parents position? which is not changing with scroll or the page position which changes? Try to use things that are completely meaningful and have a clear definition because if you fix it in chrome, what would happen with another browser? Do you really prefer to test is on all of them?
I suppose a small change in your divs so that pull the fixed div out of the absolute one or move the absolute div somewhere else.