CSS: position:fixed inside of position:absolute - google-chrome

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.

Related

position:sticky on horizontal scroll doesn't work

i have a table that looks like this:
<table id="navbar" border="1" style="background-color:navy;height:150px;position:sticky;top:0px;right:0px;left:0px;border-style: solid;border-color:black;max-width:999999px; width:100%; background-image: none;">
the style for all tables:
table{
text-align:center;
width:30%;
left:25%;
/*font-size:larger;*/
}
the psoition sticky should make it so that the table will always remain at the top of the screen, even on horizontall scroll. yet it doesn't work. the only way i found for it to work was by adding another table above and giving both the display:inline-table attribute, but it is not the solution i am looking for.
anyone knows the reason for why it doesn't work?
edit-i need to use position:sticky. it works pefectly for vertical scroll, but not for horizontal scroll. that is the problem i need to fix
Sorry it took so long for someone to answer you #Erel.
So you don't have to read my ramblings if you just want code, I'll start with the demo: https://codepen.io/NerdyDeeds/pen/oNYVLpB
There's a couple things to note here, for the behavior you're after:
Much like the whole height:100% thing, for this to work, the measurements need to go all the way down to the :root. That is to say, every DOM node hierarchy needs to know the actual limits of its bounding box (don't worry: it'll become more clear below).
When an object is positioned sticky, it basically has TWO sets of coordinate limitations: those of the viewport, AND those of its parent. If the parent is 500px wide and you scroll 1500px off screen to the right, the sticky element will stop at the edge of its parent, not continue to tag along. Which brings us nicely to the most important aspect:
The <body> tag is simply another block-level container object, only it gets an implicit min-width:100vw; min-height:100vh. That said, if the one of IT'S children that's necessitating the horizontal scroll is, say, 250vw wide, it will expand to contain that element, but it's measurement width remains the same; it's children still think papa's only 100vw wide. Likewise, were you to explicitly tell it that it's "ACTUAL" width is really only 100vw, it too, will slide off-screen when scrolling, carrying its sticky child (aren't they all?) with it.
The same thing applies to all the ancestral containers of your sticky element. They DON'T automatically get the min-width, so you need to explain to them they're to take up that full space. If you want that done dynamically, you need to explain that to the <body>, so they can inherit the "real" 100% of the page. If any ancester is throttled in its movement or its dimensions, that will cascade all the way down-chain to your element, sticky or not.
The simplest way to tackle this I've found is to simply add:
body {
width: max-content;
}
...to you CSS. This tells the body "you're actually as wide as your widest contents... pass it on!" The "cascading" portion of the CSS will take hold and carry they measurement all the way up to your sticky element, provided none of the parent nodes between it and the body themselves are constrained (like if you set a width:100vw in there somewhere. 100% will work fine, but again: only if none of IT'S ancestors is smaller).
Check out the attached CodePen. I tried to make it as self-explanatory as I could.
And again: sorry nobody got back to you sooner. That's a frustrating feeling that stinks. I hope you already found your solution, but if not, this may help who comes googling after. Hope this helped.
Use fixed position:
<table id="navbar" border="1" style="background-color:navy;height:150px;position:fixed;top:0px;right:0px;left:0px;border-style: solid;border-color:black;max-width:999999px; width:100%; background-image: none;">
position: fixed always fixates an element to some position within its scrolling container or the viewport. No matter how you scroll its container, it will remain in the exact same position and not affect the flow of other elements within the container.
position: sticky basically acts like position: relative until an element is scrolled beyond a specific offset, in which case it turns into position: fixed, causing the element to "stick" to its position instead of being scrolled out of view.

Div contents extending size of page rather than scrolling its contents regardless of overflow attribute

I am blocking out a new page for my site that is going to be responsive with a sliding divide separating 2 columns. On the left column I have a couple vertically stacked divs, the bottom of which I want to scroll its contents when it overflows. I want only the div to scroll and not the entire page.
I have already set the overflow-y to scroll and while this does produce the scroll-bar it still expands the entire page rather than recognizing the edge of the window. I have a feeling it has to do with the parent containers size not being fixed and I thought setting it to max-height: 100%; would resolve this but it has not.
here is the jfiddle
jfiddle
It is basically just a grab from my sandbox site wtb.dsdcs.com but it seems to behave the same in the jfiddle so it should suffice.
Just a disclaimer: there is a video the autoplays in both the website and jfiddle that I left intact in-case its container is part of the issue, so may need to turn down speakers.
Clarification: #PlayList is the element I wish to be able to scroll.
You need to give your Playlist class a height - (e.g 400px). Then, as you add more a items you should get a scrollbar. You can remove max-height as that won't be needed.
If you want a dynamic height of the playlist, that always takes up the remainder of the height, you could add a jQuery script:
var h1 = $(window).height();
var h2 = $('.videowrapper').height();
$('.playlist').height(h1-h2);
Since your videoWrapper is set to take up 50% of the height, the other approach could be to set your playlist to have the other 50%. So set it to height: 50%.
.playlist {
padding: 10px;
font-size: 12px;
overflow-y: scroll;
height: 50%;
position: relative;
}
EDIT 17 Oct:
The reason the above might not work with all browsers is probably because of your implementation. Like I said in the comments below, you shouldn't be using table-type display properties because they don't support overflow very well.
The W3C even say that the overflow property only applies to block-type elements LINK.
The MDN suggests the same LINK.
As such, implementing overflow on any table-type element will always be a tricky and risky approach as browser support issues or browser display inconsistencies should be expected. To get a fully supported solution, I'm afraid you'd have to try other display properties such as flex or block.
Unfortunately, there is no way to get a fully supported solution for overflow on table elements, and therefore such answer cannot be provided. The only real "solution" here that would actually solve your problem would be a complete (or partual) overhaul of your entire site.
However, I hope the above gave you hint of direction of what to do next and as such being an acceptable answer for you.
Good luck!

Using CSS transform scale breaks position:fixed

I am experiencing an odd issue and am wondering if it's a bug in the rendering engines - it occurs in WebKit and also Firefox that I've tested.
If you have a div that's fixed on the page and you add another div inside it and also set it to be fixed (to obtain a fixed header within a fixed popup), you can ensure that the header will remain visible even when the user scrolls the popup. Unless you set transform scale on the popup - doing that will break position:fixed and cause it to no longer fix to the top of the parent div and instead it will scroll along with the content. Is that expected behavior - how can I work around that?
JSFiddle
Well the transform: scale(x) will break the element out of the coordinate flow and thereby can not have a fixed position.
I'd recommend instead wrapping the text below #header in a constrained div with overflow: auto. A fixed child of a fixed ancestor just doesn't make that much sense, but I can see what you were going for.

CSS position is making image preview half visible

I am working on a project and I am using woocommerce dynamic gallery pro plugin to preview product images in product page. but the issue is that the preview image is showing half in IE.
please can you guys check the following link in IE and help me to fix.
http://www.joannelouise.com/shop/sexy-ladies-red-embellished-dress/
I find a fix, but I am not understanding how i apply this.
I notice if i remove the position from the following class, it may fix the error. but when i am giving position some value like absolute, relative, fixed, static or even inherit. it isn't giving any response until i off the position.
so guys kindly help me to fix this.
following are my changes. which are effecting 50%.
.ad-gallery .ad-image-wrapper .ad-image {
overflow: visible !important;
position: inherit !important;
}
but position thing is not working
You should really avoid so many inline styles. It makes for messy code and more work.
For some reason you're setting .ad-image to {top: 179px;}. Try this (after removing the inline top statement):
.ad-gallery .ad-image-wrapper .ad-image {
top: 0;
}
Strangely, I see {top: .5px} in Firefox. I'm not sure what's going on.
I'm not on a widows box right now, but it could be a case of not clearing a float or a parent item isn't containing children who are floated.
Try using:
overflow:auto on the parent container of whatever images are not showing fully. Can also try using overflow:hidden to achieve the same but avoid scrolling bars in some instances.
Try to avoid ever using !important on production sites if possible.
OP, What version of IE are you using?
The position property specifies the type of positioning method used for an element (static, relative, absolute or fixed).
Note: The value "inherit" is not supported in IE7 and earlier. IE8 requires a !DOCTYPE. IE9 supports "inherit".
Via http://www.w3schools.com/cssref/pr_class_position.asp
IE 7/8 Work-around:
.ad-gallery .ad-image-wrapper .ad-image {
overflow: visible !important;
position: <whatever-the-parent-is> !important;
}
Since IE 7/8 doesn't understand to inherit the position from the element's parent, you can create a CSS rule that specifies what position you'd like the element to use.

iframe preventing z-index from working?

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