This is the second day of my participation in the August More Text Challenge

demand

The requirement is to place a menu bar at the top right of a child container and always appear at the top as the container scrolls, as shown in the figure below.

The initial idea was to use the absolute definition postition: absolute to put the menu bar at the top right and then sticky position: sticky for sticky layout. It turned out that the two Settings could not be applied to the same element at the same time, so another solution was considered.

IO/f-star /pen/… codepen. IO/f-star /pen/…

Scheme selection

Because I wanted to go to the top right, I thought float: right might work as well, so I did. But I forgot one very important side effect of float: Right, which caused text to wrap around, until testers tested it. The diagram below:

Using element float directly was not feasible, so I thought maybe I could add a parent element. The parent element uses absolute positioning, then the child element (the menu bar) uses sticky positioning. I tried it out and found it worked, as a final solution.

Realize the principle of

We need to provide a parent element to the menu bar. Bar. Bar-wrap, which needs to set the width and height of the element to the same size as the container. Set position: absolute; , then pass width: 100%; Height: 100% or top: 0; left:0; right: 0; bottom: 0; So that the parent element is the same width and height as the container element.

The width should be the same as the height of the container so that the child element can be positioned correctly in the upper right corner using the right float. The height is the same as the container because an element that uses sticky positioning can only have sticky effects within its parent element, not outside of it. If the height is only the same as the height of the menu bar, there will be no stickiness effect.

Finally we need to use pointer-events: none; Make the parent element unclickable, as if it didn’t exist, and achieve clickthrough. Otherwise, other contents under the container will not be clickable.

.bar-wrap {
  /* Core style */
  position: absolute; 
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;

  z-index: 120;
  pointer-events: none;
}
Copy the code

The next step is to set the right float and sticky positioning of menu bar elements to achieve the desired effect. Because click penetration of the parent element of the menu-bar element affects the child elements, we need to set pointer-events: auto; To cancel click through.

.bar {
  /* Core style */
  position: sticky;
  top: -20px; /* Negative of the container's padding-top */
  float: right;
  z-index: 88;
  pointer-events: auto;
}
Copy the code

At the end

The implementation is not complicated, in short, it is a transparent mask on the container that can be clicked through, the menu element under the mask is set to right float and sticky, and set to not be clicked through, and finally achieves the desired effect.

IO/f-star /pen/…