I have 3 elements, two on the same level, and one child, all having fixed position. I need to set the z-index properties to place the parent on the bottom, the element on the same level in the middle, and the child on top.
I've tried setting a higher z-index for the child, but it's not working.
<div class="red">
<div class="blue"></div>
</div>
<div class="green"></div>
Here is the case http://jsfiddle.net/udENm/21/ (I need red on the bottom, green in the middle and blue on top, still maintaining red and greenon the same level).
My CSS is like this
.red {
position: fixed;
z-index: 2;
}
.green {
position: fixed;
z-index: 2;
}
.blue {
position: fixed;
z-index: 5;
}
Set your positioning to absolute and remove the z-index from the parent div (the red one) entirely. http://jsfiddle.net/calder12/udENm/32/
.foo {
background: red;
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
}
.bar {
background: green;
position: absolute;
left: 100px;
top: 100px;
z-index: 2;
width: 100px;
height: 100px;
}
.child {
background: blue;
position: absolute;
left: 40px;
top: 40px;
z-index: 5;
width: 50px;
height: 50px;
}
The z-index property only has effect within the stacking context of the containing element.
Put another way, given a bunch of block elements within the same parent element, you can control their front to back ordering pretty easily. However, z-index can only control the front to back ordering within this parent element and not within the global context.
So, you can move .blue backwards and forwards within .red all you like. You can also switch .red and .green around in the z-plane all you like too. However, you can't put .green between .red and .blue because they are in different stacking contexts.
EDIT
Stacking context only applies to elements that are in the flow. If you use position:absolute, then you can do this. See Rick Calder's answer
The green blocks z-index needs to be lower than the red ones. I used this CSS instead of the one you posted:
.foo {
background: red;
position: fixed;
left: 50px;
top: 50px;
z-index: 2;
width: 100px;
height: 100px;
}
.bar {
background: green;
position: fixed;
left: 100px;
top: 100px;
z-index: 1;
width: 100px;
height: 100px;
}
.child {
background: blue;
position: absolute;
top:50%;
left:50%;
z-index: 5;
width: 50px;
height: 50px;
}
Works fine, as you can see green is now z-index 1, red is z-index 2 and the blue block has absolute positioning.
Z-index is relative in a way to the parent. Red is already at 2, and blue is only at z-index 5 compared to it's siblings, but not to outside elements like Green.
Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context.
Kinda like this?
http://jsfiddle.net/kBv7R/
HTML
<div class="foo">
<div class="child"></div>
<div class="bar"></div>
</div>
CSS
.foo {
background: red;
position: fixed;
left: 50px;
top: 50px;
z-index: 2;
width: 100px;
height: 100px;
}
.bar {
background: green;
position: fixed;
left: 100px;
top: 100px;
z-index: 5;
width: 100px;
height: 100px;
}
.child {
background: blue;
position: fixed;
left: 90px;
top: 90px;
z-index: 6;
width: 50px;
height: 50px;
}
Related
I need to make a floating div that appears to be almost hidden and if I click in the tab it appears to the left. Floating over the rest of the site. I don't know if I made myself clear, so I put here two images, how it should look hidden and visible. But I couldn't figure it out yet how to make it. Any help will be appreciated.
I work with VueJS.
This is a vanilla js implementation that uses fixed position, the css transition property for animation, and a class that is toggled when the handle is clicked to change the position.
const slideout = document.querySelector('.slideout')
const handle = slideout.querySelector('.handle')
handle.onclick = function() {
slideout.classList.toggle('active');
}
.slideout {
position: fixed;
width: 80%;
height: 80%;
left: 100%;
top: 10%;
transition: left .3s ease-out;
}
.slideout.active {
left: 10%;
}
.handle {
position: absolute;
top: 10px;
left: -20px;
width: 40px;
height: 40px;
border-radius: 50%;
background: darkred;
cursor: pointer;
}
.body {
position: absolute;
background: red;
width: 100%;
height: 100%;
border-radius: 8px;
}
<div class="slideout">
<div class="handle"></div>
<div class="body"></div>
</div>
I've created a notice as in the pictures
But some extensions will appear above this notification
this css for notice
display: block;
position:fixed;
for "online" css
display:inline-block;
It could be those other elements also have position:fixed on them. One solution is to use z-index and set it higher than the other element
As you haven't supplied any sample html/css for us to duplicate this issue, I'm going to use some generic HTML:
div:first-of-type {
background: red;
width: 100vw;
height: 100vh;
}
.fixed {
position: fixed;
top: 0;
left: 0;
width: 200px;
height: 200px;
background: blue;
}
.fixed.green {
background: green;
left: 20px;
top: 20px;
}
<div>Some content</div>
<div class="fixed green">Fixed element</div>
<div class="fixed">Another fixed element</div>
As you can see, the green div is under the blue one. This will represent your notification.
By adding z-index:5; to the green div (in this example any value greater than 1 will work) the green div will appear at a higher level than the blue div and become visible:
div:first-of-type {
background: red;
width: 100vw;
height: 100vh;
}
.fixed {
position: fixed;
top: 0;
left: 0;
width: 200px;
height: 200px;
background: blue;
}
.fixed.green {
background: green;
z-index: 5;
left: 20px;
top: 20px;
}
<div>Some content</div>
<div class="fixed green">Fixed element</div>
<div class="fixed">Another fixed element</div>
The maximum value for z-index varies by browser but generally is in the millions. Feel free to set the notification z-index to 9999 or some other super-high value.
This question already has answers here:
css z-index issue with nested elements
(2 answers)
I have position but z index is not working
(1 answer)
Lower z-indexed parent's child upon higher z-indexed element?
(2 answers)
Closed 4 years ago.
I have a problem with positioning, I'd like to put the .sibling-child over .parent without modifying the current z-index. Is there a way to do this in CSS?
Here the jsfiddle with the problem. http://jsfiddle.net/8hb6xgLj/1/
.parent {
width: 300px;
height: 100px;
background: #333;
position: relative;
z-index: 10;
}
.child {
top: 60px;
position: absolute;
width: 50px;
height: 80px;
background: red;
}
.sibling {
width: 300px;
height: 100px;
background: #ccc;
position: relative;
z-index: 9;
}
.sibling-child {
top: 10px;
position: absolute;
width: 70px;
height: 80px;
background: blue;
}
<div class="parent">
<div class="child">
</div>
</div>
<div class="sibling">
<div class="sibling-child">
</div>
</div>
In your example, both div elements are positioned with different z-index, This means they are stacked in the order they appear in the markup, with the first declared element having the highest stacking index.
Therefore, according to that definition, there is no chance that .sibling-child will appear above .parent.
See the W3C specification on stacking context for more information. Note point 9 in particular:
Stacking contexts formed by positioned descendants with z-indices
greater than or equal to 1 in z-index order (smallest first) then tree
order.
This is the only thing I can think of.
transform: translate3d(0, -100px, 20px);
.parent {
width: 300px;
height: 100px;
background: #333;
position: relative;
z-index: 10;
}
.child {
top: 60px;
position: absolute;
width: 50px;
height: 80px;
background: red;
}
.sibling {
width: 300px;
height: 100px;
background: #ccc;
position: relative;
z-index: 9;
}
.sibling-child {
top: 10px;
position: absolute;
width: 70px;
height: 80px;
background: blue;
transform: translate3d(0, -100px, 20px);
}
<div class="parent">
<div class="child">
</div>
</div>
<div class="sibling">
<div class="sibling-child">
</div>
</div>
Is there a way to set a global margin to a page which will include absolutely and fixed positioned elements as well?
This is possible is you wrap these absolute / fixed elements with an element which has transforms set on them.
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.
body {
margin: 100px;
color: white;
transform: translateX(0);
border-top: 2px solid green;
}
.absolute, .fixed {
width: 100px;
height: 100px;
top: 0;
}
.absolute {
position: absolute;
background-color: red;
left: 0;
}
.fixed {
position: fixed;
background-color: blue;
right: 0;
}
<div class="absolute">absolute</div>
<div class="fixed">fixed</div>
Notice that, in the above snippet, both the absolute and the fixed element are positioned relative to the body with the margin.
Note:
1) I don't necessarily recommend using it this way as it will most probably cause confusion in the long run.
2) As #Temani Afif pointed out fixed elements will behave like absolute elements this way - so this technique may not work as expected depending on the context.
You can add margin to all elements with the wildcard selector, but then you'll spend a lot of time cancelling this out on internal elements. You can try something like body > * to add margin to top level elements.
body > * {
margin: 50px;
}
#abs {
position: absolute;
top: 0;
left: 0;
background: red;
width: 100px;
height: 100px;
}
#abs .inner {
position: absolute;
top: 0;
left: 0;
background: blue;
width: 50px;
height: 50px;
}
#fixed {
position: fixed;
bottom: 0;
right: 0;
background: green;
width: 100px;
height: 100px;
}
<div id="fixed"></div>
<div id="abs">
<div class="inner"></div>
<div>
I am working on an image uploader. I have a drag and drop field for the image using https://codecanyon.net/item/slim-image-upload-and-ratio-cropping-plugin/16364167?ref=pqina&ref=pqina&clickthrough_id=749572872&redirect_back=true . But I want the dropzone to have an image as an overlay of the dropzone. I managed to do this with a :before element. It works as intended in Chrome and even in Edge. But in Firefox I can't click the dropzone behind the :before Element. Is there any way to fix that?
Very simplified example here:
Simplified :before:
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 8px;
left: 8px;
opacity: .5;
-moz-opacity: 0.5;
}
https://jsfiddle.net/6kv6u9kv/
I want the "click me" to be clickable. I appreciate any quick help because this is for work. Thanks in advance!
SOLUTION:
You can use pointer-events: none; css property in your overlay.
The pointer-events property allows for control over how HTML elements
respond to mouse/touch events – including CSS hover/active states,
click/tap events in Javascript, and whether or not the cursor is
visible.
CODE SNIPPET:
.dropper {
width: 200px;
height: 200px;
background: #aaa;
padding-top: 100px;
}
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 8px;
left: 8px;
opacity: .5;
-moz-opacity: 0.5;
z-index: 100000;
pointer-events: none;
}
<div class="dropper">
<a href="#" id="click">
click me
</a>
</div>
pointer-events: none is an obvious choice though has less browser support.
Here is another way
.dropper {
width: 200px;
height: 200px;
background: #aaa;
padding-top: 100px;
position: relative;
}
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 0;
left: 0;
opacity: .5;
-moz-opacity: 0.5;
}
.dropper a {
position: relative;
}
<div class="dropper">
<a href="#" id="click">
click me
</a>
</div>
You can use the css pointer-events style to tell the browser to, as the name suggests, ignore any pointer events. This includes blocking pointer events to elements it may cover.
.dropper {
width: 200px;
height: 200px;
background: #aaa;
padding-top: 100px;
}
.dropper:before {
content: " ";
width: 200px;
height: 300px;
background: #ff0000;
position: absolute;
top: 8px;
left: 8px;
opacity: .5;
-moz-opacity: 0.5;
z-index: 100000;
pointer-events: none;
}
<div class="dropper">
<a href="#" id="click">
click me
</a>
</div>
Of course check the browser support. If you are targeting a browser that does not support it you would have to implement some forwarding system: capture the click on .dropper get the mouse x,y and for any element occupying the same coordinates trigger the event for that element.