I havent found this exact question.
I have a page set up as
<div id="page">
<div id="chrome">
<div id="element">bla</div>
<div id="content">bla</div>
</div>
</div>
#page has position:absolute, and dimensions
#chrome has position:static, and overflow:auto
#element has position:absolute, right:0, top:0
#content has a large amount of content. it scrolls within #chrome, whereas #element stays fixed on the #page, without needing position:fixed.
http://jsfiddle.net/pike/x4kshd3f/
In some browsers - mainly windows i think - the #element overlaps the top of the scrollbar of the #chrome.
Is this correct behaviour ? Is there a way to make the scrollbar of the static #chrome appear on top of its absolutely positioned children ?
PS .. there is a reason why its structured like this. I cant use position:fixed. I cant put the scrollbars on #page. #chrome has to be static.
It actually happens on other browsers/platforms too, and yes, I'm afraid its intended behaviour.
Element with static positioning do not create a stacking context. the #element, which has position:absolute, has a stacking context. the effect is #element overlays #chrome, in a sense.
What seems to solve it in edge browsers is css
#chrome { isolation:isolate }
which is a css candidate from 2014-12. and a very sensible one.
https://developer.mozilla.org/en-US/docs/Web/CSS/isolation
http://dev.w3.org/fxtf/compositing-1/#isolation
There are other ways to create a stacking context, but they all seem to interfere with the absolute positioning of #element, making it 'relative' to #chrome instead of #page (making it scroll along with the #content instead of staying fixed).
Still open for better supported solutions - I won't accept this answer.
Related
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.
I am building a site and have a div with another div inside (lets call them div.container and div.contained). div.container is relatively positioned and div.contained has a fixed position. I want to use the overflow-y: scroll property to have the overflowing content in the container displayed within a defined height and scrollable. I found that this is a common issue in many versions of Internet Explorer along with an article that states the quickest way to fix the bug is to make the position of div.contained relative (http://code.tutsplus.com/tutorials/9-most-common-ie-bugs-and-how-to-fix-them--net-7764).
I tried this workaround but changing the position style of div.contained throws off the whole website. I tried looking through the forum and have found similar issues but no specific workaround for fixed elements, just relative ones. Does anyone have any advice on how to fix this ie bug for a fixed positioned div?
I am building a design and have it pretty much done however an item I have positioned absolutely will not show the overflow in IE7. It works for every browser but IE7.. I'm not supporting ie6. The div/image will not show anything past its parent container in IE7. I've tried a higher z-index, overflow:visible with no success.. The absolute positioned div is in the top nav bar left of the first menu item.. should be obvious
The site is here
thanks for any help or suggestions
To fix it in IE7, do the following:
Remove:
position: relative;
From .navbar-inner
It's a bit redundant to have it on inner, because it's container is already set to a relative position (they are the same size/shape). It will carry the same effect without it on the inner div, and give you the results you're looking for.
Try giving .navbar-inner a higher z-index value than you have given to the absolutely positioned DIV.
I'd reduce your absolutely positioned elements z-index down to something like 100 and make .navbar-inner 101.
The nav works the same in every browser i've tested on a mac and pc; however, I cant for the life of me figure out why in IE7 the nav is appearing under the content in the main content block. Check out http://obs4.dynapp.net/ to see the problem, it only exist in IE7. Check out the source if your interested in helping out with the problem. I dunno, I've spent hours staring at html/css and cant figure anything out.
http://obs4.dynapp.net/
This is a seriously annoying IE7 bug. It occurs because positioned elements later in the DOM will be given priority over those earlier in the DOM, regardless of z-index status.
This article will explain how to fix it: http://thedesignspace.net/MT2archives/000763.html
Basically, add position and z-index to the least common ancestor. So, if your header and content are both contained in a container, add position and z-index to that container. If they're direct children of the body, add it to the body.
Hope that helps.
z-indexing is weird with IE7. You have position: absolute for your nav. You have position: relative for your content. Yes, z-indexing should work where your position doesn't matter, but IE7 will take that into affect and give you two different "stacks" for z-indexes so absolute and relative positioned elements do not interact with each other. Try giving your nav a position: relative instead and then readjusting your css accordingly.
I was trying to absolutely position an element at the bottom of the page (not the viewport). The element is a direct child of the BODY. You can imagine the page to have lots of content so that there is a scrollbar.
So something like this:
<body>
<img id="target" src="images/code.png" style="position:absolute;bottom:0;"/>
This put the image at the bottom of the viewport over the existing content. However, once I added the following css rule:
body{
position:relative;
}
The image went to the bottom of the page.
So if BODY is not the containing block of all elements, what is ?
Also, I am sure this is a solved problem but I couldn't find an example with detailed explanation of the problem and the solution. Any pointers?
It could be <html>?
Set position: relative on that and see what happens.
Update - Straight from quirksmode
The containing block
In order to specify the exact position of the element, you have to add top, bottom, left, and/or right declarations. These all give coordinates relative to the top/left or bottom/right reference point. What is this reference point?
position: static: No reference point, since a static block cannot be moved.
position: relative: The position the block would take if it were not moved (i.e. if it had position: static).
position: absolute: The containing block, which is the first ancestor element that does not have position: static. If there is no such ancestor, the <html> element serves as the containing block. (Note: in older browsers the <body> element serves as the default containing block.) <--- Bingo
position: fixed: The viewport (browser window).
Ok lets suppose you have the following:
<body>
<img id="target" src="images/code.png" style="position:absolute;bottom:0;"/>
<div style="margin-bottom: 50px">Content here</div>
</body>
This should solve the problem. Obviously set the bottom margin to the height of the image. Otherwise you could try setting the bottom margin of the body tag to the height of the image, then set the bottom setting for the image to -{height of the image}. This should achieve the same effect as above though.
PS In case you didnt realise, margin-bottom is the amount of space that appears below an element. If you want a coloured background for the body and you want this to take effect around the footer (like, say, if your footer is only 80% of the screen and centred, leaving 10% at either end) then you could always try padding-bottom: 50px.
Sounds like natural behaviour to me. You said the page would have lots of content and you would have a scrollbar. Having an element with position: absolute it would calculate it's position based on the nearest parent with position relative.
If the page is so high that you would have a scrollbar, the body element would stretch to the bottom of the page. Your image (position: absolute) is a child of body(position: relative), so I don't see the problem.
I also don't really understand your question:
I was trying to absolutely position an
element at the bottom of the page (not
the viewport).
This put the image at the bottom of
the viewport over the existing
content. However, once I added the
following css rule:
body{ position:relative; }
The image went to the bottom of the page.
Isn't the problem solved now? Do you want the image at the very bottom? (when you scroll down you can see it) or do you want it just above the fold?
Maybe this is a bit silly, but i think there is the above the body. I use resets, and in some of the large ones is always a line like this:
body, html { 'css properties bladiebla' }.
So to me that suggests that html is the container for body, sounds pretty logical to me ;) (but i can't find any references or proof of it myself a.t.m.)