I'm developing a web interface involving a JavaScript scrollbar restyling solution that attempts to hide the browser's default scrollbar behind an HTML/CSS replacement, while preserving support for the browser's default scrolling behavior, a feature many popular JS scrollbar plugins lack. The only issue I've encountered with this method is that some browsers insist on displaying the default scrollbar on top of the one created by the plugin, destroying the desired aesthetic altogether.
In an attempt to solve this problem, I tried wrapping the element containing the scrollbar in a div with overflow: hidden; and using JS to detect the width of the default scrollbar and position the element it controls so that it falls outside the clipping boundary of the parent div. However, as many of you probably know, Content that spans beyond the bottom or right boundary of an element with overflow: hidden can be accidentally scrolled into view during mouse dragging operations like text selection in which the course crosses the bottom or clipping boundary of the concealing parent element (i.e: dragging to the right would bring the default scrollbar back into view).
Luckily, though, this behavior does not occur when content extends beyond the top or left boundary in such a scenario. Knowing this, I'm considering continuing with the approach outlined above, but styling the scrolling element with direction: rtl to flip its scrollbar from right to left, and beyond the boundary of the concealing element, then applying direction: ltr to the child element containing all of its contents to negate the direction change for all of the actual content.
This technique produced the desired result in every test I've conducted thus far. However, I'm wondering if this solution is too good to be true, and I'm overlooking a fatal accessibility and/or compatibility issue with CSS direction for scrollbar placement that should prevent me from using this method.
TL;DR: Is using the CSS direction property to control the position of an element's scrollbar a bad idea?
In terms of correct usage of the property, it is a bad idea. direction: rtl is correctly used to flip the reading direction of text using alternate character encoding e.g. Arabic, Hebrew, etc. Try and find another way around the issue. Try taking a look at the source of some of the aforementioned popular JS scrollbar plugins to see how they do this.
Related
TinyMCE floatpanels (mce-floatpanel) and tooltips (mce-tooltip) are set as children of <body> with position: absolute. I understand the necessity with regard to z-index etc, but it also creates a problem with scrolling in certain circumstances.
If TinyMCE is the child of a container which scrolls, the menus and tooltips become unmoored. For example:
A <div> with height: #px and overflow: auto → jsbin
A <div> with position: fixed → jsbin
I've seen the following two solutions suggested:
To specify the editor float elements' container, as in these TinyMCE issues:
Dropdown panel is not properly affixed
How to change floatPanel's parent?
To close or hide the menu by manipulating the DOM onscroll or onmouseleave etc, as in this SO answer
Specifying the editor container is seemingly not yet available.
The trouble with the second suggestion is twofold. First, it feels hacky and has hard to account for edge cases. Second, I'm using react.
The React component doing the scrolling is far up the hierarchy, with hundreds of descendants. Monitoring scroll from there with the onScroll SyntheticEvent works, but scroll event fires extremely rapidly, including during initialization as data loads into sub-components altering their size.
I don't know where to go from here. Any help is greatly appreciated.
It turns out specifying the UI container is somewhat available, as an undocumented feature, as requested in this bug and implemented in this commit. This is not the solution I hoped it would be, having various unexpected side effects and bugs.
At this point I'm considering bypassing React entirely and monitoring the DOM directly for scroll events from the TinyMCE wrapper.
I am doing some VoiceOver experimentation with scrolling (the three-finger swipe up/down gesture).
My test page is at:
http://107.170.41.208/AccessibleHTML
There is a div with a scrollbar and lots of content (red background), and after that another div that is not scrollable with a lot of content (yellow background).
With the mouse I can scroll through the red background content, but using VoiceOver it skips that section.
How can I scroll through the red section content with VoiceOver?
A little late to the party but hopefully it's still useful to people.
Using position: absolute can sometimes cause some issues for screen readers as the DOM layout might not match the visual order. The VoiceOver can sometimes take the decision that it wouldn't make sense to read that first (or at all).
In that specific case you could just set the required height on the "red" <div> with overflow:scroll and it would be fine and should be readable and scroll-able.
As a more general rule, try and keep the visual order consistent with the DOM order, using float sparingly to change the layout slightly.
There obviously are rules somewhere dictating how and why this happens but they are tied up in Apple's code and very changeable between releases.
I am trying to find the top and left coordinates of a background-image that by applying some CSS rules has been shifted off the viewport. Difficult to explain in words, here is a visual example:
Black box: Viewport
Red box: <div> with a background-image
Blue box: <div> containing an <a>
When I do getBoundingClientRect of the <div> with the background-image, I get 0px 0px. It makes sense, because the container is within the viewport, and it starts at the very top and left.
However, the background-image of that <div> has been shifted to the left (and it could have been shifted to the top too), and therefore the coordinates should differ from the ones from the <div>. So my question is:
How would I READ (I don't want to change) How can I find the coordinates of the green point in any page that is facing this situation? I mean, the browser must have known how many pixels it needs to cut the background-image, right?
I am currently using Javascript to access the Web/Dom API. I am willing to use anything (undocumented maybe?) to achieve this.
Here is a solution to your problem that works on modern browsers.
var testNode = document.getElementById('test');
var testBackgroundPosition = getComputedStyle(testNode,null).backgroundPosition.replace(/px/g,'').split(' ');
As you can see from the following page not all web browsers support this method.
http://caniuse.com/getcomputedstyle
There is no answer to the "Cross-browser (IE8-) getComputedStyle with Javascript?" question yet and I don't know another solution to this problem.
Without getComputedStyle() there is no reasonable way of getting the current style settings for an element since that requires going through all of the included CSS. It is possible but involves CPU intensive code. If you were to go that direction you will be able to create a temporary div inside the existing div with relative positioning, possibly setting top and left, or margins, to the values from the background position and then calculate where the div's clientTop and clientLeft ends up which may work in some cases.
There is a css property for that: the background-position. Try the following code to retrieve the information asked for:
$('#divId').css('backgroundPosition');
I have been trying to understand how they did those effects in http://artofflightmovie.com/ with no success so far. I am not even sure what to google for for help. Could any one ellaborate on it and perhaps put links to plugins\tutorials\other websites doing the same thing?
There is already a similar question, but it didn't help me a bit ^^
Custom scroll bar behavior in Javascript?
All of the answers here so far are spot on and cover various pieces of the execution. Joseph's post about how we 'contained' and 'maneuvered' the site are dead-on, and those mentioning jQuery accurately depict our heavy reliance on it :)
With that said, the other concept of moving along a non-linear path was probably the most difficult part. We literally used an Illustrator file that was setup like a piece of graph paper and drew a bezier path that reflected the movement we wanted from the scrollbar. Then we 'downsampled' the path by converting the curved lines into a bunch of straight lines that represented the curve (similar to downsampling audio waveforms) to keep performance/speed high. We took those coordinates, gave them to our designer, and he created a gigantic design file and literally designed each content section at the designated 'stop' points. Next we mapped each coordinate along the path to a percentage value of the scroll position. We stored these values in a JavaScript array. Lastly we wrote some JS functions that we pipe the scroll position through to determine how to offset the positioning of the site 'container'. (It basically 'tweens' between each coordinate allowing us very fine/precise values at any given scroll percentage) The scroll functionality is handled by a tall div that basically sets our document height to force a scrollbar, and we just read it's position during a Scroll Event and slide the container around to where it should be using the above mentioned functions.
The parallax effect is achieved by applying a percentage of the position offset (what we use to move the container around) and applying it to the sub-containers of the various content sections. This makes the subcontainers move slower or faster than the background, but on the same motion path.
Lastly, the little snowboarders and helicopters (which have CSS3 rotations in addition to x,y movement in some browsers!) are positioned by using a simliar array of 'start' and 'end' positions and tweening between them based on the scroll percentage.
I'll leave it at that to keep this from turning into a book, but I'd be happy to elaborate on specifics if you're interested.
Full disclosure: I was lead developer on the site. I'm not posting to 'toot my own horn' or anything like that, just to be helpful and provide assistance to a fellow tinkerer. I come here a lot to dig through and get insight from others. (many, many thanks to those who have helped us!) Also, shameless plug, but the film is breath-taking... go rent it if you haven't yet, you won't be sorry. :)
That's a pretty cool website ;)
Basically using some javascript you can detect how far a person has scrolled. Considering the amount of scrolling you can move the contents of your webpage around if their position is absolute.
There are a couple of jQuery plugins that allow you to do simular stuff although I'm not sure you can "scroll through" a sequence of coordinates.
Here are a couple of jQuery plugins that helps you get simular effects:
http://johnpolacek.github.com/scrolldeck.js/
http://johnpolacek.github.com/scrollorama/
http://demos.flesler.com/jquery/scrollTo
http://webdev.stephband.info/parallax.html
I just picked a couple I'm familiar with but there are many plugins that are alike.
edit:
Decided to add some more simular websites for your pleasure.
http://www.activatedrinks.com
http://www.beetle.de
http://www.nikebetterworld.com
the whole page is an "overlay" - a full width and height wrapper <div>. sort of how modal windows do their "full page shadow" effect and have a small div float inside. the whole page content is in that wrapper. the scroll path is a script. the script captures the body scroll and moves the contents of the div accordingly to the positions provided by the script. with a body long enough to be scrollable (which cannot be seen since the wrapper covers the whole page), it's as if you are scrolling sideways, upwards etc.
an analogy is a modal window. the wrapper is the full-page shade. the modal window is the content. and notice how modal windows stick to the middle? that's using a script to calculate it's position to stay in the middle by moving the modal window down, relative to the page's top. but in that website's case, they move in different directions.
It doesn't seem too complicated.
Using the .scroll(function() {}) in jQuery you listen for a scroll event. When triggered you set the position style (left, top) of the content div to give the appearance of moving sideways instead of down.
I guess you'll need overflow:none property on the div to prevent users from scrolling over the area you don't want them to see.
Sounds like a lot of effort for a clunky user interface in my opinion.
After googling around and finding a lot of ie bugs I still did not find a description of the problem I have.
The initial situation is a standard one. We have a tooltip which is actually a hidden div that will be displayed on mouseover at a given location. The div is hidden with display:none and contains a table with the content. We tried different libraries for showing the div (scriptaculous and jQuery Cluetip) but the effect is the same.
The problem:
Everything is fine as long as the contents fits the width of my window. But when I resize it until the horizontal scrollbar is activated the content of the hidden div will be shown at the end of the page when the tooltip is activated.
This is really strange as it happens only under these premises. When more than one tooltip is involved the browser might even crash (and under Vista takes the whole system with him duh).
I know it's a bit complicated to explain but I hope that someone at least had heard of that bug and can point me into the right direction.
Setting the width css property to "auto" (defined in the W3C standard) in IE will cause the <div> element to take up the entire space allotted to it. If the <body> element does not have a width applied, then this can result in a page miles and miles wide. This often crashes the browser, depending on the operating system. The best option is to just set it to null instead.
(This is based on actual experience coding for IE6 and may not necessarily apply to IE7+).
Another thing to keep in mind is that most browsers do what's called "lazy rendering" which means that if an element is hidden on the page, it won't render it. It won't even acknowledge its existence as a potentially visible object until it is unhidden. This means having no idea how big that object is going to be until you reveal it. This can cause problems if you're trying to figure out how big something will be once you make it visible. Basically the only way around it is to unhide it, read its size, re-hide it, then proceed.
The way that I did my tool tip is to use visibility hidden and visible. Once the mouse is off, I set the x and y to 0 to move the tooltip out of the viewing space.
This only works if the position is set to absolute.
Edit: How did you position the tooltip when showing it:
I positioned the tooltip by changing the css values of "top" and "left".
box.css("left, e.pageX+1);
box.css("top", e.pageY+1);
Where 'e' is my event variable from:
mousemove(function(e){});