Borak - software developer illustrational
Blog
15.1. 2020 / 00:00

javascript

typescript

Angular

Angular 8

css

When css property position: sticky doesn’t work. Sticky header directive in Angular using Angular material elements.

I have recently came across the need to implement the sticky headers in the list of material design mat-list components. However the relatively new property ‘position: sticky’ appeared not to be the solution to work.
. Due to several reasons it failed to work properly. This article is about to explain why

position: sticky
css property does not work in the specific setups and how to implement your own sticky headers leveraging the Angular directives.

Position sticky

Css property handles the block to behave as relatively positioned until its containing block reaches certain treshold within its containing block.


H3 – What is containing block for element with position sticky?

It is the nearest ancestor of the block. However, when talking about sticky position, we need to take into account the containing block of the block containing the positioned element. For that, we need to learn, how the ancestor of the sticky element is positioned:

  • Sticky, static, relative
    •      The containing block is formed by the edge of the content box of the nearest ancestor element.
  • Absolute:
    • The containing block is the first of its ancestors, which is positioned as either absolute or relative.
  • Fixed 
    • The containing block is the viewport

H3-  When sticky is set to be fixed.

Sticky element get to be fixed after the containing block of the sticky element reaches certain trashold. For example, when we set element to be sticky with combination of top property like this:

position: sticky;
top: 20px

The positioned element will behave as relative until its top edge appears to be 20px from the edge of the top edge of the containing element of the sticky-positioned element.

It is simillar to fixed element, which is fixed to be, for example, 20 px of the top of the wievport. When we scroll the body, the fixed element stick at its fixed position.

The sticky element behave like that after the top limit is reached. With the difference, that it takes the containing block that is set to overflow: scroll of its parrent as the viewport.

Pic 01 – sticky element and its viewport


When sticky doesn’t work

Hovewer pretty solution the sticky concept is, there are scenarios, when this solution fails.
The position sticky behaves as regular static property when:
  • Some of the containing elements have its property overflow set to auto or hidden.
  • One or more ancesstors are of the type HTMLUknownElement

HTMLUknownElement

The HMTLUknown element is a type of tag, that is not known to browser. That simply means, all custom tags, that are not in the HTML 5 specification are of the type HTMLUknownElement. This element on its default behaves as ordinary inline tag. The position sticky stops to work, when we set the element’s position property to block.

HTMLUknownElement and the Angular components

As angular creates for its components custom elements with the name of the selector setup in the @Component decorator, the position sticky mostly does not work in the Angular applications.

HTMLUknownElement in Angular – the solution for position: sticky

One possible solution to make the sticky position work is to define the host elements to our components as HTML 5 compliant tags. We can simply write

@Component({
   selector: div[my-compoent]',
   template: `
     
  `
})
export class MyComponent{
}

And then, we simply use the component in the parent template like this:

<div my-component>
   content
</div>

This way we avoid the HTMLUknownElement tag and the issue with position sticky altogether.

The position sticky cannot be used – Third party Angular libraries with custom tags.


The previous solution works, when we have control about the component being rendered. However this is not always our situation. Sometimes we can come across the need to make sticky header in the elements generated by code, we do not have the control over. Mostly third-party libraries.
Then, we have only one option left. Implement our own sticky behavior.


Custom sticky header directive

If you have gotten right to this article and so far to this paragraph, probably no of the above solutions suit your need. Then you are only one option left. To develop your own implementation of sticky headers. If you need the sticky behavior for angular templates, I can actually be of a help to you.

Actualy, there is an implementation of sticky directive in the npm registry. However the problematics is so interesting to me, I developed my own implementation in the form of the angular directive. You can install the solution, I will further dissect and implement in the course of the following tutorial, from here:

npm i @petrborak/ng-sticky-header

More about the implementation of your ng-sticky directives in my next article. I will provide you with the link here as soon as the article is presented.

Cheers.

More by Borak

To maximalize your user experience during visit to my page, I use cookies.More info
I understand

#BORAKlive

This page is subjected to the Creative Common Licence. Always cite the Author - Do not use the page's content on commercial basis. Comply with the licence 3.0 Czech Republic.
go to top