HTML z-index not working as expected - element position issue? - javascript

I have a page with an input element whose position is determined by the normal flow of the page (i.e. its position is NOT explicitly defined as part of the element definition).
Then, I have other elements (divs) that are created programmatically with fixed position, and should appear behind the input element whenever there is an overlap between them.
I tried assigning to the input element a ridiculously high z-index (100001, while the programmatically elements have a z-index < 1000) but the input element still is shown BEHIND the others.
I found some posts suggesting that the input element should also be positioned as the other elements, but this could have negative impact on the general layout of the page.
Does anyone have a suggestion I may try?
Thanks.

z-index only applies to positioned elements, so you need to position it.
Set it to position: relative if you want to position it without moving it or taking it out of normal flow.

z-index is intended for elements positioned as absolute, relative and fixed.
Try setting your input position: relative, then you z-index should work.
#myInput {
position: relative;
z-index: 100001;
}

Related

Whether 'position:absolute' is always 'display:block'

I am trying to understand positioning of elements in html. The accepted answer here says,
"All elements that are position:absolute; are automatically treated as
display:block, since that's the only logical display mode for absolute
positioning."
Is this always true? If display is always block for absolute elements, why the following code snippets appear differently? Please help me to understand this. thanks.
<div>
<div style="display:inline-block;">aaa</div>
<div style="position:absolute;">bbb</div>
<div style="display:inline-block;">ccc</div>
</div>
<br><br>
<div>
<div style="display:inline-block;">aaa</div>
<div style="position:absolute;display:inline-block;">bbb</div>
<div style="display:inline-block;">ccc</div>
</div>
There's a couple of things here. First, no, not all absolute positioned elements are treated as display:block. Their display value is blockified which means that they are converted to block-level display values. For example:
display:inline-flex => display:flex
display:inline-grid => display:grid
display:inline-table => display:table
display:inline list-item => display:list-item (Firefox supports inline list-item)
display:none and display:contents aren't changed.
display:inline, display:inline-block, and internal table object boxes =>
display:block
Elements that are already block level are unaffected. Flex is still flex, grid is
still grid, etc.
However, that doesn't explain why you get different results for your two cases, since in each case the absolute positioned items do indeed have a computed display value of block. For this, we need to address our expectations of what it means for an element to be display:block. We expect it to start a new line and have its left to right margin edges fill the width of the containing block.
In fact, that only applies to block level elements in normal flow. Absolute positioned elements are not in normal flow, and so those rules don't apply. They have their own set of rules, part of which say that if their top, left, bottom, right values are auto (which they are in your examples), the box is positioned according to where its position would have been if it hadn't been absolutely positioned. And if it hadn't been absolutely positioned, the display:block and display:inline-block difference would have had an effect, in your first case starting a new line, in your second case remaining on the same line.
The default behavior of position: absolute is display:block, but you override that default behavior when you add display:inline-block;.

Why fixed positioned element with lower z-index is front of relative positioned element with higher z-index?

I have a code which controls scroll dependant animations. The direct children of body are put on each other. So the first element has z-index 0, the second has z-index 1, and so on. And all of them are wrappers, with relative position. They children have relative position first, and if the element reaches the top of the window, the position of it switches to fixed. If it happen, it's wrapper goes back in the layer panel (with z-index: 100), behind an another element with position: fixed, and with z-index 2. It's a bit weird, because if the wrapper's child has position: relative, the wrapper takes the right place. After it's child's position turns to fixed, it immediately goes back in the layers. What's the relationship between these things? For better understanding i attach some pictures from chrome devtools, layers:
Here, the black element is the child, and the gradient element is the parent. The parent stays at the right place in the order of z axis, and the child has position: relative.
Here, just a few scrolls away, the child gains position: fixed, and the parent goes back (with z-index 100). What happens here? Why the parent goes back in the layers, if it's child has position: fixed?

How to make an element's height increase with every child added to it

I have a <div> that has children appended to it by a script. These children elements are automatically appended by a PHP script and positioned using position:absolute. I tried to give the parent <div> the style min-height:400px allowing the elements appended to the <div> to increase the parent's height. The only problem is that the height does not increase when I do this. Does anybody know what I can do to fix this?
EDIT: I am not able to use position:relative for positioning my elements. Are there any solutions that allow for position:absolute.
Yes you can use position absolute (yeee♥!)
LIVE DEMO TEST CASE
By simply doing:
$(this).height( this.scrollHeight );
or with pure JS:
this.style.height = this.scrollHeight ;
and adding this to your element's CSS:
overflow:hidden;
overflow-y:auto;
Edit:
The demo tested fine in IE10, Firefox, Chrome, Safari, and Opera.
The key point here is setting the overflow value for the x or y axis (whichever dimensions you need the size of) to auto, rather than the default value of visible. Then the scrollWidth or scrollHeight property can be used on the HTML DOM object to get the full size of the element, including any absolutely-positioned descendants.
Odd as it seems, this is entirely consistent with the fact that setting overflow:hidden for a container clips any absolutely-positioned descendants. Apparently, elements with position:absolute aren't quite as "out of the flow" as we've always been told :)
You should not use position: absolute for this because stuff that is positioned that way will be pulled out of the normal render flow. This results in the parent not noticing that its content s acually very high. Use position: relative for the child div's. This way the parent will grow automatically.

Using .position() in jQuery

My script here needs a little work on the positioning of the sentence. If you click on any of the choices, the sentence should slide down to that height. I'm trying to use .position() to obtain a relative position (as the doc says, relative to the offset parent, which is why I'm writing this thread).
Obviously, the .position() is a little off right now because it seem to think it's offset parent is the document itself and the jQuery doc didn't mention anything about setting the offset parent. Any inputs are greatly appreciated.
PS: I'm currently using position: relative on the sentence, which are 2 <p> tags.
on css add position: relative; to the parent element/container
Add position:relative; to your CSS for div[id^=wrapper].
All absolute positions are taken relative to the closest positioned container. In your original code, the closest positioned container is the <body> tag, which obviously isn't what you want.

Computed height of an element set to display: none

To calculate a top position for an element of variable height, I was thinking of doing the following:
Move the element 1000px off the top of the viewport
Set the element to display: block
Get the height of the element
Set the element to display: none
Continue on as if everything is normal and good
Any pitfalls in this approach? Is there a more elegant solution?
I'd look at prototype's implementation of getDimensions.
It sets the position to absolute, visibility to hidden, and display to block briefly. I've written one which handles getting the height of something which is contained within a display:none element, but it's a bit shonky in some edge cases.
can you not just set the visibility to hidden and get the offsetHeight?

Categories