*Responsive* position: fixed-like panel? - css

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
When the page is scrolled to the top, the top of the panel is at the top of its display area.
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).
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.
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.
Scroll down a bit, and line 10 of each is at the top.
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.

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).

This is my interpretation with your values of example based on scrollTop();
Review this demo and ask any question http://jsfiddle.net/4ZWQU/10/.

Related

How to control scroll bars in Angular UI Grid

I'm using Angular UI Grid in a project. The grid sizes itself so that all the columns fit horizontally in a div.
This works great, until there are more rows than fit on one screen. Then, a vertical scroll bar comes up (good), which covers part of the last column (bad). Horizontal scroll bars can be enabled to reach those last 20 or so px, but when you scroll horizontally, the header cells don't scroll. This throws everything out of alignment.
Since the grid was perfectly sized before the scroll bar, there should not be a need for the horizontal scroll bar. But the way the scroll bar covers the content means that without it, you can't see anything that might be in the right 20 or so px.
I need to fix this. Here are some solutions I have looked into implementing, unsuccessfully:
Find some way to know if there is a vertical scroll bar and add padding or margin somewhere to push in the content of both the header cell and the data cell, to keep things in alignment. I haven't found an easy way to grab the container who may or may not have a scroll bar and then I think the logic to ask it if it has a scroll bar would be brittle. Plus, just playing around with adding padding where I think it should go did not effectively push over the content.
Find a way to let the container with the scroll bar push outside of the grid when it has a scroll bar. This has basically the same issue as #1 in that that guy is pretty slippery.
Find a way to replace the scroll bar with my own. It seems that there is someone who did a branch that lets you do this with a specific library, but we are tied to a specific commit of UI Grid and adding libraries takes an act of congress.
Thoughts?
How you can know if there is a vertical scrollbar :
If you haven't customized the rows with a rowTemplate, then you might be having a rowHeight of 30px (if not please inspect).
var dataRowHeight = (numberOfRows * 30) + padding (if you have);
var gridElementHeight = angular.element("#my-ui-grid-div-id")[0].offsetHeight;
if (dataRowHeight > gridElementHeight) {
// you have a verticalscrollbar
}
Safe side : specify width for all columns by % and leave 1% behind for the scrollbar.
Ugly side : Get the width of the 'viewport', loop through and calculate the actual pixels from your provided percentage for all columns, if you detect a vertical scrollbar using the technique above, leave 15px behind.

gwt ScrollPanel in TabPanel: no vertical scrollbar

EDIT
I have fixed the whitespace behaviour by resizing components within the VerticalPanel, that seem to have had an effect on the panel's dimension somehow missed by the console. I don't quite understand how.
However, I am still stuck with none of my panels showing vertical scroll bars.
In a GWT project, I have the following structure:
Page
DockLayoutPanel
North (header)
Center (body)
South (footer)
/DockLayoutPanel
Body
SplitLayoutPanel$1
West
SplitLayoutPanel$2
North
Center
TabPanel
ScrollPanel
VerticalPanel
-Several widgets-
/VerticalPanel
/ScrollPanel
/TabPanel
/Center
/SplitLayoutPanel$2
/West
Center
/SplitLayoutPanel$1
My problems are with the ScrollPanel in the TabPanel, which in itself contains a VerticalPanel containing several widgets. This is true for each Tab in the TabPanel.
My problem is that, while the width's for all containers in SplitLayoutPanel$2's center have 100% width, the ScrollPanel contains a horizontal scrollbar with a considerable white area next to it's VerticalPanel, while they are in absolute metrics the same size.
Illustrating the situation
This is the TabPanel, with ScrollPanel, and VerticalPanel. Notice how the horizontal scrollbar exists, while the TabPanel, ScrollPanel and VerticalPanel have the same width. Scrolling to the right yields a white area.
The ScrollPanel and VerticalPanel all sport an absolute width of 598px. The West component of the DockLayoutPanel has a size of 600, so that matches. Also notice how bringing up the developer console has made the scrollbar disappear. In fact, the entire panel has disappeared behind it, and no vertical scrollbar pops up.
When scrolling the bar to the right, the VerticalPanel gets partially placed off screen, and the ScrollPanel shows this whitespace. Obviously, I don't want the whitespace to be there, so there won't be need for a scrollbar at all. All panels in this situation still have the same width: 598px. Resizing the SplitLayoutPanel, using the border to the right, increases these values (obviously), but the panels do still share equal width and the whitespace remains the same size, while I'd expect it to get wider too.
The second tab contains a load of text, which continues off the screen, but no scrollbars appear.
Problem conclusion
No vertical scrollbars
A horizontal scrollbar with some magically summoned whitespace
Compontents claim to have equal width
Any help is greatly appreciated.
EDIT
Have tried resizing the VerticalPanel to 90 or 80% width. The whitespace seems unaffected and it shows that 100% really covers the visible width and not more.
TabPanel (at least the one from GWT proper) resizes from the inside-out: its size varies depending on the size of the selected tab. So your ScrollPanel will never have a vertical scrollbar unless you explicitly give it a size, and your content is actually overflowing the layer of the SplitLayoutPanel you put the TabPanel in.
Layout panels, such as TabLayoutPanel, on the other hand resize from the outside-in: the SplitLayoutPanel would set the size of the TabLayoutPanel in its center region, and the TabLayoutPanel would in turn set the size of the ScrollPanel, so if the content of the ScrollPanel overflows, a vertical scrollbar appears.
First Point : Don't mix and match layout panels and non - layout panels.
Second Point : If you want proper resizing and scrollbars, always try to mention width and height in percentages.
I see that you have mentioned width to be 100%. But what about the height?
What I suggest for you is,
Change TabPanel to TabLayoutPanel
Set all the panels height throughout the heirarchy as 100%

Div popup alignment

I'm using a "homemade" php calendar in my site's right sidebar. The site's body is a fixed 1000px. When a day on the calendar with an event scheduled is hovered over, a div shows up that gives details on that event. Here's a visual representation:
The problem here is that the event box usually exceeds the boundaries of the body. On smaller monitors, the box extends past the right side of the screen and cannot be read. I tried having it fall to the left instead of the right, but this covers the main text area and looks odd. Is there anything I can do to make the box fall to the right, but if required (viewed on a smaller screen), be pushed to the left? Similar to a float, I guess.
Thanks.
Edit: Sorry, I forgot to mention the way I'm making the boxes show up. It's entirely CSS-driven. The containing element is positioned relatively, and the boxes are absolutely positioned. They're kept off-page (left: -9999px;) and show up upon calendar cell hover. This process seems to be snappier. Therefore, positioning the element to avoid this problem is not possible.
I don't want the box positioned to the left of the cell. I want it positioned to the right unless otherwise required due to a visitor's screen size.
For Javascript:
Check for the size of the document (to find the right most pixel)..
Check for the right most pixel of the box
Subtract box.right from document.right and move box left by that amount
For CSS:
Make the position of the box absolute and right: -10;
This is more a CSS / Javascript question.
First way: assign {position:absolute; right:0} to the popup div and {position:relative} to the containing div, so it will be floating to the left all the time.
Second way: use javascript / jQuery to calculate the right edge location of the popup div, modify the left if the div is going to poke out of the edge.

Avoiding nested scrollbars

I'm hoping someone can suggest a UI that I've actually never seen used.
I've got a lot of data that needs to be displayed in a fixed height scrolling div and to make it more palatable, the client wants sub-data to be displayed in an accordian div that can be expanded and closed.
The problem is that the sub-data is also potentially lengthy and requires a fixed header so that the user understands what's in each column. Please see the fiddle: http://jsfiddle.net/J5qFA/34/
You'll have to use your imagination a little, but consider the grey bars as headers on expandable divs and the one labled as "Expanded" is a header that's been clicked, showing its contents. (Note that expanding one header toggles closed any open div.)
The black bar is the data header and the yellow content is the data.
Is there a way to make the black bar "stick" to the top of the scrolling window so it's always visible when the user navigates down the yellow content? Note that it shouldn't appear over the top of any grey headers, so only needs to stick to the top of the scrolling window if the user scrolls down to see more yellow data.
And if not, is there a better way to ensure that the black header is always visible above the yellow data?
Oh, and I don't want to nest scrollbars, obviously!
Hope this makes sense!
Give the yellow data div a fixed height and overflow-y:auto.
http://jsfiddle.net/J5qFA/35/
ive also remove overflow:scroll on the outer
Well, Don't know if there is a better way, but one way (I would think of) to do it is using jQuery scroll, than attaching the black bar classes according to the position of the screen using window.pageYOffset and window.scrollTo(0, y).
I guess you might have 3 cases:
The black bar is under the top of the screen - show it as usual.
The black bar is above the top of the screen, and it's div is is the screen - use position: fixed;
The black bar is above as well as it's div - same as 1.
sorry, but I don't have the time now to write the code up but if you'll choose to do it this way i'll be happy to help.
Good luck anyhow!

scrolling to bottom of fixed positioned div

I have a fixed position side tab on my page that contains filtering options for the user. When there are a lot of options, the side tab gets too long and the bottom goes beyond the bottom of the page, where it is impossible to view.
Is there a way to have the whole page continue scrolling to the bottom of the side tab div? I don't want to put scroll bars inside my side tab div, even though that would be an easy fix. I just want, when the bottom of my div butts against the bottom of the page, to bring the whole div up with it so that the bottom content is visible.
I am limited in that I can't use jQuery in this particular application. I can, however, use Dojo.

Resources