The double 11 black box is so cool? Let's use CSS variables to improve it!

Preface

Which websites did you go shopping on during Double 11 just past? No matter which website you go to, Tmall is probably indispensable. I found such an interesting phenomenon when visiting Tmall:

Although this effect is still relatively common, there is one detail that is different. For example, let's first look at the effect of an ordinary header gradually fading as the window scrolls:

Compare it to find out what is different, the normal version is completely transparent at the beginning, and slowly displayed as the window scrolls, which is opacityachieved by controlling the transparency property.

The small black box version has a gradient color at the beginning, and it is gradually gradual to be nearly translucent. This method looks more elegant, but it looks like a beautiful gradient color when entering the page before scrolling. , The behavior when scrolling is almost the same as before when relying on transparency.

What we want to improve is to use the scrolling distance to control background-position. As the window scrolls, the degree of the gradient will gradually change to control the hidden effect.

style

First of all, let header's write out the style:

header {
      /* 设置一个控制背景色位置的CSS变量,方便JS控制 */
      --position: 100;

      /* 居中靠下显示子元素 */
      display: grid;
      place-items: end center;

      /* 设置为固定定位 */
      position: fixed;

      /* 距离上边左边为0 */
      top: 0;
      left: 0;

      /* 宽度铺满屏幕 */
      width: 100%;

      /* 给个合适的高度 */
      height: 40px;

      /* 白色字体 */
      color: white;

      /* 字体大小 */
      font-size: 16px;

      /* 让字体细一点 */
      font-weight: 100;

      /* 增加下内变局,防止文字过于靠下 */
      padding-bottom: 10px;

      /* 设置过渡效果 */
      transition: background-position .2s;

      /* 黑色渐变背景 */
      background: linear-gradient(black, rgba(148, 88, 88, 0.3) 80%, rgba(0, 0, 0, 0)) 0 calc(var(--position) * 1%) / 100% 300%;
    }

operation result:

You can see that we headerhave set a CSS variable in it . If you are not sure what a CSS variable is, please click here . The grid is also used for centering . Of course, it is not completely centered , but slightly lower. , Because I think Tmall’s small black box is just centered on the lower side.

Overall realization

Then we started to write JS code, because the scroll distance of the screen cannot be obtained with pure CSS, but in order to facilitate the interaction between the two sides, we still use CSS variables , because the improvement brought by CSS variables is not only saving points. CSS code, as well as reducing the cost of CSS development and maintenance.

More importantly, many interactive developments in the components have been transferred from the original JS to the CSS code, making the component code more concise, and at the same time making the visual performance more flexible. ——Zhang Xinxu

For the specific benefits that CSS variables can bring to us, please refer to Zhang Xinxu's blog:

"The Improvement and Change of CSS Variables to the Development of JS Interactive Components"

Let's take a look at how CSS variables interact with JS:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  <title>属于自己的渐变小黑盒</title>
  <style>
    /* 清除默认样式 */
    * { padding: 0; margin: 0 }

    header {
      /* 设置一个控制背景色位置的CSS变量,方便JS控制 */
      --position: 100;

      /* 居中靠下显示子元素 */
      display: grid;
      place-items: end center;

      /* 设置为固定定位 */
      position: fixed;

      /* 距离上边左边为0 */
      top: 0;
      left: 0;

      /* 宽度铺满屏幕 */
      width: 100%;

      /* 给个合适的高度 */
      height: 40px;

      /* 白色字体 */
      color: white;

      /* 字体大小 */
      font-size: 16px;

      /* 让字体细一点 */
      font-weight: 100;

      /* 增加下内变局,防止文字过于靠下 */
      padding-bottom: 10px;

      /* 设置过渡效果 */
      transition: background-position .2s;

      /* 黑色渐变背景 */
      background: linear-gradient(black, rgba(148, 88, 88, 0.3) 80%, rgba(0, 0, 0, 0)) 0 calc(var(--position) * 1%) / 100% 300%;
    }

    main {
      /* 给个合适的高度 */
      height: 1000px;
    }
  </style>
</head>
<body>
  <header>咱们自己的小黑盒</header>
  <main></main>

  <script>
    // 获取header
    const header = document.getElementsByTagName('header')[0]

    addEventListener('scroll', () => {
      // 获取偏移值
      const top = document.documentElement.scrollTop

      // 设置一个合适的范围
      if (top <= 200) {
        // 令header的渐变色位置变成计算后的渐变位置
        header.style.setProperty('--position', 100 - Math.min(100, top))
      } else {
        // 在移动一定范围后令其完全不透明
        header.style.setProperty('--position', 0)
      }
    })
  </script>
</body>
</html>

operation result:

Imagine what it would be like without using CSS variables :

header.style.backgroundPosition = '0 ' + 100 - Math.min(100, top) + '%'

Although it may seem like nothing, it will be a disaster when there are more attributes to be controlled, and this method should always carry CSS units, such as px, %, rem, which adds unnecessary It’s mentally burdensome, and it also slows down the efficiency of the program.

After using CSS variables , there is no need to bring a unit, just assign a number directly, so why not bring a unit? The answer lies in calcthe function:

calc(var(--position) * 1%)

Remember that you can no longer use JS thinking to write the calc function here. In JS, we use +it because this represents string splicing, and here the number one 乘以percent will become a specific percentage. Similarly, if you need other units, you can make flexible modifications according to specific needs:

calc(var(--position) * 1px)

⚠️Note that the one in front of px 1is very important and cannot be omitted!

And it is not necessary to write 1, you can also multiply according to specific needs:

calc(var(--position) * 6.6rem)

Expand

In fact, seen from the code and our daily lives can effect that, essentially rolling back some distance headertransparency on the fixed will not change, wasted listening onscrollevents. But you can't cancel the monitoring, because you don't know when the user will slide to the top again, but this situation is very suitable for another effect:

I forgot what this effect is called. In short, it displays something similar to a progress bar at the top as the user scrolls the page, so that the user can know what kind of position they are in the web page. , Look at the code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  <title>属于自己的渐变小黑盒</title>
  <style>
    /* 清除默认样式 */
    * { padding: 0; margin: 0 }

    header {
      /* 设置一个控制位置的CSS变量,方便JS控制 */
      --position: 0;

      /* 设置为固定定位 */
      position: fixed;

      /* 距离上边左边为0 */
      top: 0;
      left: 0;

      /* 宽度铺满屏幕 */
      width: 100%;

      /* 给个合适的高度 */
      height: 10px;

      /* 设置过渡效果 */
      transition: transform .1s;

      /* 渐变背景 */
      background: linear-gradient(to right,#4481eb,#04befe);

      /* 设置形变效果 */
      transform: scaleX(var(--position));

      /* 设置变形参照点 */
      transform-origin: left;
    }

    main {
      /* 给个合适的高度 */
      height: 10000px;

      /* 渐变背景 */
      background: linear-gradient(#30cfd0,#330867)
    }
  </style>
</head>
<body>
  <header></header>
  <main></main>

  <script>
    // 获取header
    const header = document.getElementsByTagName('header')[0]

    addEventListener('scroll', () => {
      // 获取偏移值
      const top = document.documentElement.scrollTop

      // 获取页面总高度
      const height = document.documentElement.scrollHeight

      // 设置CSS变量
      if (top > height - document.documentElement.clientHeight - 1) {
        header.style.setProperty('--position', 1)
      } else {
        header.style.setProperty('--position', top / height)
      }
    })
  </script>
</body>
</html>

This article was first published on the WeChat public account: "The front end does not move"

Guess you like

Origin blog.csdn.net/GetIdea/article/details/109633246