WICG / spatial-navigation

Directional focus navigation with arrow keys
https://drafts.csswg.org/css-nav-1/
Other
216 stars 38 forks source link

[css-nav-1] Revise selecting best candidate policy #94

Closed junhoseo closed 5 years ago

junhoseo commented 6 years ago

Currently we consider distance and order in DOM structure. But sometimes these are not sufficient for reasonable choice.

Case 1: image

In above case, distance with active element is same each other. So blue element will be selected if it is earlier element in DOM tree, and yellow element will be selected on the contrary.

Case 2: image

image

Sometimes a focusable element can be placed inside another focusable element. In this case, should we allow focus moving to opposite element? Opposite element is not placed in direction, but partially.

jihyerish commented 6 years ago

Case 1.

Yes. The focus will move depending on the DOM order if the candidates have the same distance from the active element. So far, I think it's a reasonable result. But in some condition, it would be nice to consider the visual inclusion relation among the elements.

Case 2.

In that regard, we need to consider the visual inclusion relation in this case. If you see the sample below, https://wicg.github.io/spatial-navigation/demo/sample/heuristic_text_type_elements.html image

The content area of the (A)anchor element with "spatial navigation" contains that of the (B)anchor element with "repository". This causes that the focus cannot move from (A) to (B) nor from (B) to (A).

junhoseo commented 6 years ago

For case #2, and minimizing unreachable case, I suggest an additional step 'internal search' in processing model. Let's see following scenario.

image

In this scenario, currently red color element is active element. 3 elements are children of a container element(blue color). Meanwhile, there is green element and it is (visually) inside active element. And let it is not child of the container. Usually, such green element never gets focus because it is encapsulated(In this scenario, green element can get focus through yellow element. But it is introduced to show an important case.). And we hit down key.

For now, let's see how 'internal search' step works.

image

In internal search step, valid rectangle is defined. It is rectangle of active element, and limits focus candidate. Also we define starting point as edge of active element. In this scenario, only green element is candidate for getting focus in internal search step.

Important different point between internal search for active element and finding in container is, in case of internal search, candidate should be 'fully' inside of valid rect. But, in case of finding in container, partially visible element can be candidate. This is why yellow element can't be candidate.

I think we can integrate this step with existing processing model.

For each container from active element's nearest container to root container
    if internal search step finds a candidate
        stop loop

    if normal step finds a candidate or scroll
        stop loop

So, let's see, how integrated processing model works. In first iteration, container is blue element. In this iteration, we can't any candidate(or scroll) in neither internal search step nor normal step. In second iteration, container is root element. In this iteration, green element can be candidate in internal search step. So we give focus to the candidate and stop loop.

hugoholgersson commented 6 years ago

Usually, such green element never gets focus because it is encapsulated

The problem is that spatnav only looks outside of activeElement's visual box, right?

Also we define starting point as edge of active element.

Perhaps this is all we need to do (no need for an extra "internal" step)?

I wonder if we ever need to use the complete "focus box".... Perhaps edges as search origin give good enough approximations for most (all?) distance calculations?

junhoseo commented 6 years ago

The problem is that spatnav only looks outside of activeElement's visual box, right?

Yes. Spatnav looks outside of activeElement, also looks partially insersecting element. But never looks inside element.

Perhaps this is all we need to do (no need for an extra "internal" step)? I wonder if we ever need to use the complete "focus box".... Perhaps edges as search origin give good enough approximations for most (all?) distance calculations?

I think using edge as search origin in common cases can minimize unreachable problem. But it maybe reduce intuitiveness. For example, in above scenario, left(apricot? color) and right(yellow color) can be candidate when we hit down key. It looks like such elements are not placed in direction. Of course, it depends on the person. What do you think?

hugoholgersson commented 6 years ago

For example, in above scenario, left(apricot? color) and right(yellow color) can be candidate when we hit down key. It looks like such elements are not placed in direction. Of course, it depends on the person. What do you think?

Yes, they can, which is good. All visible focusables in the direction, down, should be considered candidates. The green focusable will anyway win because it's closer to activeElement.

junhoseo commented 6 years ago

:) OK. So this is more harder example :) :) :)

image

Focusable elements are placed as grid. And red color element is active element. We hit down key again.

I think most people expect yellow element will get focus. But actually, green element will get focus because it is placed in direction and closest element with red element. How we can resolve this problem when we use active element's edge as starting point in common cases?

hugoholgersson commented 6 years ago

I agree. :) I get your point...

One alternative could be to prioritize elements that are fully aligned (i.e. elements that can be [partly] projected onto each other)...?

frivoal commented 6 years ago

I think the suggestion in https://github.com/WICG/spatial-navigation/issues/94#issuecomment-425004503 is actually quite good. Should we write it in the spec first, or first try to implement in the polyfill, try it to see if it is nice, and update the spec only if we like it?

frivoal commented 6 years ago

For case 1 in https://github.com/WICG/spatial-navigation/issues/94#issue-351959505, I am much less sure what the order should be if not the DOM. The one most in front? The largest one? The one with the largest visible area? I am not 100% sure how to decide which answer is best.

frivoal commented 6 years ago

I think there are several issues being discussed at the same time in this one. Separating them into sub topics:

As for the rest, which I think is best described in https://github.com/WICG/spatial-navigation/issues/94#issuecomment-425004503, I think I was actually confused when I said I agreed. In https://github.com/WICG/spatial-navigation/issues/94#issuecomment-425004503, if the green box is in the same container as the other boxes, the specification already handles that. However, if it is not in the same container, then it seems that skipping it is a feature, not a bug. That is what containers are for. If that's not desired, then making the "blue" box in that example a container seems like a mistake.

Is there any situation where we would want the blue box to be a container, but still go from red to green?

junhoseo commented 6 years ago

Hi @frivoal,

if the green box is in the same container as the other boxes, the specification already handles that.

Would you please explain how spec handles?

Is there any situation where we would want the blue box to be a container, but still go from red to green?

I found a case: image

In above case, a link "arrow keys" is placed in two lines. So the layout box of the element will be red box. Meanwhile, another link "modifier key" is placed in red box. So in this case, we hardly navigate into "modifier key.

junhoseo commented 6 years ago

I found a case:

Oh, the case is already noticed by @jihyerish at https://github.com/WICG/spatial-navigation/issues/94#issuecomment-418079301 :)

frivoal commented 5 years ago

Issue migrated to w3c/csswg-drafts#3386