Amphtml: Extending amp-dynamic-css-classes to support viewport intersections

Created on 14 Apr 2016  Â·  25Comments  Â·  Source: ampproject/amphtml

A number of the sites we’re working on have elements that appear and disappear based on scroll position, mostly things like fixed header bars, floating social button overlays.

I'm kicking around the idea of adding to amp-dynamic-css-classes the ability to specify viewport intersections and have classes added/removed to the <body> based on view-ability.

Something like

<amp-dynamic-css-classes>
{
       “viewports": [
               {
                       “selector”: “div.somthing”,
                       “viewable”: “class-to-add”,
                       “hidden”: “class-to-add”.
               }
       ]
}
</amp-dyncamic-css-classes>

Alternatively, add to the elements themselves

<div class=”whatever” data-amp-viewable=“class-to-add-to-body” data-amp-hidden=“class-to-add-to-body”></div>

Personally I like the json version, it’s more in line with how other amp tags work.

Questions:

  1. Is this a good idea in general?
  2. Which model?
  3. Is there any need for specifying using pixel scroll position or % scroll position rather than element boundaries?

This, combined with normal css transforms would provide a great deal of the functionality that people currently implement with js.

I'm looking for feedback before I go down the full intent to implement route.

Soon Feature Request

Most helpful comment

@nikoviedo This codepen https://codepen.io/aghassemi/pen/GOEWEz may also help.

All 25 comments

Could you describe the type of visual changes you'd like to make? I think we should go from there and then see how to implement it.

To pick an example on somebody else's site if you look at a Washington Post article on a mobile device as you scroll the header bar is replaced by a share bar then as you get toward the bottom of the article a tease for another article appears as a fixed overlay.

Another example from one of our customer sites: If you look at this Dailydot article (again on mobile) as the header scrolls off a menu dot appear on the right, on the AMP version we've faked it with layering.

Those are just a couple of examples. The underlying need is to be able to show/hide/modify fixed layer elements based on the scroll position of the document.

CC @dvoytenko @rudygalfi
Thanks!

We want to do something like amp-sticky for the straight forward use case like those share bars I believe.

I still think it is useful to add classes based on viewport position. E.g. to fade in a image as it enters viewport, but I'd rather see those class changes as applied to the respective element. Toggling classes on body is pretty expensive and should not have too many false positives.

CC @ericlindley-g

Interesting idea—slotting in the backlog to take a look at in more depth when ready.

@jpettitt , could you share links to examples of this behavior?

@ericlindley-g the washington post link a few comments up does it as does the DailyDot link.

@cramforce adding classes to an element makes sense, although the trigger may not be that element's position becasue it may not even be displayed. We could do something like this which would solve the putting classes on the page issue.

<amp-whatever-we-call-this-thing>
{
       “viewports": [
               {
                       "target": "div.element.to.apply.class.to"
                       “track”: “div.element.whose.position.triggers”,
                       “viewable”: “class-to-add”,
                       “hidden”: “class-to-add”.
               }
       ]
}
</amp-whatever-we-call-this-thing>

@jpettitt Thanks (sorry, missed the links on the first read)

Would this feature allow for a better user experience like on http://lucidlemon.github.io/paradeiser/, where the menu would disappear completely when scrolling down on a small mobile device and reappear when scrolling up. In my humble opinion, the main navigation is a pretty important aspect of mobile never really got much attention.

@88kbbq That's a great suggestion—it may even make sense as an option in amp-fixed, so the hide-on-scroll-down/show-on-scroll-up behavior can apply to a range of fixed-position cases

/cc @cramforce

@88kbbq so you're talking about headroom.js ? I like that although I'd want to have more flexibility than the single offset trigger it offers. I can see a bunch of use cases.

  1. The header bar (both a disappearing version and one that gets smaller when you scroll past a given point)
  2. A footer bar that appear after you pass the end of the article text
  3. A footer with an ad unit that only appear once you scroll down the page. (yes I know this would be a fixed ad unit, a policy change).
  4. Other elements that appear in side margins to select next/prev article after the user has scrolled the initial article.

The general point being to have as much flexibility as possible and not to be prescriptive about UX unless there is a strong technical reason to do so.

@ericlindley-g & @cramforce +1 for an option on amp-fixed

I get the AMP premise and mobile-first approach, but the process of vetting anything to do with JS and getting functionality integrated with some amp-extension is slow and resource intensive. I don't understand why little libraries like headroom.js can't just be whitelisted in the same way fonts are, or why we can't include a 50k of inline JS like with CSS. I'm just finding this AMP project so restrictive and not seeing how this really benefits the mobile Internet. Think about Line call buttons and all those niche social media sharing functions that will never make it into this project, and the consider the overhead of adding 20 amp-extensions on a single page in order for designers to achieve a desired functionality. Doesn't this defeat the whole purpose of the project?

Just allowing arbitrary JS to implement such a feature would disable many of the optimizations in AMP (which are based on having control on when things change their position) and often JS libs aren't build with all-async loading in mind.

No reason headroom.js couldn't be wrapped in a quick extension. The project would likely do slightly more generic extension when designing from scratch (which is on our radar).

@88kbbq I don't want to dismiss your concern. There are many use cases where AMP is not a great fit (like basically all apps). The great thing is that one can just not use it.

Thanks for your reply @cramforce. My thoughts were that rules could be set for adding custom JS just like with CSS (no picture element, no !important, etc.) and if the page validates then it's AMP'd; if not, it isn't. Then it would be for developers and website owners to decide direction with much less difficulty and in a much shorter timeline. For example, if I was getting paid to build an AMP HTML site but had the request from the customer to add this feature, we're looking at several months just to get something like headroom.js implemented. I know the app/plugin/extension thing has been all big since iPhone but I would argue that a full set of building blocks is more important than building amp-extensions. Appreciate the comments. I'm just thinking that my site would be valid AMP HTML if it weren't for this one JS script. And since 80% of my visitors are on mobile devices, I believe the extra screen provided with this script is important enough to make a case for inline JS. I'm hoping the powers to be will consider amp-custom extension for JS.

@88kbbq Custom JS will come. Not too optimistic about us shipping it this year, but we're working on it. Plan is embedded in this post https://medium.com/@cramforce/2016-will-be-the-year-of-concurrency-on-the-web-c39b1e99b30f#.85pep8oqy

@aghassemi — would the use cases described in this bug be addressed with https://github.com/ampproject/amphtml/issues/8411 ? If so, we can close and track there.

@ericlindley-g not everything, but we have also decided not to allow css triggers based on visibility or scroll due to ux/perf abuse potentials in the Design Review Meeting on 3/22 (https://github.com/ampproject/amphtml/issues/8190). (this issue is essentially amp-visibility-spy I proposed in that review meeting)

Reiterating our solution:
-#8411 will cover certain scroll-based animations
-For things not possible with #8411, we will provide custom components (e.g. dock, hide/show headers, navlink highlighting based on headings coming to view, etc.. )

8411 is getting close! In the meantime, closing this issue and breaking out specific issues for:

hide/show header: https://github.com/ampproject/amphtml/issues/8268
amp-visibility-spy: https://github.com/ampproject/amphtml/issues/10861
docking video: https://github.com/ampproject/amphtml/issues/8088
trigger visibility of a fixed element based on scroll position (potentially scroll position of other elements): https://github.com/ampproject/amphtml/issues/10862

Feel free to flag if any requested/related features aren't supported/tracked yet. Thanks!

@ericlindley-g how change header class on scroll??

@nikoviedo — it's not possible to change the class of an element on scroll.
However, amp-position-observer and amp-animation may help achieve the same goal.

What are you trying to achieve by changing the header class on scroll?

@nikoviedo This codepen https://codepen.io/aghassemi/pen/GOEWEz may also help.

Hey! @aghassemi thanks for that! But, i need change all the content inside header (color, font sizes, etc)!

@nikoviedo — amp-position-observer is not designed to do that, but I would like to understand your need here. Do you have an example webpage that shows what you'd like to do?

@ericlindley-g - www.viapais.com.ar whitout AMP

Thanks! I don't see any scroll-bound effects on mobile, but on desktop it looks like:

• the "Via Pais" logo text shrinks
• the header itself reduces in size
• the white bar below shifts up so it remains under the header
• the black bar below slides up to hide behind the header.

This all seems possible with amp-position-observer and amp-animation— @aghassemi do you see any issues? Would it be prohibitively complex?

@nikoviedo @ericlindley-g yeah that all seems doable.
Hardware accelerated properties like opacity and visibility and transform can be changed via amp-animation so you can use transform:scale to change the size of the logo and transform:translate to shift the headers as per header.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebastianbenz picture sebastianbenz  Â·  48Comments

zhouyx picture zhouyx  Â·  60Comments

lisotton picture lisotton  Â·  52Comments

jpettitt picture jpettitt  Â·  42Comments

ericlindley-g picture ericlindley-g  Â·  60Comments