- From: Thaddee Tyl <thaddee.tyl@gmail.com>
- Date: Tue, 22 May 2012 15:17:13 -0700
- To: www-style@w3.org
A common pattern in the web is to use `element.scrollIntoView()` to show that element in the context of the web page. However, the design of scrollIntoView puts that element either at the very top or at the very bottom of the viewport. In most cases, web authors want to center that element. As a result, there is great duplication of code to make that work, and scrollIntoView gets rarely used, except for quick and dirty implementation of a search functionality. I suggest a solution to that in the following bug, copy and pasted below. All feedback is warmly welcome! https://www.w3.org/Bugs/Public/show_bug.cgi?id=17152 --- The main reason why we might use `scrollIntoView()` is to bring an element into the viewport. However, showing that element at the top or at the bottom of the viewport is detrimental to understanding the context in which this element is. As a result, what authors really want is to center the element. I know we are implementing that in JS again and again throughout Firefox, and web developers are, too. Webkit has a method called `void scrollIntoViewIfNeeded(optional boolean center);`, which scrolls the page so that an element, if not completely shown, becomes completely shown, and appears vertically centered in the viewport if the boolean is true. The reason I bring this method up is to highlight its bad design. 1. Boolean flags are unreadable: it is unclear from reading `scrollIntoViewIfNeeded(false)` what that `false` means, and even if we know that it is about centering the element, which one, of `true` and `false`, does indeed center the element. 2. We already have `void scrollIntoView(optional boolean top)`. Having many methods whose intents are collinear is wrong. Different methods should have orthogonal goals. I therefore suggest the following addition: partial interface Element { void scrollIntoView(ScrollPosition options); }; dictionary ScrollPosition { float top = 0.5; float left = 0.0; boolean notIfViewed = true; }; where `top` and `left` are meant as percentages of `max(0, scrollY - element.clientHeight)` and `max(0, scrollX - element.clientWidth)` respectively. If `notIfViewed` is true, and the element is completely in the viewport, then this method does nothing. If `notIfViewed` is true, and the element is partially hidden, then scroll just enough so that the element appears completely in the viewport. In all other cases, scroll so that the element is positioned at `options.top * max(0, scrollY - element.clientHeight)` with respect to the top border edge, and at `options.left * max(0, scrollX - element.clientWidth)` with respect to the left border edge. Overloading of `scrollIntoView` happens as described at <http://www.w3.org/TR/WebIDL/#idl-overloading>. An intended effect of this design is that calling `element.scrollIntoView({});` automatically does the right thing and centers the element on the screen, while you can still get the old behavior by calling `element.scrollIntoView()`.
Received on Tuesday, 22 May 2012 22:18:02 UTC