Example code: http://jsfiddle.net/ZAm2A/3/
The goal is to position certain popup(div.absolute-block) window against(relative to) any dom element on any page with different html structure.
In order to be able to position popup absolutely, we need to embed it into that dom element, having previously wrapped div.absolute-block with relatively or absolutely positioned block (div.relative1 in our example).
The trouble is that if dom element, we embedded popup in, has block with overfillw: hidden (div.overflow1) among it's ancestors, div.overflow1 will probably crop popup. div.overflow1 may be positioned relatively and we cannot influence it in our situation.
The second approach is to append our popup to page body. In this case we face problem of positioning our popup relatively to certain dom element. We can calculate and set top and left properties for popup on document ready event. But in case of window resizing, ajax content changes or any events changing position of tracked element we have to recalculate popup position.
I think whether there could be some new html 5 features that will let me position popup without embedding it into dom element, i want to position popup relative to? Any other ideas are appreciated.
There's no way to have a child element escape a parent element that has overflow set to hidden. If you want to have an element positioned exactly over the top of a certain element on the page, your safest option is to put it at the root of the document, use Javascript to calculate and adjust the position, and update on window resize, etc. You might be interested in using jQuery's position() (relative to parent) or offset() (relative to entire document) methods to help calculate this.
Also, here's a somewhat-related question on the overflow: hidden issue which might help: Make child visible outside an overflow:hidden parent
Related
I maintain a library, react-to-print. The library provides a React component that at its core has two inputs: a trigger (usually a button), and content. When the trigger is clicked, the library will copy the entire DOM representation of the content and put it into an iframe. It will also copy all style links on the page to ensure the content is styled correctly within the iframe.
A while ago, someone raised an issue (the end of the thread explains the core problem) concerning the library's seaming inability to print content that was horizontally scrolled, in this case, within a table. It turns out that what is actually happening is that a component within the content is virtualizing its render, meaning only content this is visible on the screen is actually being rendered. So the issue is that react-to-print is not maintaining the scroll positions of child elements when it copies them into the iframe.
I know how to scroll the entire page itself inside of an iframe, but do not know how to maintain the scroll of individually scrolled DOM elements that are children of the window. Is there a way to do that?
While an ideal solution would of course be just turn on a setting or something and done, I'm guessing that, if a solution is possible, it will look something like:
Iterate over every element on the page
If the element has a scroll, save its scroll position in a map
Copy over the elements into the iframe (as is currently done)
Iterate over every element in the iframe and apply a scroll if one is found for it in the map
Is it possible to make an element have fixed position, but stop it from scrolling with the page?
My problem: I am building a tooltip that I dynamically determine the placement for depending on what space is available on the page for it. It needs to pop up over everything else next to its target element and not take up space. So I initially thought position absolute.
But absolute position is based off of the element's parent wrapper. My page gets wrapped in multiple various wrappers that I have no control over (on Salesforce, but this isn't necessarily a Salesforce specific question).
So I need to position it off of the viewport instead of relying on what parent it ends up getting wrapped in. So position fixed, works great.
The only issue is position fixed has the element scroll with the page. I don't really want the tooltip to follow the user as they scroll.
I feel I need to keep the position based on the viewport due to not being able to control the parent wrappers. But all I have found is position fixed, so not sure if some method exists to stop the element from scrolling with the page.
Seems like you want to use position: absolute; instead of fixed.
If you're set on position: fixed, the only way I know of to have the element move with the rest of the page as the user scrolls is by editing the location with JavaScript when the browser scroll event fires. Otherwise, if you position with respect to the viewport at first, you'll be positioned with respect to the viewport on an ongoing basis. However, hooking into the scroll event doesn't necessarily perform well, and although there are debouncer functions available to help with that, it wouldn't be my first choice.
You may be able to use position: absolute without tangling with the extra page wrappers, however. Is there is an element (call it A) that has these properties:
your tooltip lives inside A (or can be moved there)
you can correctly position your tooltip relative to A
the extra wrappers are always outside A
If so, set position: relative on element A. Your tooltip will use A for reference and not an extra wrapper outside A (even if that wrapper also has position: relative set on it).
Is there a way to make "scrolling" inside an element completely impossible? By that, I mean the content of the element must always keep the same position relative to the element. The element in question has fixed dimensions and overflow: hidden;.
I am not talking about preventing the user to scroll inside a certain element, for example by overriding the behaviours of key presses with JavaScript. I don't think doing so would be a good idea as it's impossible to comprehensively predict all the controls of the user and their associated key-bindings. I want to entirely disable scrolling, even when not done by the user.
For example, if the element contains another element with an id attribute, accessing this id (by clicking a link with href="#the-id-in-question") would automatically cause the content to scroll so that the targeted element (the one with an id) is positioned at the top left of its parent.
Another example: if the element in which we want to disable scrolling contains interactive content, tabbing through it will again change the positioning of its content.
I am thinking about using JavaScript to make a div in the parent webpage to follow the position of another element inside an iframe; the position of the element in the iframe changes when the size of the window changes (responsive design), so is it possible to make the div at the parent page change position accordingly as well? I simply don't know where to start
You can get the element inside the iframe:
document.getElementById('iFrame').contentWindow.document.getElementById('x');
Once you get the element you can work with his position, to get element position with pure javascript look this.
It's simpler to do this with jquery, but maybe with javascript it's more efficient.
After all, just position your div according to the position of the element.
How can one know if an element is in front of another element, if the overlaying element is transparent? The purpose for this is if you're artificially clicking a page element by its ID, and you're ensuring there's no overlay on top of the element that would make confirm the click as synthetic (as a normal user would have to click on the overlay).
Case 1: The overlay is a child of the clickable element To Detect it: Ensure there's no children of the clickable element that look unusual.
Case 2: The overlay has an absolute position and a higher z-index to overlay the clickable element
To Detect it: No clue! Unless you iterate through the bounding rectangles and z-index of every element in the DOM or go through the entire DOM looking for particular style attributes. That is expensive.
So, given the number of ways an element can be made to overlay another element, how can a user script detect elements overlaying elements? I suspect a very verbose method of going through the entire DOM could be avoided.
It turns out there's two ways to do this, and by this I mean two ways to find out if any given element is the top most element regardless of opacity.
Adapted from this blog post post and using their code (with some modifications) it's possible to see the top most element at any given mouse position. I modified their code to look for the computed style zIndex of any elements at a position. The downside to this approach is it's computationally costly in that you're looking at the positions of every element in the DOM more or less.
This stack question about checking whether an element is really visible on screen received an answer that linked to a browser method document.elementFromPoint which when given some screen coordinates returns the top most element, regardless of opacity but in accordance with its display style. It appears as though that function is supported in at least Firefox and Chrome.
In the end, there's two solutions to choose from, with the latter likely being the best solution in terms of reliability and cost.