- From: Glenn Adams <glenn@skynav.com>
- Date: Tue, 22 May 2012 22:41:34 -0600
- To: Thaddee Tyl <thaddee.tyl@gmail.com>
- Cc: www-style@w3.org
- Message-ID: <CACQ=j+cbuZnSmzg2er1s4isUURtBYeA8+-6HeDejczijNRg-Rg@mail.gmail.com>
On Tue, May 22, 2012 at 4:17 PM, Thaddee Tyl <thaddee.tyl@gmail.com> wrote:
> 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()`.
>
while the intent of your proposal seems good, the details would need
tweaking, and general buy-in and implementation support would need to occur
before adopting; a couple of quick comments:
- creating a new type ScrollPosition may be over-design, when a simpler
signature may suffice
- using top and left as ScrollPosition values is western writing system
centric, and may need to be relativized to handle rl-tb and tb writing modes
Received on Wednesday, 23 May 2012 04:42:46 UTC