I have a parent and a child elements:
.parent {
will-change: transform;
overflow: hidden;
position: absolute;
}
.child {
position: fixed;
top: 80px;
left: 80px;
}
without will-change:transform style, .child element regardless of parent's position and overflow:hidden will be positioned based on window.
Now that the .parent has this style, not only top and left of .child calculate from .parent, but also overflow:hidden applies on .child too.
It seems that position:fixed will be totally ignored if we add will-change:transform
Take a look here: https://jsbin.com/beluweroti/1/edit?html,css,output
Note: I don't add this style to .parent, so I cannot simply remove it.
I can deal with positioning, and set correct left and top, but the question is
how can I ignore overflow:hidden for fixed-positioned children?
From the specification:
If any non-initial value of a property would cause the element to generate a containing block for fixed positioned elements, specifying that property in will-change must cause the element to generate a containing block for fixed positioned elements
So basically you are facing the issue with transform and not the will-change because:
For elements whose layout is governed by the CSS box model, any value other than none for the transform property also causes the element to establish a containing block for all descendants. Its padding box will be used to layout for all of its absolute-position descendants, fixed-position descendants, and descendant fixed background attachments.ref
So transform is creating a containing block for fixed position element and will-change should do the same and since the .parent is now the containing block of the fixed element it will also apply its overflow on it.
Basically you can do nothing if you cannot remove the will-change property or change its value from .parent
Related
So if I understand z-index correctly, it would be perfect in this situation:
I want to place the bottom image (the tag/card) below the div above it. So you can't see the sharp edges. How do I do this?
z-index:-1 // on the image tag/card
or
z-index:100 // on the div above
doesn't work either. Neither does a combination of anything like this. How come?
The z-index property only works on elements with a position value other than static (e.g. position: absolute;, position: relative;, or position: fixed).
There is also position: sticky; that is supported in Firefox, is prefixed in Safari, worked for a time in older versions of Chrome under a custom flag, and is under consideration by Microsoft to add to their Edge browser.
If you set position to other value than static but your element's z-index still doesn't seem to work, it may be that some parent element has z-index set.
The stacking contexts have hierarchy, and each stacking context is considered in the stacking order of the parent's stacking context.
So with following html
div { border: 2px solid #000; width: 100px; height: 30px; margin: 10px; position: relative; background-color: #FFF; }
#el3 { background-color: #F0F; width: 100px; height: 60px; top: -50px; }
<div id="el1" style="z-index: 5"></div>
<div id="el2" style="z-index: 3">
<div id="el3" style="z-index: 8"></div>
</div>
no matter how big the z-index of el3 will be set, it will always be under el1 because it's parent has lower stacking context. You can imagine stacking order as levels where stacking order of el3 is actually 3.8 which is lower than 5.
If you want to check stacking contexts of parent elements, you can use this:
var el = document.getElementById("#yourElement"); // or use $0 in chrome;
do {
var styles = window.getComputedStyle(el);
console.log(styles.zIndex, el);
} while(el.parentElement && (el = el.parentElement));
There is a great article about stacking contexts on MDN
Your elements need to have a position attribute. (e.g. absolute, relative, fixed) or z-index won't work.
In many cases an element must be positioned for z-index to work.
Indeed, applying position: relative to the elements in the question would likely solve the problem (but there's not enough code provided to know for sure).
Actually, position: fixed, position: absolute and position: sticky will also enable z-index, but those values also change the layout. With position: relative the layout isn't disturbed.
Essentially, as long as the element isn't position: static (the default setting) it is considered positioned and z-index will work.
Many answers to "Why isn't z-index working?" questions assert that z-index only works on positioned elements. As of CSS3, this is no longer true.
Elements that are flex items or grid items can use z-index even when position is static.
From the specs:
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/
Make sure that this element you would like to control with z-index does not have a parent with z-index property, because element is in a lower stacking context due to its parent’s z-index level.
Here's an example:
<section class="content">
<div class="modal"></div>
</section>
<div class="side-tab"></div>
// CSS //
.content {
position: relative;
z-index: 1;
}
.modal {
position: fixed;
z-index: 100;
}
.side-tab {
position: fixed;
z-index: 5;
}
In the example above, the modal has a higher z-index than the content, although the content will appear on top of the modal because "content" is the parent with a z-index property.
Here's an article that explains 4 reasons why z-index might not work:
https://coder-coder.com/z-index-isnt-working/
Z-index needs these to work:
Position: relative, absolute, fixed, ..
Make sure that the parent element hasn't overflow: hidden;
I have had the same problem with z-index
and you believe me or not it's fixed just by setting the background color
like this
background-color: white;
If all else fails, look for syntax errors in your HTML. It's not intuitive, but I've seen it be the reason why z-index doesn't work.
The following code has invalid HTML syntax:
<div class="over"/>
<div class="under"/>
...(it's is invalid syntax because a div isn't a self closing tag).
CSS properties that were applied to these rogue HTML elements, such as background-color: black, position: fixed, width: 150px, and top:150px, were all working as expected. However, the z-index: 2 property wasn't working under the exact same conditions.
Only when the invalid HTML was fixed did the z-index work correctly.
I'm not sure why z-index was pickier than the other CSS attributes, but maybe this answer can help someone.
In my case I had my Navbar's opacity to 0.9, I got my answer from codercoder.com, as I removed the opacity property from my Navbar's css, z-index worked
just give position other that static. And u should give both container a position than it will work.
This question already has answers here:
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 6 months ago.
Seems like I just found a bug or something. Usually when an element has a pseudo-element and I want it to show behind its parent I use z-index:-1. This works fine if the element has position relative or absolute but on position fixed something weird happens: the pseudo-element comes between the background and the text of the element like this:
div {width:200px;height:100px;position:fixed;background:black;display:block;}
div::after {content:"";position:absolute;top:0;width:100%;height:100%;background:red;z-index:-1;display:block;}
<div>
example
</div>
Can this be fixed so the pseudo-element goes completely behind the parent as it does with the other positions?
Thank you.
The behavior your are experiencing is due to stacking contexts in CSS:
A stacking context is formed, anywhere in the document, by any element in the following scenarios:
[…]
Element with a position value absolute or relative and z-index value other than auto.
Element with a position value fixed […]
So when you use position: fixed on the parent, it becomes a new stacking context, whereas when you use position: absolute or position: relative without a z-index, it is not a new stacking context, which is why you see this discrepancy in behavior.
When the parent element is a stacking context it becomes a "container" for position stacking. The text or other elements inside it are by default at the stacking position 0 but the pseudo element in your example has z-index of -1 so it goes behind the text. It does not go behind the parent because the parent itself is the container. It is like you have all these elements in a box and elements can't go outside the the box.
So to have the pseudo element be behind its stacking context parent, we can use a 3D transform to translate the pseudo element behind the plane of the parent. We add transform-style: preserve-3d so "that the children of the element should be positioned in the 3D-space" and then we can add transform: translateZ(-1px) to push the child element behind:
div {
width:200px;
height:100px;
position:fixed;
background:black;
display:block;
transform-style: preserve-3d;
}
div::after {
content:"";
position:absolute;
top:0;
width:100%;
height:100%;
background:red;
z-index: -1;
display:block;
transform: translateZ(-1px);
}
<div>
example
</div>
So I want to offset an element 5 pixels up. I set position: absolute and top: -5px. Now the element is positioned relative to the page, not the containing TD tag. Am I understanding absolute positioning wrong? It does say
position it at a specified position relative to its closest positioned
ancestor or to the containing block.
Ancestor is TD, right?
Similarly, the top definition says
For absolutely positioned elements (those with position: absolute or
position: fixed), it specifies the distance between the top margin
edge of the element and the top edge of its containing block.
So why does this JsFiddle render the table content block relative to the page, not the TD?
You're missing a position: relative; in the parent TD element. The TD doesn't include that by default.
JS fiddle. http://jsfiddle.net/2p225mv2/2/
CSS to fix it:
td {
position: relative;
}
Because you're missing the part that says: closest positioned ancestor with the key word being "positioned".
Add:
td {
position:relative;
}
and you'll get this jsFiddle example
I'm having problems to make the div parent inherit the height of the div child.
.parent {
position: relative;
}
.child {
position: absolute;
width: 960px;
}
The text should be in the black gap.
Any help?
Do you need the child to be positioned absolutely for some reason?
This is why it doesn't 'fit' in your parent element.
According to the documentation
Position absolute:
Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor or to the containing block. Absolutely positioned boxes can have margins, they do not collapse with any other margins.
View the illustrations at https://developer.mozilla.org/en-US/docs/Web/CSS/position to see what exactly happens.
Remove any size attributes of the parent, it will then become as big as it needs to be for its contents.
Why have you declared position:absolute? If you want to move .child you should use position:relative or margins.
Absolute positioning removes the element from the natural flow of the document.
I have a div and an image inside it
<div>
<img src="logo.png">
</div>
img {
float: left;
}
I can see the div have collapsed, the height have become to 0,
my first question is, but the image is inside the, cuz the div's height is 0,why the image still can be see?
I know the solution like give the div a overflow property, even to auto. But why it can solve the problem?
By default, a parent element will not wrap around floated content. (It would be annoying in many situations if it did.) So if you want it to do so, you need to force the container to enclose the floated element. overflow: hidden; is one way of doing it, though it's not always a viable solution. There are quite a few other ways of doing it, too, such as the "clearfix" method.
The overflow property works to contain floats because, to obey the rule, the containing element has to 'look and see' what's inside it. Normally, floated content is taken outside the document flow and mostly ignored by other elements.
Here are some other containment options for that div:
The "clearfix" method:
div:after {
content:"";
display:table;
clear:both;
}
Floating the container:
div.contain {
float: left;
width: 100%;
}
Using display: table:
div {
display: table;
width: 100%;
}
Using display: inline-block:
div {
display: inline-block;
width: 100%;
}
Using position: absolute;:
div {
position: absolute;
width: 100%;
}
Some of these are more useful than others, and context will determine which is and isn't appropriate in any particular layout. Generally, I stick with overflow: hidden unless some content needs to hang out of the containing element (such as in a drop down menu), in which case I'll normally use the "clearfix" option.
Floating elements doesn't affect the size of the parent element. As the div only contains floating elements, there is nothing that gives it height.
By setting the overflow style on the parent element (to anything but visible), you force it to contain its elements, so that they can be scrolled.
By not setting a specific size on the parent element, it will get the size from its children, and you don't get scrollbars. As the children are now contained, the floating elements will affect the size of the parent.
An alternative to using overflow on the parent element, is to add a non-floating child after the other, and use clear: both; on it so that it's below the floating children. That way the parent will contain the children because of that last non-floating child.