Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a sticky header possible in AMP?

So far I haven't found a solid way to create a sticky header on AMP pages. I know there are CSS workaround/hacks, but nothing I can use in a production environment. A simple "position:fixed;" unfortunately won't work in my case.

Out of all the components, I thought there would be one that toggles a body class on scroll, but I haven't found anything yet. Also don't think "amp-position-observer" will be of any use.

Am I missing something? Ideally I'd like to be able to toggle an element's class name after a scroll of X amount of pixels. Is this possible in AMP?

like image 202
Joseph Wer Avatar asked Jun 13 '18 00:06

Joseph Wer


2 Answers

Toggling an element's classname after a scroll of X amount of pixels is currently not supported as amp-position-observer does not allow changing amp-state.

You can combine amp-position-observer to change parts of the header using amp-animation. However, it's application is limited as the supported CSS properties are limited. Nevertheless, with a little bit of creativity this approach can be quite flexible. One possible pattern is to duplicate elements in your header which are then shown/hidden based on your scrolling position.

Here is a sample highlighting the header based on the currently focused section.

like image 175
Sebastian Benz Avatar answered Nov 08 '22 06:11

Sebastian Benz


I built a working solution of a sticky header within an amp-list. The pitfall is that amp elements add display: block and position: absolute on many elements.

To use position: sticky you need to use display: inline and position: relative on all subelements on your header. Make sure these are actually applied and not overwritten, use id to get a higher specificity over the amp css classes.

Here's an example using an amp list css:

  • All divs need display: inline
  • The amp-list gets an id (not class) to apply css to itself and the generated child div
  • Divs can be nested as long as they use display: inline

.sticky {
  position: sticky;
  z-index: 1;
  display: inline-block;
  box-sizing: border-box;
  width: 100%;
  background-color:white;
  top: 40px;
}

.inline {
  display: inline;
}

#list-wrapper, #list-wrapper>div {
  display: inline;
  position: relative;
}
<div>
    <amp-list [src]="..." items="." single-item layout="flex-item" id="list-wrapper">
        <template type="amp-mustache">
            <div class="inline">
                <span class="sticky">
                    <span>Sticky header</span>
                </span>
            </div>
        </template>
    </amp-list>
    <div>Your content</div>
<div>
like image 25
lisa p. Avatar answered Nov 08 '22 05:11

lisa p.