I write css coded is the following lines. but not working z-index.
I want to know how I can make the z-index work while keeping the value of position as relative.
#foo {
position: relative;
z-index: -1;
width: 100%;
height: 30%;
background-color: lightblue;
}
#bar {
width: 50%;
height: 30%;
background-color: lightpink;
}
As far as I know, if you set the value of position to a non-static value, the z-index should work. Are there any other factors that affect the z-index?
Also if I change the value of position to absolute it works fine.
When position is relative
When position is absolute
everything is working as you need you can see I have added margin-bottom:-20px; to .foo so that you can se that in effect that .foo is behind .bar.
Understand that position won't take item out of flow, which will keep it at it's position. To see this in effect there must be some overlapping between two elements, than you can see the z-index in efffect.
html,
body {
width: 100%;
height: 100%;
}
#foo {
position: relative;
z-index: -1;
width: 100%;
height: 30%;
background-color: lightblue;
margin-bottom: -20px;
}
#bar {
width: 50%;
height: 30%;
background-color: lightpink;
}
<div id="foo">Foo</div>
<div id="bar">Bar</div>
Given the following HTML:
#header {
position: fixed;
z-index: 1;
background-color: red;
width: 100%;
height: 150px;
top: 0;
}
#drop {
position: absolute;
top: 5px;
width: 100px;
background-color: green;
height: 400px;
z-index: 3;
}
#footer {
position: fixed;
z-index: 2;
background-color: blue;
width: 100%;
height: 150px;
bottom: 0;
}
<div id="header">
<div id="drop">
</div>
</div>
<div id="footer">
</div>
How do I amend the CSS only, so #drop is considered in front of both #header and #footer. While maintaining that #footer is in front of #header?
According to the current standard, this is as easy as removing the z-index from #header. With the default z-index of auto, the header does not establish a new stacking context, and thus the dropdown and the footer belong to the same stacking context, and #drop's z-index of 3 pushes it above the footer. You can even remove the z-index from the footer as well; because it comes after the header in document order, it will still be on top.
Try it out:
#header {
position: fixed;
background-color: red;
width: 100%;
height: 150px;
top: 0;
}
#drop {
position: absolute;
top: 5px;
width: 100px;
background-color: green;
height: 400px;
z-index: 3;
}
#footer {
position: fixed;
background-color: blue;
width: 100%;
height: 150px;
bottom: 0;
}
<div id="header">
<div id="drop">
</div>
</div>
<div id="footer">
</div>
Works great. In Firefox.
But since you're probably using Chrome, not so much. Chrome has decided to ignore the standard for mobile performance reasons; in Chrome, a position: fixed element always establishes a new stacking context, regardless of its z-index value. As BoltClock points out, this change may sooner or later appear in other browsers as well.
And thus in Chrome, since the dropdown is a descendant of the header, its stacking context is the one established by the header, and that stacking context is below the footer, per your requirement. So in a cross-browser future-proof way and within your constraints, this is utterly impossible.
If you want to do this without your JavaScript workaround, I see two options:
Move the dropdown out of the header
That works easily enough in your example
#header {
position: fixed;
z-index: 1;
background-color: red;
width: 100%;
height: 150px;
top: 0;
}
#drop {
position: fixed;
top: 5px;
width: 100px;
background-color: green;
height: 400px;
z-index: 3;
}
#footer {
position: fixed;
z-index: 2;
background-color: blue;
width: 100%;
height: 150px;
bottom: 0;
}
<div id="header">
</div>
<div id="drop">
</div>
<div id="footer">
</div>
but is more elaborate in your actual case on Discourse, where the dropdown then can no longer be top: 100%; for nice positioning. You'd actually have to measure the correct y-coordinate when creating the dropdown, so this isn't a JS-free solution either.
Keep the dropdown in the header, but make the header not create a new stacking context
However, as explained above, this means that the header cannot be position: fixed anymore. And since your header must of course be fixed in the viewport (and we don't want to ensure this via JS), the header then has to have an ancestor that's position: fixed instead.
Just wrapping the header in another fixed-position div doesn't do you any good, since it creates the exact same problem; the footer is still in a different stacking context. So this wrapper div needs to include both the header and the footer. If that's not doable in Discourse's architecture, you can stop reading here.
By making your wrapper position: fixed, but making your header position: absolute and z-index: auto, you prevent a new stacking context from being created by the header.
The wrapper needs a width of 100%, so the header's and footer's width: 100% work. The wrapper will have a height of 0, which is both necessary (because it sits above your main content and thus must not obscure it) and not problematic (since the footer is still position: fixed at the bottom, and the wrapper itself has visible overflow).
In your example, it looks like this:
#fixed-wrapper {
position: fixed;
width: 100%;
}
#header {
position: absolute;
background-color: red;
width: 100%;
height: 150px;
top: 0;
}
#drop {
position: absolute;
top: 5px;
width: 100px;
background-color: green;
height: 400px;
z-index: 3;
}
#footer {
position: fixed;
background-color: blue;
width: 100%;
height: 150px;
bottom: 0;
}
<div id="fixed-wrapper">
<div id="header">
<div id="drop">
</div>
</div>
<div id="footer">
</div>
<div id="fixed-wrapper">
As for actually testing it on Discourse, I used http://discourse.opentechschool.org/ because it hasn't been updated yet to include your JavaScript workaround (and I happen to have an account there).
I clicked "reply" on a post, resized the composer so that it overlaps with the header, and clicked the (now only partially visible) "search" icon. As expected I couldn't see the search popup.
Then I put this into the JavaScript console:
$("<div id='fixed-wrapper' />").prependTo("#main")
.css({position:"fixed", width:"100%", zIndex: 1000}) // z-index 1000 is what the
// header used to have
.append( // move the header and footer
$("header.d-header, #reply-control") // to the wrapper and remove
.css({zIndex:"auto"}) // their z-indexes
);
$("header.d-header").css("position", "absolute") // stop the header from
// creating a stacking
// context
Now the search box is above the composer, which itself is still above the header, as desired.
If you can live with header being static, then I think this is what you are looking for.
#header {
position: static;
z-index: 1;
background-color: red;
width: 100%;
height: 150px;
top: 0;
}
#drop {
position: absolute;
top: 5px;
width: 100px;
background-color: green;
height: 400px;
z-index: 3;
}
#footer {
position: fixed;
z-index: 2;
background-color: blue;
width: 100%;
height: 150px;
bottom: 0;
}
<div id="header">
<div id="drop">
</div>
</div>
<div id="footer">
</div>
Here's a simple example:
<div class = "has-scrollbar">
<div class = "long"></div>
<div class = "overlay"></div>
</div>
.has-scrollbar {
width: 200px;
height: 100px;
overflow-y: scroll;
position: relative;
}
.long {
height: 200px;
width: 50px;
background: blue;
}
.overlay {
width: 100%;
height: 100%;
background: red;
opacity: 0.5;
position: absolute;
top: 0;
}
JsFiddle
The red overlay should completely fill the parent container. The height of .long is not known in advance. The .has-scrollbar div should still be scrollable (and not covered).
Any solution using position: fixed on .overlay will not likely work. The real-world scenario is far more complex. Consider the position of .has-scrollbar within the body to also not be known in advance.
So you don't know about long, but seems like you do control has-scrollbar, so you can make overlay fixed and position it in the same place as has-scrollbar:
.overlay {
height: 100px;
margin-top: 8px; /* just to compensate for body margin in the example */
pointer-events: none; /* mouse events will pass through */
position: fixed;
width: 200px;
}
Updated JSFiddle.
I'm trying to make a background image be outside a div and can't figure out how to do this (if even it's possible). My HTML:
<div id="test"></div>
My CSS:
#test {
width: 50px;
height:50px;
background: 0 50px url('https://developers.google.com/_static/images/developers-logo.svg') blue;
}
A stand-alone demo:
http://jsfiddle.net/568Zy/
The demo shows the image within the 50x50 div. What I was hoping for was to have the background image start at 0px from the top and 50px from the left.
Any ideas?
Your question does not make it clear exactly what you want the end result to look like.
It is not possible to make a background image 'overflow' it's element, however you can apply the background image to a pseudo element and make that whatever size you want and position it wherever you want.
I have used this technique on your example: http://jsfiddle.net/ybw750jd/
#test {
background: blue;
height:50px;
position: relative;
width: 50px;
}
#test:before {
background: url("https://picsum.photos/450/100") repeat scroll 0 0 transparent;
content: " ";
display: block;
height: 100px;
position: absolute;
width: 450px;
z-index: -1;
}
If this is not the effect you want, please rephrase your question and consider making a mock up image showing what you want it to look like.
Try this: http://jsfiddle.net/568Zy/16/. Essentially, you're creating two <div> elements, and set one to be absolute with a z-index: 0; on one and z-index: 1; on the other.
<div id="test">zzz</div>
<div class="z-index"></div>
#test {
background: blue;
width: 50px;
height:50px;
position: relative;
z-index: 1;
}
.z-index {
position: absolute;
background: url('https://developers.google.com/_static/images/developers-logo.svg');
z-index: 0;
width: 300px;
height: 100px;
top: 0px;
left: 50px;
}
I have the following html...
<div class="header"></div>
<div class="main"></div>
<div class="footer"></div>
And following css...
.header{
position: fixed;
background-color: #f00;
height: 100px;
}
.main{
background-color: #ff0;
height: 700px;
}
.footer{
position: fixed;
bottom: 0;
background-color: #f0f;
height: 120px;}
But why the header and footer is not fixed, anything I did wrong? I want only "main" to be scrollable and "header" and "footer" to be at a fixed position. How to do?
+-------------------------------------+
| header | -> at fixed position (top of window)
+-------------------------------------+
| main |
| |
| | -> scrollable as its contents
| | scroll bar is window scroll bar not of main
| |
| |
+-------------------------------------+
| footer | -> at fixed position (bottom of window)
+-------------------------------------+
See this fiddle
My issue was that a parent element had transform: scale(1); this apparently makes it impossible for any element to be fixed inside it. By removing that everything works normally...
It seems to be like this in all browsers I tested (Chrome, Safari) so don't know if it comes from some strange web standard.
(It's a popup that goes from scale(0) to scale(1))
if a parent container contains transform this could happen. try commenting them
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
you need to give width explicitly to header and footer
width: 100%;
Working fiddle
If you want the middle section not to be hidden then give position: absolute;width: 100%; and set top and bottom properties (related to header and footer heights) to it and give parent element position: relative. (ofcourse, remove height: 700px;.) and to make it scrollable, give overflow: auto.
Double-check that you haven't enabled backface-visibility on any of the containing elements, as that will wreck position: fixed. For me, I was using a CSS3 animation library...
Working jsFiddle Demo
When you are working with fixed or absolute values,
it's good idea to set top or bottom and left or right (or combination of them) properties.
Also don't set the height of main element (let browser set the height of it with setting top and bottom properties).
.header{
position: fixed;
background-color: #f00;
height: 100px;
top: 0;
left: 0;
right: 0;
}
.main{
background-color: #ff0;
position: fixed;
bottom: 120px;
left: 0;
right: 0;
top: 100px;
overflow: auto;
}
.footer{
position: fixed;
bottom: 0;
background-color: #f0f;
height: 120px;
bottom: 0;
left: 0;
right: 0;
}
I had a similar problem caused by the addition of a CSS value for perspective in the body CSS
body { perspective: 1200px; }
Killed
#mainNav { position: fixed; }
As others pointed out, certain CSS properties on a parent element will prevent position: fixed from working. In my case it was backdrop-filter.
This might be an old topic but in my case it was the layout value of css contain property of the parent element that was causing the issue. I am using a framework for hybrid mobile that use this contain property in most of their component.
For example:
.parentEl {
contain: size style layout;
}
.parentEl .childEl {
position: fixed;
top: 0;
left: 0;
}
Just remove the layout value of contain property and the fixed content should work!
.parentEl {
contain: size style;
}
Another cause could be a parent container that contains the CSS animation property. That's what it was for me.
For anyone having this issue primarily with navbars, not sticking to the top, I found that if any element in the parent container of the positon: fixed; element has a width exceeding 100% - so creating horizontal scrollbars - is the issue.
To solve it set the 'parent element' to have overflow-x: hidden;
You forgot to add the width of the two divs.
.header {
position: fixed;
top:0;
background-color: #f00;
height: 100px; width: 100%;
}
.footer {
position: fixed;
bottom: 0;
background-color: #f0f;
height: 120px; width:100%;
}
demo
You didn't add any width or content to the elements. Also you should set padding top and bottom to your main element so the content is not hidden behind the header/footer. You can remove the height as well and let the browser decide based on the content.
http://jsfiddle.net/BrmGr/12/
.header{
position: fixed;
background-color: #f00;
height: 100px;
width:100%;
}
.main{
background-color: #ff0;
padding-top: 100px;
padding-bottom: 120px;
}
.footer{
position: fixed;
bottom: 0;
background-color: #f0f;
height: 120px;
width:100%;}
You have no width set and there is not content in the divs is one issue. The other is that the way html works... when all three of fixed, is that the hierarchy goes from bottom to top... so the content is on top of the header since they are both fixed... so in this case you need to declare a z-index on the header... but I wouldn't do that... leave that one relative so it can scroll normally.
Go mobile first on this... FIDDLE HERE
HTML
<header class="global-header">HEADER</header>
<section class="main-content">CONTENT</section>
<footer class="global-footer">FOOTER</footer>
CSS
html, body {
padding: 0; margin: 0;
height: 100%;
}
.global-header {
width: 100%;
float: left;
min-height: 5em;
background-color: red;
}
.main-content {
width: 100%;
float: left;
height: 50em;
background-color: yellow;
}
.global-footer {
width: 100%;
float: left;
min-height: 5em;
background-color: lightblue;
}
#media (min-width: 30em) {
.global-header {
position: fixed;
top: 0;
left: 0;
}
.main-content {
height: 100%;
margin-top: 5em; /* to offset header */
}
.global-footer {
position: fixed;
bottom: 0;
left: 0;
}
} /* ================== */
I had the same issue, my parent was set to transform-style: preserve-3d; removing it did the trick for me.
We'll never convince people to leave IE6 if we keep striving to deliver quality websites to those users.
Only IE7+ understood "position: fixed".
https://developer.mozilla.org/en-US/docs/Web/CSS/position
So you're out of luck for IE6. To get the footer semi-sticky try this:
.main {
min-height: 100%;
margin-bottom: -60px;
}
.footer {
height: 60px;
}
You could also use an iFrame maybe.
This will keep the footer from 'lifting off' from the bottom of the page. If you have more than one page of content then it will push down out of site.
On a philosophical note, I'd rather point IE6 users to http://browsehappy.com/ and spend the time I save hacking for IE6 on something else.
You can use it in the same way because if the parent container has the transform effect, you could create a child where it occupies 100% of the parent container and add a position realtive and then the container that you want to add the position fixed and it works without problems.
might be an answer for some cases https://stackoverflow.com/a/75284271/7874122
TLDR position: fixed is attached to containing element, by which element is positioned. if containing block is different than viewport dimensions, fixed element will be placed according to containing block.