Top suction is a common design pattern in which components start rolling with the program but stick to a boundary when they hit it. For example, baidu home page search box top effect.

The scrolling effect is as follows:

So for this very common suction top, what are the implementation methods?

position: sticky

In the CSS document of MDN about postion, there is a sticky parameter, which means:

Stickily positioned element is the element with the sticky positional attribute after calculation

The element is positioned according to the normal document flow, and then relative to its nearest scrolling ancestor and containing block; Includes table-related elements, offset based on top, right, bottom, and left values. The offset value does not affect the position of any other elements.

This implementation method is simple and quick, and its specific implementation requirements can be summarized as follows:

  1. The parent element is scrollable

2. Specify top, bottom, left, right4 values

Note that this feature is a new feature of the CSS and may be supported by browsers. The following figure shows the support for this feature:

Add position: -webkit-sticky

The sample code

.sticky {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
}
Copy the code

Dynamic style

In actual production, the reason why sticky is not used is that its browser support is not comprehensive. Hence the dynamic style.

The idea is very simple: add scroll listening function to the parent element to judge the distance between the current top component and the boundary. If the distance is less than or equal to 0, modify its style as: Position :fixed; . , take VUE framework as an example (only VUE~ cry), the specific implementation code:

<template> ... <div ref="tabRow" :class={'fixed': fixed}></div> ... </template> <script> ... data() { return { fixed: false } }, mounted: {this. $nextTrick (() = > {/ / tabRow for a component's ref value / / the component initial distance the distance at the top of the page. This offsetTop = this.$refs.tabRow.getBoundingClientRect().top; /** Add listener */ window.addeventListener ('scroll', this.handlescroll); }) }, methods: {handleScroll () {/ / screen the current rolling distance let scrollTop = window. PageYOffset | | document. The documentElement. The scrollTop | | document.body.scrollTop if (scrollTop >= this.offsetTop) { this.fixed = true } else { this.fixed = false } } }, destroyed() { window.removeEventListener("scroll", this.handleScroll); }... </script> <style> ... .fixed { position: fixed; left: 0; top: 0; }... </style>Copy the code