In html if a child div is bigger than the parent div it will create scrollbars on the parent div if you set the appropriate style rules.
However, I want it so that when an attempt to scroll occurs (by hitting the arrow keys, making the appropriate javascript call on the element) the minimum needed expansion in size occurs on the child occurs such that it can scroll to the degree that it would have scrolled anyway if the child was already that big.
To state that again: if the child was 300px width within a parent of 200px width, and I hit right arrow key, and it scrolls 20 pixels to the right, then if the child is 200px in that same scenario, I want it to enlarge in width by 20 pixels and no more if possible, and then scroll 20 pixels to the right.
This is all assuming there is no way to make a sub-element scroll within its parents regardless of whether it's actually larger than its parent. There might well be so I apologise in advance if i haven't done enough research. :)
You probably know that the style overflow: scroll will make scroll bars show up regardless of child size. Do you actually need Javascript to boost the child dimensions, rather than having an extra wrapper div with greater dimensions that would cause the scroll like in this demo? I know Safari already scrolls approximately 20px on arrow key down within selected scroll divs by default, and I would assume other browsers have this functionality as well.
If you do have need for increasing the div size with javascript, jQuery has a few functions that would be helpful. The .keydown() method looking for left and right arrow keys (which I believe are key codes 37 and 39 respectively) and the .animate() or some other CSS method would work to resize the div chained together.
The .scroll() method could come in useful as well. You could chain the resize code to the scroll method with an overflow: scroll property already applied. I would test to see if browsers will trigger the .scroll method even if the scroll bars are empty. If not, you could potentially make the child only 1px wider/taller then the parent div and then rely on the jQuery to further resize on the user's scroll.
Broadly speaking, I would advise against the javascript/jQuery resize and scroll. Compatibility with different browsers, especially mobile browsers, would be inconsistent or unusable. I don't know exactly what your needs are, but if it can be accomplished with only HTML/CSS it would be much cleaner and more compatible. I would reserve the javascript for cases where usability will not be lost if it does not run.
Related
Now I’ve seen this page from webflow, which has inspired me much.
In this page, you start scrolling horizontally, then when you reach a certain area, the scrolling direction changes so that the page starts scrolling vertically.
Is there a way to do this?
(Preferably vanillaJS, but jQuery would be fine)
Basically there is not a set-up solution built into standards or jQuery (and I don't really recommend to use jQuery). I haven't searched if there is a library to do this (I suspect there is, and you should use one if possible instead of building by hand) but I'll try to roughly explain what it uses in vanilla JS/CSS.
We can construct a really long element (that includes the contents you want to reveal by scrolling), and use some cropping mechanism so that only a portion of it is displayed. This is basically done with overflow: hidden;.
Next this long element should move with scrolling. Adding an onscroll event listener that adjusts the transform property (spefically, translate functions) would do that.
These element should behave magically: they scroll to a position, stop and stay there until they reach another scrolling position, where they continue to be scrolled away. This is accomplished with the position: sticky; CSS property. See what MDN says:
The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), including table-related elements, based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements.
This is somewhat hard to understand but the key is that it stays where it is as if it was a normal element until reaching the position you have set through top/bottom/left/right properties. Then it stays at that position until it's scrolled away together with its parent element (the "nearest scrolling ancestor").
So now you have an element that
Is really long but has only a portion shown
Can move as mouse scrolls so that users see more as scrolling
Stays in a fixed position through a part of the page and then scrolled away
which is basically the effect you want.
These three steps are the basic building blocks of such fancy effects you mentioned. There should be of course many nasty implementation details that I haven't outlined here but I hope this answer help you briefly catch what's happening under the hood.
I have a div with its own scrollbar using the overflow: auto property.
With this div I display a table. For some of the rows I would like to display markers on the scrollbar of their positions within the div.
At the moment I am calculating the position of the desired rows I want to mark within the scrollbar by subtracting the offsets from the parent div, and then I am creating div with their fixed position
With the newly created div, how do I display that position on the scrollbar rather then in the div or is it even possible to add fixed divs on the scrollbar?
There's really no good way to do this. The scrollbar created by overflow: auto is a bit of a weird beast: its size and metrics are dependent on the browser and OS, and cannot be reliably detected by Javascript.
(For example, the scrollbar on most Windows systems will have "buttons" at the top and bottom, but the Mac OS scrollbar does not; this changes the positioning of the scroll thumb for content, as it affects the overall length of the scrollbar. In fact, the Mac OS scrollbar is invisible by default on many systems, so attempting to position content over it will look rather strange!)
About the only way I can imagine going about this would be to forego the native scrollbar entirely and use a Javascript-created standin, but those tend to have wonky behavior that will piss users off. Unless this feature is extremely important to you, I'd be inclined to write it off as impossible.
I am lacking of a better term to describe this UX. It is basically a content container that is scrollable. Depending on the scrolling position, the top or bottom edge of container would light up (or change style) to indicate there is content at either of the direction. For example, when you go to Yahoo.com, and scroll down a little, the top edge of the scrollable section would turn purple, indicating there is content at the top that's outside of the viewport. (See image below)
I wonder if there is already some well known script library that can achieve this so I don't have to reinvent the wheel.
This is a fairly custom concept, but you can see how to get started by looking at the way Bootstrap's Affix method works: http://getbootstrap.com/javascript/#affix
Essentially you will need to have a scroll event listener which tracks what the position is that a user is scrolled on a container. When the scroll position reaches certain breakpoints, the listener function will trigger CSS classes which may do a variety of things.
I'm having a little trouble getting my head around a Javascript animated scroll issue.
I'm using the SuperScrollorama Jquery plugin which is built on-top of the Greensock JS tweening library.
The fundamental effect I'm after is to "pin" a section down, then use vertical scrolling to expand some content, then "unpin" the section once the content is fully expanded, so the user can scroll on - i.e. http://blueribbondesign.com.au/example/
But when I try to apply this same effect to multiple sections one after the other, everything gets all broken: the "unpinned" content below the pinned element is pushed off screen and it seems to miscalculate the height of the element when it performs the animation in reverse (i.e. scrolling back up the page). - i.e. http://blueribbondesign.com.au/example2/
I've been endlessly fiddling with the "position:fixed" and "pin-spacer" div, and tried attaching the Superscrollorama plugin to various containing elements, but still cannot work out how to get it to work.
Any help from the brilliant crowd-sourced minds of the web would be much appreciated,
Cheers,
TN.
I've been working with this issue myself. What happens is there's a blank div spacer put above the section being pinned with a height that you've defined in the pin() function. Secondly, the pinned element gets a position:fixed assigned to it. Both of these things allow the scroll bar to continue down the page while the element stays affixed. In turn, whatever you had below that section gets bumped down because of that spacer div's height.
If your pinned element is centered horizontally, first give it a left:50%, margin-left:-{width/2}px to fix it from pushing to the left edge.
Next, you'll have to detect the pin/unpin events (which are offered by the plugin as parameters additional to "anim"), and change the section underneath to also toggle a fixed/relative position. When you change that underlying section to be at a fixed position, be sure to set its "top" property to whatever the pinned element's height is. Once the pinned element becomes unpinned, change it back to relative positioning. Does that make any sense?
It seems that different techniques will call for different fixes, but those things are what I'd pay attention to... fixed positioning, and then using the pin/unpin events for adjustment.
I'm building a web app that has a grid of many small scrollable divs (actually, Ace editors), and this grid has enough elements that it is larger than the window. When a user begins scrolling over empty space, I want them to be scrolling the window itself; when a user begins scrolling inside a grid element, I want them to scroll the div contents there. The thing is, if a user begins scrolling over empty space, and then scrolls such that their mouse goes over a grid element, that scrollable div captures all the scrolling events, interrupting the user's flow over the grid and "trapping" them inside the grid element.
I can't manually capture onmousewheel events, since AFAIK there's no way to capture horizontal mouse wheel movement separately from vertical, and I want users on Mac OS X to be able to scroll in all directions. I've thought about using JS to add an invisible div with a very high z-index on the first onscroll event, and removing it as soon as onscroll events aren't triggered for a certain period of time. Haven't yet coded this up, but I'm wondering if there's a better solution, or if there are any potential pitfalls that I haven't thought of. Any help or advice would be great! Thanks!
I think a solution for this would be incredibly difficult due to browser support, and the actual solution, which would probably be something like calculating the scroll, backtracking the div, and applying the scroll to the page.
You could do something like this:
$('div').scroll(function(e){
// figure out how much it has scrolled
window.scrollBy(0,howmuch);
});
I don't recommend this solution in the slightest though, I think the better option would be to set the divs to overflow:hidden; and pick up a solid scroll plugin, and use that to customize the scroll behavior on the divs.