Re: [css3-selectors]: Proposal: :in-view() selector for better visibility control

On Tue, Dec 6, 2016 at 10:40 AM, Alexander Shpack <shadowkin@gmail.com> wrote:
>>
>> This is the solution that everybody reaches for when they're
>> suggesting something circular, and unfortunately, it doesn't work. ^_^
>>
>>
>> Not applying any other styles would in most cases totally break the
>> page's styling.
>
>
> Wait, wait. It's not a "not applying". It sounds more like work with a
> current snapshot, not with a live DOM tree. Don't return the result of style
> applying to the source list for the selector. Like a versioning in RDBMS on
> selects.

This then ends up being super-complex and unstable. I'll explain further below.

>> You can't even just limit it to the elements getting
>> styled by that rule, as their sizes/positions can be affected by other
>> elements on the page.  It also breaks the fundamental model of CSS,
>> that it's a declarative model and ordering has almost no effect.
>
> :hover can produce loop and it's ok. My proposal can produce the same loops
> and it's bad. No, bad is not enough, it's BAD.

No, I didn't say :hover was "ok". It's not great, and we don't want to
repeat it's mistakes.

Important to note, too, is that :hover is a "loose" loop - it can't
trigger a loop-back until the next user input even is received, well
after styles are calculated, layout is performed, elements are painted
on the screen, and scripts (both JS and in-browser) get to run.
Loops, thus, are just visually annoying, not troublesome from a
theoretical standpoint.

This suggestion, tho, is different - it's a much "tighter" loop,
detectable as soon as layout as performed.  This means that, if we
want a consistent page, we have to go back and recalculate styles as
soon as we do layout, before we even get to paint anything.  Loops
here are equivalent to a infinite loop in JS code - it prevents the
browser from doing anything unless you kill the page.

So, you might say, let's break the loop!  :hover actually gets this
treatment too - browsers will usually not re-check :hover styles until
the cursor actually moves; this prevents pages from wiggling
underneath you when you're just scrolling with a mousewheel or
touchpad, and also happens to partially defeat the :hover loop - once
your mouse stops it freezes on either "hovering" or "not hovering",
somewhat arbitrarily.

But that doesn't work for this suggestion. The :hover loop is based on
user interaction, and is "local" to it - the :hover styling happens
when your mouse gets close, and gets updated when your mouse moves
near it; if your cursor moves further away, the loop stops.  For
in-view styling, we theoretically have to re-check any time *any*
styling is updated *anywhere* on the page, in case the new styling
moved or resized the element in question.  Have an animation running
anywhere on your page? Every in-view element might be looping.
There's no stability at all; you've just pushed the loop out to be a
little looser, but haven't stopped it.

This is why, as a general policy, any pseudo-class based on styling or
layout is verboten.  They just don't work, even if you apply
expensive/complicated interventions (which this sort of "snapshot"
suggestion is).

> Guys, let's take away from your heads browser development mind and look on
> the problem as a web developers. We would like to control elements that are
> located somewhere in or out of viewport. Popup has flown out of viewport? I
> would like to return it back and make it fully visible without scrolling.
> Animation should start when box appears on viewport? Easy! So, how can I do
> it without JS? No way. I must to be tormented... Possible loops? I don't
> care. I can shot my leg in thousand ways. So what? Millions of developers
> will kiss you for this feature. :)

I'm only *barely* a browser dev. I write specs, and I write webpages
(for personal use now, but previously as my job); I just happen to
have 20 browser devs within a hundred feet of me. Trust me when I say
that I understand your desire here.

It just doesn't work in CSS.  The timing is wrong.  The only way to do
it that has the right timing model is to use JS, and that's why we've
recently specced and started implementing IntersectionObserver, as
suggested earlier in the thread.  You can write some pretty simple
code that adds/removes a class based on whether it's visible, and then
do everything else in CSS.

~TJ

Received on Tuesday, 6 December 2016 19:13:45 UTC