Re: [css-selector] :focus and shadow host

On Tue, Mar 24, 2015 at 4:05 AM, Takayoshi Kochi (河内 隆仁)
<kochi@google.com> wrote:
> On Fri, Mar 20, 2015 at 3:20 AM, Tab Atkins Jr. <jackalmage@gmail.com>
> wrote:
>> I'm a little confused by the Doc.  It, and this email, attempt to
>> define tabStop as "basically HTML spec's 'tabindex focus flag'".  But
>> it's definitely not - your "State 2" makes this clear, because the
>> HTML spec sets the 'tabindex focus flag' when tabindex is negative.
>
> Hmm, when tabindex is negative (-1),
> I thought tab navigation skips the element,
> thus "tabindex focus flag" is false then.
> Where in the HTML spec sets the flag?
>
> (I may miss something obvious)

You're correct that tab navigation skips the element, but the element
is still focusable; you just can't reach it by hitting the Tab key
repeatedly.  The spec defines it at
<https://html.spec.whatwg.org/multipage/interaction.html#specially-focusable>.

>> I'm not sure how this explains the behavior of <input>, though.  From
>> what I understand of the Doc, you would set tabStop=true on <custom-a>
>> and the like, to make them show up in the sequential navigation order
>> even when tabindex isn't set at all.  But you're saying that to
>> trigger this case, you need to set tabStop=false, and require a
>> non-negative tabindex value.  <input> doesn't need to be auto-focused,
>> though.
>>
>
> Hmm, originaly tabStop meant to be for *shadow host*s, when authors
> want to put tab order of a shadow host via tabindex but doesn't want
> the host itself takes focus (delegates focus to its inner elements in its
> shadow tree).
>
> Without using tabStop property at all, if you don't specify tabindex on a
> shadow host,
> tab navigation behavior works as most authors expect for e.g.
> <custom-input>, I believe.
>
> Once you put non-negative tabindex on a shadow host, the host itself becomes
> focusable,
> which may not be the desired behavior, for e.g. <custom-input>.
> tabStop=false works for this case.

Okay, I understand here.  Let me rephrase just to be certain I've got it right.

If an author is making a component with internal focusable elements,
like <file-input> or something, by default it'll work "correctly" - as
you tab through the doc, when you reach the <file-input> its focusable
children will get tabbed through.  But if you set <file-input
tabindex=1>, then it's all messed up: the <file-input> itself becomes
focusable, which you didn't want; and the children don't follow it
along - they stay in the normal document-order tab order.

So you want three things:

1. A way to declare a "tab group", so all the children of <file-input>
can be repositioned in tab order together, without having to
explicitly set tabindex attributes on all of them.
2. A way to declare that an element is the "controller" for a tab
group, dictating where the group goes in the document's tab order,
without becoming focusable itself.
3. Ideally, a way to accomplish #1 and #2 that just uses the tabindex
attribute on a host element, for simplicity and compat with how
shadow-using built-in elements work.

All of this makes sense, and I agree with it.

> (I don't understand why "auto-focus" is relevant here)

Oof, I used words badly, and *also* mangled the crap out of that
sentence.  What I meant was:

"<input> doesn't need tabindex set for it to be focusable by default."

I now understand the proposal, though.  When tabindex *isn't* set on
the host, it *already* works as desired - the focusable shadow
children are tabbable as normal, in document order.  This is trying to
fix the case where tabindex *is* set on the host, which is currently
broken.

So this definitely makes sense as a goal, but I think we can do a lot
better for a proposal.  The current proposal is very unintuitive, I
think.  Maybe we can create a .isTabGroup property which gives the
desired behavior - it defaults to "false", but when set to "true", the
element is no longer directly focusable, but its tabindex moves all of
its children (that don't have their own explicit tabindex value)
around in the tab order.

>> Basically I'm pretty confused about this whole thing and how tabindex
>> and tabStop are supposed to interact.
>>
>> (Tangent: I'm also confused about how tabStop is supposed to be
>> writable, when tabindex apparently implicitly sets it as well.  Do you
>> have to listen for tabindex mutations and continually reset tabStop to
>> the value you want?  Or does it remember when it's been "manually
>> set", and stop listening to tabindex mutations?  Or something else?
>> Neither of these options have good ergonomics. :/ )
>
> That's a good point, to keep the compatibility of existing "tabindex",
> some complexity seems inevitable, though there may be better ideas.

I'm fine with some complexity, I just don't understand how it works.
The doc doesn't seem to really define how this works; it just implies
that both (a) isTabStop reflects the state of the tabindex property,
and (b) isTabStop can be manually set to a value.  These two
statements are mutually contradictory without further explanation.
If, as I suggest above, we have a well-named property for achieving
the grouping behavior, we can separate these out, and leave isTabStop
as a readonly helper property letting you know whether a given element
is a tab stop at that moment.

~TJ

Received on Wednesday, 25 March 2015 20:21:05 UTC