So, position: sticky
is awesome, right? And so is Angular, right? Using both in conjunction with Firefox and Chrome work great. The problem starts with Safari.
If you build an Angular component that has a position: sticky
div within it as the first element in the template, Safari doesn't know how to handle it. Example:
AppComponent:
@Component({
template: '<sticky-component></sticky-component>'
})
export class AppComponent {}
StickyComponent:
@Component({
selector: 'sticky-component',
template: '<div class="sticky">Should be sticky</div>',
styles: [
`
.sticky {
position: sticky;
position: -webkit-sticky;
top: 0;
}
`
]
})
export class StickyComponent {}
This will generate a DOM like:
...
<sticky-component>
<div class="sticky"></div>
</sticky-component>
...
If you physically write out the HTML without the <sticky-component>
it works great in Safari. But since the parent of the sticky element is the host element, this fails. Trying to add the sticky CSS to the host element doesn't seem like it works either. Has anyone run into this issue before or has any solution? I know I can implement this sticky functionality using event listeners within Angular, but position: sticky
is sooo much easier.
StackBlitz example: https://stackblitz.com/edit/angular-jede8a (works in Chrome/Firefox but not in Safari)
This is more of a workaround which might not suit your needs but I guess it deserves an answer since it does solve the problem (not necessarily in the way you'd like it).
If the issue with Safari is a custom element (with a dash) used in the DOM, you can get rid of that by specifying a different selector. Instead of
selector: 'sticky-component',
you could have
selector: 'div[sticky-component]',
and then use the component by adding an attribute.
<div sticky-component></div>
Although certainly not ideal in this use-case, this is a valid way to define components. In fact, it's often done with custom buttons -- for example, Material itself uses this pattern: <button mat-button>
.
Not sure about inline styling. But if you move style to an external file. Following should do the trick.
:host {
.sticky {
position: sticky;
position: -webkit-sticky;
top: 0;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With