0

How can I make a floating panel, taller than the screen height, in an even taller page, such that the panel always remains visible, yet scrolls enough to display all parts of it?

This strikes me as similar to the more common "panel that stays in one spot", but with a bonus challenge: since my magic panel is taller than the window, anchoring the top of the panel at the top of the screen (or, indeed, anywhere on the screen) means that the lower regions of the panel can never be displayed.

There may be other ways to meet the goal, but FWIW what I envision is

  1. When the page is scrolled to the top, the top of the panel is at the top of its display area.
  2. When the page is scrolled down a bit, the panel stays in sync with it, scrolling down pixel-for-pixel—it behaves position:static (the default).
  3. When things are scrolled down far enough to expose the bottom of the panel, it pins there in the ordinary "stays in one spot" style, allowing the page to scroll down further while keeping the bottom of the panel visible and immobile—it becomes position:fixed.

I guess #2 could also be proportional scrolling, if that's possible, so that when the window scrolls down, say, 30% of its full travel, the panel also scrolls down 30% of its travel.

Concretely, suppose the page height is 1000 lines, the panel height is 200 lines, and the window height is 100 lines.

  1. At the top, line 1 of the page is at the top of the window, and line 1 of the panel is at the top of the window.
  2. Scroll down a bit, and line 10 of each is at the top.
  3. When scrolling reaches line 101 of the page being at the top, scrolling the panel to that position would move its bottom above the bottom of the window. So instead, it leaves its line 100 at top and stays position:fixed as you scroll further down.
Community
  • 1
  • 1
jackr
  • 1,407
  • 1
  • 14
  • 29
  • have you tried some code?? – DaniP Nov 01 '13 at 18:22
  • Well, I tried setting `top` to a percent, but that doesn't change the positioning logic (if `static`, it stays at 30% of the window height or whatever). – jackr Nov 01 '13 at 20:15

2 Answers2

0

You can do this with three pieces of information: the height of the window, how far the window has scrolled down, and how tall the panel is.

Simply put, have the panel be position:static to begin. As soon as the window has scrolled down such that windowScroll + windowHeight >= panelHeight, set the panel to position:fixed with its top at windowHeight - panelHeight so that the panel is moved off the screen entirely except for an amount equal to the height of the window. Edit: misread your question a little bit: don't use windowHeight - panelHeight, use the amount of the panel you want to show when the user scrolls past it.

Listen to the window's (or document's, might have to test that) onscroll event to tell you when to recalculate the panel's state. To keep IE7 and IE8 from choking (they send far too many onscroll events), either use a timeout to emulate listening to the onscroll event or deregister your listener for ~50-500ms (depending on complexity) after each calculation.

Note: getting viewport height can be a little tricky. For figuring out how far it has been scrolled, try $(window).scrollTop() or equivalent. As for the panel height, keep in mind browser differences between height, innerHeight, and outerHeight (or use a library that provides browser-independent access to this value, which I believe jQuery does).

Community
  • 1
  • 1
hilste
  • 146
  • 2
  • 6
0

This is my interpretation with your values of example based on scrollTop();

Review this demo and ask any question http://jsfiddle.net/4ZWQU/10/.

DaniP
  • 37,813
  • 8
  • 65
  • 74
  • Thanks, that was helpful. But there's one thing missing: you toggle the scrolling behavior "if st > 100", an arbitrary number. I need it to flip based on visibility. In my updated jsfiddle http://jsfiddle.net/4ZWQU/10/ you can see an attempt, but (despite my read of the documentation) clientHeight is not showing the visible-region height, but rather the total height of the data (also, and I think validly, returned by scrollHeight). Is there a way to get the height of the visible portion of an element? – jackr Nov 01 '13 at 22:31
  • yes it can be possible i use 100 only as a referent of your example – DaniP Nov 02 '13 at 02:22