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:
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.
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.
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.. )
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.
Most helpful comment
@nikoviedo This codepen https://codepen.io/aghassemi/pen/GOEWEz may also help.