Css一些小样式

1,474 阅读5分钟

遇到好的有趣的炫酷的样式会随时更新。

box边框的颜色和内容字体颜色一样 currentColor


.box{
  width: 200px;
  height: 200px;
  color: purple;
  border: 1px solid currentColor;
}
<div class="box">
  测试 边框的颜色会和字体的颜色一样
</div>

除了一个div元素下的第一个ul元素不使用这个样式

给多个 li 添加 margin-top 的时候,往往要求第一个 li 不需要 margin-top,这时候可以选择使用 :not(first-child) 或 :not(:first-of-type),也可以选择使用 ul * + *(猫头鹰选择器),可以选中 ul 中所有紧跟在某个元素之后的元素

ul.sideul:not(:first-of-type) {
   border-top: 1px solid rgba(255,255,255,0.2)
}

猫头鹰选择器

猫头鹰选择器,因为+这种方式酷似猫头鹰,被称为猫头鹰选择器。

* + * {   margin-top: 5px; }
  • 上面定义了一个简单的猫头鹰选择器
+: 相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素。
*: 通配符,代表任意元素。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
        <style>
            .a {background: pink;}
            .warp div + div {margin-top: 20px;}
        </style>
    </head>
    <body>
        <div class="warp">
            <div class="a">div</div>
            <div class="a">div</div>
            <div class="a">div</div>
            <div class="a">div</div>
        </div>
    </body>
</html>

给文本中单独文字加颜色

<style>
    [data-unit]:after {
      content: attr(data-unit);
      color: #3b98e0;
    }
 </style>
 
 <p data-unit="元">剩余话费40</p>
  • JS Bin - Collaborative JavaScript Debugging
  • IE7,8不支持 Can I use... Support tables for HTML5, CSS3, etc

user-select 禁止选择文本

.box{
  width: 200px;
  height: 200px;
  color: purple;
  border: 1px solid currentColor;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

<div class="box">
    文本不能被选中,禁止粘贴复制
</div>

selection 可设置文字被选择时的样式

    .box {
      width: 200px;
      height: 200px;
      color: purple;
      border: 1px solid currentColor;
    }

    ::selection {
      background: #FE6E66;
      color: #FFF;
    }
    
  <div class="box">
    测试 改变文字选中的颜色
  </div>

优惠券样式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>内圆角</title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }
    body {
      /* background: #999; */
      padding-top: 50px;
    }
    .wrapper {
      display: flex;
      position: relative;
      width: 320px;
      height: 100px;
      margin: auto;
      filter: drop-shadow(2px 2px 3px #999);
    }
    .wrapper div {
      height: 100%;
    }
    .wrapper b {
      position: absolute;
      right: 30%;
      top: 5px;
      height: calc(100% - 10px);
      border-left: 1px dotted #fff;
    }
    .left {
      background: #58a;
      background:  radial-gradient(circle at top right, transparent 5px, #44C9A1 0) top right ,radial-gradient(circle at bottom right, transparent 5px, #44C9A1 0) bottom right ;
      background-size: 100% 60%;
      background-repeat: no-repeat;
      color: white;
      width: 70%;
      border-radius: 5px 0 0 5px;
    }
    .right {
      background: #58a;
      background: radial-gradient(circle at top left, transparent 5px, #44C9A1 0) top left ,radial-gradient(circle at bottom left, transparent 5px, #44C9A1 0) bottom left ;
      background-size: 100% 60%;
      background-repeat: no-repeat;
      width: 30%;
      color: white;
      border-radius: 0 5px 5px 0;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="left"></div>
    <b></b>
    <div class="right"></div>
  </div>
  </div>
</body>
</html>

文字滚动 跑马灯效果

/* 跑马灯效果 */
@keyframes around {
  from {
   margin-left: 100%;
  }
  to {
   /* var接受传入的变量 */
   margin-left: var(--marqueeWidth--);
  }
 }
.marquee_container{
  background-color: #666;
  border-radius: 30rpx;
  height: 70rpx;
  width: 100%;
  overflow: hidden;
}
.marquee_container:hover{
  /* 不起作用 */
  animation-play-state: paused;
}
.marquee_text{
  color:#fff;
  font-weight: bold;
  font-size: 40rpx;
  display: inline-block;
  white-space: nowrap;
  animation-name: around;
  animation-duration: 15s;  /*过渡时间*/
  animation-iteration-count: infinite;
  animation-timing-function:linear;
}


 <!-- 跑马灯 -->
  <view class="marquee_container" style="--marqueeWidth--:-12em">
    <view class="marquee_text">{{swiperInfo.subject}}</view>
  </view>

文字拉长

  font-size: 40rpx;
  font-weight: 700;
  transform: scale(1, 3);
  -ms-transform: scale(1, 3);
  -webkit-transform: scale(1, 3);
  -moz-transform: scale(1, 3);
  -o-transform: scale(1, 3);
  font-weight: bolder;
  margin-top: 32rpx;

一条线 两头尖

.solid2 {
	position: absolute;
	left: 32.4%;
	width: 3rpx;
	height: 100%;
	background: -webkit-linear-gradient(top, #fff 0, #ccc 50%, #fff 100%);
	z-index: 999;
}

背景色渐变

background: linear-gradient(to right , yellow, chartreuse);

四周阴影包围

 box-shadow: 3px 4px 10px 0px rgba(0,0,0,0.2); 

字体渐变

image.png

    <style>
        .text {
            background: -webkit-linear-gradient(0deg,
                    #56ecc7,
                    #9f5ad8 5%,
                    #56ecc7 10%,
                    #df0e54 15%,
                    rgb(84, 12, 126) 20%,
                    #12eb0a 25%,
                    #e79435 30%,
                    #e40e0e 35%,
                    #56ecc7);
            -webkit-background-clip: text;
            color: transparent;
        }
    </style>
    
    <p class="text">我是渐变文字我是渐变文字我是渐变文字我是渐变文字我是渐变文字我是渐变文字我是渐变文字</p>

动态文字渐变

image.png

    <style>
        body {
            height: 100vh;
            width: 100vw;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #000;
        }
        .loading {
            /* 背景被裁剪成文字的前景色。 */
            background-clip: text;
            -webkit-background-clip: text;
            background-image: linear-gradient(45deg, #fff, #000);
            font-size: 30px;
            color: transparent;
            animation: backColorMove 0.8s linear infinite;
        }
        @keyframes backColorMove {
            0%,
            100% {
                background-image: linear-gradient(45deg, #fff, #000 5% 7%, #fff);
            }

            20%, 80% {
                background-image: linear-gradient(45deg, #fff, #000 58% 60%, #fff);
            }

            50% {
                background-image: linear-gradient(45deg, #fff, #000 93% 95%, #fff);
            }
        }
    </style>
    <div class="loading">掘金</div>

动态进度条-vue

image.png

<template>
    <div class="progress-bar">
        <span class="progress-fill" ref="fill" :style="[{ 'background-color': color }]"></span>
    </div>
</template>
<script>
export default {
    name: "loading",
    props: {
        color: {
            type: String,
            default: "hsl(260, 90%, 70%)"
        },
        value: {
            type: [String, Number],
            default: 0
        }
    },
    mounted() {
        setTimeout(() => this.render())
    },
    methods: {
        render() {
            this.$refs.fill.style.width = this.value + "40%";
        }
    },
};
</script>
<style lang="scss" scoped>
.progress-bar {
    width: 280px;
    background-color: rgb(232, 232, 232);
    height: 42px;
    border-radius: 42px;
    overflow: hidden;
    position: relative;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.8),
        6px 2px 12px -2px rgba(0, 0, 0, 0.6);
    .progress-fill {
        display: block;
        height: 100%;
        max-width: 100%;
        width: 0;
        transition: 2s width ease-in-out;
    }
}
.progress-fill {
    &:after {
        content: "";
        display: block;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        background-image: linear-gradient(
            -45deg,
            rgba(255, 255, 255, 0.2) 25%,
            transparent 25%,
            transparent 50%,
            rgba(255, 255, 255, 0.2) 50%,
            rgba(255, 255, 255, 0.2) 75%,
            transparent 75%,
            transparent
        );
        background-size: 40px 40px;
        animation: loading-line 2s linear infinite;
    }
}
@keyframes loading-line {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: 40px 40px;
    }
}
</style>

鼠标滑入线条光影效果

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      display: flex;
      background: #000;
      overflow: hidden;
    }

    .container {
      position: relative;
      width: 240px;
      height: 80px;
      margin: auto;
    }

    .hover-text {
      position: absolute;
      top: 30px;
      left: 30px;
      line-height: 80px;
      width: 240px;
      color: #fff;
      font-size: 24px;
      text-align: center;
      cursor: pointer;
    }

    .container:hover .rect {
      stroke-dasharray: 640px;
      stroke-dashoffset: 0;
    }

    .rect {
      fill: none;
      stroke-width: 3;
      stroke-linejoin: round;
      stroke: #fff;
      stroke-dasharray: 640px;
      stroke-dashoffset: 640px;
      transition: all .5s ease-in-out;
      filter: drop-shadow(0 0 2px #f24983) drop-shadow(0 0 4px #f24983) drop-shadow(0 0 8px #f24983) drop-shadow(0 0 12px #f24983);
    }
  </style>
</head>

<body>
  <div class="container">
    <svg width="300" height="140" OK xmlns="http://www.w3.org/2000/svg">
      <rect x="30" y="30" class="rect" height="80px" width="240px"></rect>
    </svg>
    <div class="hover-text">HOVER ME</div>
  </div>
</body>

</html>

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      display: flex;
      background: linear-gradient(#1a0f19, #16121c);
    }

    svg {
      position: absolute;
      width: 600px;
      height: 600px;
    }

    .container {
      position: relative;
      width: 400px;
      height: 400px;
      margin: auto;
    }


    .line {
      --colorA: #f24983;
      fill: none;
      stroke-width: 10;
      stroke-linejoin: round;
      stroke-linecap: round;
      stroke: #fff;
      stroke-dasharray: 328 600;
      animation: rotate 2s infinite linear;
      filter:
        drop-shadow(0 0 2px var(--colorA)) drop-shadow(0 0 5px var(--colorA)) drop-shadow(0 0 10px var(--colorA)) drop-shadow(0 0 15px var(--colorA)) drop-shadow(0 0 25px var(--colorA));
    }

    .line2 {
      animation: rotate 2s infinite -1s linear;
      --colorA: #37c1ff;
    }


    @keyframes rotate {
      0% {
        stroke-dashoffset: 0;
      }

      100% {
        stroke-dashoffset: 928;
      }
    }
  </style>
</head>

<body>
  <div class="container">
    <svg xmlns="http://www.w3.org/2000/svg">
      <path d="M 400 160 A 2 2 90 0 0 260 160 A 2 2 90 0 0 120 160 C 120 230 260 270 260 350 C 260 270 400 230 400 160"
        class="line" />
    </svg>
    <svg xmlns="http://www.w3.org/2000/svg">
      <path d="M 400 160 A 2 2 90 0 0 260 160 A 2 2 90 0 0 120 160 C 120 230 260 270 260 350 C 260 270 400 230 400 160"
        class="line line2" />
    </svg>
  </div>
</body>

</html>

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body,
    html {
      width: 100%;
      height: 100%;
      display: flex;
      background: #000;
    }

    div {
      position: relative;
      margin: auto;
      width: 300px;
      height: 300px;
      --colorA: #b78eff;
    }

    div::before,
    div::after {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      border-radius: 50%;
      border-top: 10px solid #fff;
      filter: drop-shadow(0 0 2px var(--colorA)) drop-shadow(0 0 5px var(--colorA)) drop-shadow(0 0 10px var(--colorA)) drop-shadow(0 0 20px var(--colorA));
      -webkit-animation: rotate 3s infinite linear;
      animation: rotate 3s infinite linear;
    }

    div::after {
      --colorA: #ffec41;
      -webkit-animation-delay: -1.5s;
      animation-delay: -1.5s;
    }

    @-webkit-keyframes rotate {
      100% {
        transform: rotate(360deg);
      }
    }

    @keyframes rotate {
      100% {
        transform: rotate(360deg);
      }
    }
  </style>
</head>

<body>
  <div></div>
</body>

</html>

动态三色球

image.png

  <style>
    #app {
      width: 100%;
      height: 100vh;
      background-image: repeating-linear-gradient(90deg, rgba(201, 201, 201, 0.06) 0px, rgba(201, 201, 201, 0.06) 1px, transparent 1px, transparent 96px), repeating-linear-gradient(0deg, rgba(201, 201, 201, 0.06) 0px, rgba(201, 201, 201, 0.06) 1px, transparent 1px, transparent 96px), repeating-linear-gradient(0deg, rgba(201, 201, 201, 0.09) 0px, rgba(201, 201, 201, 0.09) 1px, transparent 1px, transparent 12px), repeating-linear-gradient(90deg, rgba(201, 201, 201, 0.09) 0px, rgba(201, 201, 201, 0.09) 1px, transparent 1px, transparent 12px), linear-gradient(90deg, white, white);
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
    }

    .loading {
      width: 200px;
      height: 200px;
      position: relative;
      -webkit-animation: rotate 2s infinite;
      animation: rotate 2s infinite;
      filter: url(#mix);
    }

    .loading .loading-circle {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      position: absolute;
      left: 50%;
      top: 50%;
      margin: -30px 0 0 -30px;
    }

    .loading .loading-circle:nth-child(1) {
      background-color: #ffd000;
      -webkit-animation: circle-move-1 2s infinite, change-z-index 6s -2s infinite;
      animation: circle-move-1 2s infinite, change-z-index 6s -2s infinite;
    }

    .loading .loading-circle:nth-child(2) {
      background-color: #8bcbff;
      -webkit-animation: circle-move-2 2s infinite, change-z-index 6s -4s infinite;
      animation: circle-move-2 2s infinite, change-z-index 6s -4s infinite;
    }

    .loading .loading-circle:nth-child(3) {
      background-color: rgba(252, 96, 96, 0.945);
      -webkit-animation: circle-move-3 2s infinite, change-z-index 6s -6s infinite;
      animation: circle-move-3 2s infinite, change-z-index 6s -6s infinite;
    }

    @-webkit-keyframes circle-move-1 {

      0%,
      20%,
      100% {
        transform: translate(0, 0) scale(1);
      }

      40% {
        transform: translate(0, -18px) scale(0.5);
      }

      60% {
        transform: translate(0, -85px) scale(0.5);
      }

      80% {
        transform: translate(0, -85px) scale(0.5);
      }
    }

    @keyframes circle-move-1 {

      0%,
      20%,
      100% {
        transform: translate(0, 0) scale(1);
      }

      40% {
        transform: translate(0, -18px) scale(0.5);
      }

      60% {
        transform: translate(0, -85px) scale(0.5);
      }

      80% {
        transform: translate(0, -85px) scale(0.5);
      }
    }

    @-webkit-keyframes circle-move-2 {

      0%,
      20%,
      100% {
        transform: translate(0, 0) scale(1);
      }

      40% {
        transform: translate(-16px, 12px) scale(0.5);
      }

      60% {
        transform: translate(-90px, 65px) scale(0.5);
      }

      80% {
        transform: translate(-90px, 65px) scale(0.5);
      }
    }

    @keyframes circle-move-2 {

      0%,
      20%,
      100% {
        transform: translate(0, 0) scale(1);
      }

      40% {
        transform: translate(-16px, 12px) scale(0.5);
      }

      60% {
        transform: translate(-90px, 65px) scale(0.5);
      }

      80% {
        transform: translate(-90px, 65px) scale(0.5);
      }
    }

    @-webkit-keyframes circle-move-3 {

      0%,
      20%,
      100% {
        transform: translate(0, 0) scale(1);
      }

      40% {
        transform: translate(16px, 12px) scale(0.5);
      }

      60% {
        transform: translate(90px, 65px) scale(0.5);
      }

      80% {
        transform: translate(90px, 65px) scale(0.5);
      }
    }

    @keyframes circle-move-3 {

      0%,
      20%,
      100% {
        transform: translate(0, 0) scale(1);
      }

      40% {
        transform: translate(16px, 12px) scale(0.5);
      }

      60% {
        transform: translate(90px, 65px) scale(0.5);
      }

      80% {
        transform: translate(90px, 65px) scale(0.5);
      }
    }

    @-webkit-keyframes change-z-index {

      0%,
      100% {
        z-index: 3;
      }

      33.33% {
        z-index: 2;
      }

      66.66% {
        z-index: 1;
      }
    }

    @keyframes change-z-index {

      0%,
      100% {
        z-index: 3;
      }

      33.33% {
        z-index: 2;
      }

      66.66% {
        z-index: 1;
      }
    }

    @-webkit-keyframes rotate {

      0%,
      60% {
        transform: rotate(0deg);
      }

      80%,
      100% {
        transform: rotate(360deg);
      }
    }

    @keyframes rotate {

      0%,
      60% {
        transform: rotate(0deg);
      }

      80%,
      100% {
        transform: rotate(360deg);
      }
    }
  </style>
 <div id="app">
    <div class="loading">
      <div class="loading-circle"></div>
      <div class="loading-circle"></div>
      <div class="loading-circle"></div>
      <svg xmlns="http://www.w3.org/2000/svg">
        <defs>
          <filter id="mix">
            <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
            <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 21 -7" />
          </filter>
        </defs>
      </svg>
    </div>
  </div>

动态tabbar小样式

image.png

<style>
        * {
            margin: 0px;
            padding: 0px;
            box-sizing: border-box;
        }

        .container {
            width: 100%;
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: #fc5c65;
        }

        .bar {
            padding: 0px 10px;
            display: flex;
            align-items: center;
            background-color: #ffffff;
            border-radius: 10px 10px 20px 20px;
            box-shadow: 3px 3px 0px 0px rgb(235 59 90);
        }

        .bar .bar-item {
            position: relative;
            overflow: hidden;
            padding: 20px 25px;
            cursor: pointer;
        }

        .bar .bar-item i {
            z-index: 1;
            position: relative;
            color: #a4b0be;
            transition: all .3s ease-in-out;
        }

        .bar .bar-item.pre-active i {
            color: #fc5c65;
        }

        .bar .bar-item.active i {
            color: #fc5c65;
            animation: colour 1s ease-in-out;
        }

        .bar .bar-item.active .bar-fluid {
            position: absolute;
            top: 0px;
            left: 0px;
            background-color: #fc5c65;
            width: 100%;
            height: 0px;
            animation: fluid 1s ease-in-out;
        }

        .bar .bar-item.active .bar-fluid:before {
            content: '';
            position: absolute;
            top: 0px;
            left: -50%;
            background-color: #ffffff;
            width: 110%;
            height: 400%;
            border-radius: 50%;
        }

        .bar .bar-item.active .bar-fluid:after {
            content: '';
            position: absolute;
            top: 0px;
            right: -50%;
            background-color: #ffffff;
            width: 110%;
            height: 400%;
            border-radius: 50%;
        }

        .bar .bar-item.active .drop {
            position: absolute;
            top: -2.5px;
            left: 38px;
            background-color: #fc5c65;
            width: 2.5px;
            height: 2.5px;
            border-radius: 50%;
            animation: drop 1s ease-in-out;
        }

        @keyframes colour {
            0% {
                color: #a4b0be;
            }

            55% {
                color: #a4b0be;
                transform: scale(1);
            }

            60% {
                color: #fc5c65;
                transform: scale(1);
            }

            70% {
                transform: scale(1.1);
            }

            80% {
                transform: scale(1);
            }
        }

        @keyframes fluid {
            0% {
                height: 0px;
            }

            30% {
                height: 10px;
            }

            100% {
                height: 0px;
            }
        }

        @keyframes drop {
            20% {
                top: -2.5px;
            }

            50% {
                top: 21px;
            }

            51% {
                top: -2.5px;
            }
        }
    </style>
<div class="container">
        <div class="bar">
            <div class="bar-item pre-active" onclick="changeActive(this)">
                <div class="bar-fluid"></div>
                <div class="drop"></div>
                <i class="far fa-calendar-alt">按钮</i>
            </div>
            <div class="bar-item" onclick="changeActive(this)">
                <div class="bar-fluid"></div>
                <div class="drop"></div>
                <i class="far fa-sticky-note">按钮</i>
            </div>
            <div class="bar-item" onclick="changeActive(this)">
                <div class="bar-fluid"></div>
                <div class="drop"></div>
                <i class="far fa-bell">按钮</i>
            </div>
            <div class="bar-item" onclick="changeActive(this)">
                <div class="bar-fluid"></div>
                <div class="drop"></div>
                <i class="far fa-address-book">按钮</i>
            </div>
        </div>
    </div>
<script>
    const preactiveItem = document.querySelector('.pre-active')
    const barItems = document.querySelectorAll('.bar-item')

    function changeActive(newActive) {
        preactiveItem.classList.remove('pre-active')
        barItems.forEach(element => {
            element.classList.remove('active')
        })
        newActive.classList.add('active')
    }
</script>

水滴充电样式

image.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .main {
            width: 100%;
            min-height: 100vh;
            padding: 0;
            text-align: center;
            overflow: hidden;
            font-size: 14px;
        }

        .container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #000;
            flex-direction: column;
            filter: contrast(30);
            --drop-color: rgb(181, 249, 252);
        }

        .drop {
            width: 80px;
            height: 90px;
            border-radius: 50%;
            background-color: var(--drop-color);
            filter: blur(20px);
            position: absolute;
            animation: 3.2s down linear infinite;
            animation-fill-mode: backwards;
        }

        .drop:nth-of-type(1) {
            animation-delay: 0s;
        }

        .drop:nth-of-type(2) {
            animation-delay: 0.5s;
        }

        .drop:nth-of-type(3) {
            animation-delay: 0.7s;
        }

        .collection {
            width: 120px;
            height: 120px;
            background-color: var(--drop-color);
            filter: blur(20px);
            animation: 8s spin linear infinite;
            border-radius: 50%;
            position: relative;
        }

        .progress {
            position: absolute;
            font-size: 32px;
            font-family: fantasy;
            color: #333;
        }

        @keyframes down {
            0% {
                opacity: 0;
                transform: translateY(-600%) scale(0.7);
            }

            50% {
                opacity: 1;
                transform: translateY(-100%) scale(0.5);
            }

            100% {
                opacity: 0;
                transform: translateY(0%) scale(0.45);
            }
        }

        @keyframes spin {
            0% {
                transform: scale(1) rotate(0deg);
            }

            50% {
                transform: scale(1.15) rotate(180deg);
                border-radius: 40% 10% 50% 45%;
            }

            100% {
                transform: scale(1) rotate(360deg);
            }
        }
    </style>
</head>

<body>
    <div class="main">
        <div class="container">
            <div class="drop"></div>
            <div class="drop"></div>
            <div class="drop"></div>

            <div class="collection"></div>
            <span class="progress">75%</span>
        </div>
    </div>
</body>

</html>

动态充电样式

image.png

<style>
    #app {
      width: 100%;
      height: 100vh;
      background-color: black;
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
    }

    .loading {
      width: 360px;
      height: 360px;
      position: relative;
    }

    .loading h5 {
      width: 180px;
      height: 180px;
      position: absolute;
      top: 30%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-family: "Source Code Pro", monospace;
      font-size: 48px;
      font-weight: normal;
      color: white;
      z-index: 9;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .loading .loading-warrper {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100vh;
      filter: contrast(10) hue-rotate(0);
      animation: changeColor 5s infinite linear;
      background-color: black;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .loading-circle {
      position: relative;
      width: 300px;
      height: 300px;
      box-sizing: border-box;
      filter: blur(8px);
    }

    .loading-circle::before {
      content: "";
      position: absolute;
      width: 180px;
      height: 180px;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background-color: black;
      z-index: 10;
    }

    .loading-circle::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      width: 205px;
      height: 205px;
      transform: translate(-50%, -50%);
      background-color: #79f77f;
      border-radius: 42% 37% 55% 48%/47% 43%;
      animation: rotate 10s infinite linear;
    }

    .loading-drop {
      position: absolute;
      bottom: -90px;
      left: 50%;
      margin-left: -50px;
      width: 120px;
      height: 120px;
      border-radius: 50%;
      background-color: #79f77f;
      filter: blur(8px);
    }

    .loading-drop span {
      width: 25px;
      height: 25px;
      display: block;
      position: absolute;
      border-radius: 50%;
      background: #79f77f;
    }

    .loading-drop span:nth-child(0) {
      left: 36px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 30px;
      height: 30px;
      animation: up 10s ease-in-out infinite;
      animation-delay: -2.926s;
    }

    .loading-drop span:nth-child(1) {
      left: 47px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 30px;
      height: 30px;
      animation: up 6s ease-in-out infinite;
      animation-delay: -9.247s;
    }

    .loading-drop span:nth-child(2) {
      left: 59px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 27px;
      height: 27px;
      animation: up 9s ease-in-out infinite;
      animation-delay: -7.432s;
    }

    .loading-drop span:nth-child(3) {
      left: 43px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 30px;
      height: 30px;
      animation: up 6s ease-in-out infinite;
      animation-delay: -7.824s;
    }

    .loading-drop span:nth-child(4) {
      left: 85px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 27px;
      height: 27px;
      animation: up 9s ease-in-out infinite;
      animation-delay: -5.499s;
    }

    .loading-drop span:nth-child(5) {
      left: 48px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 30px;
      height: 30px;
      animation: up 9s ease-in-out infinite;
      animation-delay: -6.562s;
    }

    .loading-drop span:nth-child(6) {
      left: 87px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 29px;
      height: 29px;
      animation: up 8s ease-in-out infinite;
      animation-delay: -7.502s;
    }

    .loading-drop span:nth-child(7) {
      left: 22px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 28px;
      height: 28px;
      animation: up 7s ease-in-out infinite;
      animation-delay: -6.979s;
    }

    .loading-drop span:nth-child(8) {
      left: 89px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 30px;
      height: 30px;
      animation: up 8s ease-in-out infinite;
      animation-delay: -5.912s;
    }

    .loading-drop span:nth-child(9) {
      left: 59px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 28px;
      height: 28px;
      animation: up 10s ease-in-out infinite;
      animation-delay: -9.794s;
    }

    .loading-drop span:nth-child(10) {
      left: 98px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 31px;
      height: 31px;
      animation: up 10s ease-in-out infinite;
      animation-delay: -0.365s;
    }

    .loading-drop span:nth-child(11) {
      left: 95px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 27px;
      height: 27px;
      animation: up 8s ease-in-out infinite;
      animation-delay: -7.939s;
    }

    .loading-drop span:nth-child(12) {
      left: 99px;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 28px;
      height: 28px;
      animation: up 10s ease-in-out infinite;
      animation-delay: -1.82s;
    }

    @keyframes up {
      90% {
        opacity: 0.7;
      }

      100% {
        opacity: 0.5;
        transform: translate(-50%, calc(-50vh + 60px));
      }
    }

    @keyframes rotate {
      50% {
        border-radius: 47% 43%/42% 37% 55% 48%;
      }

      100% {
        transform: translate(-50%, -50%) rotate(720deg);
      }
    }

    @keyframes changeColor {
      100% {
        filter: contrast(50) hue-rotate(360deg);
      }
    }
  </style>
<div id="app">
    <div class="loading">
      <h5>60%</h5>
      <div class="loading-warrper">
        <div class="loading-circle"></div>
        <div class="loading-drop">
          <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
        </div>
      </div>
    </div>
  </div>

鸿蒙效果

image.png

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>公众号:前端学不动</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    html, body { height: 100% }
    body {
      background: black;
      display: flex;
      align-items: center;
      justify-content: center
    }
    .ul {
      position: relative;
      width: 100px;
      height: 50px;
      padding: 10px;
      list-style: none;
      overflow: hidden
    }
    .ul:first-of-type {
      padding-bottom: 0
    }
    .ul:last-of-type {
      padding-top: 0;
      /* margin-top: -2px; */
      /* animation: container-move .1s 1.2s forwards */
    }

    .harmony {
      position: absolute;
      top: 10px;
      left: 10px;
      width: 70px;
      height: 70px;
      border: 15px solid white;
      border-radius: 50%;
      transform: translateY(50%);
      box-shadow: 0 0 6px white, inset 0 0 6px white;
      animation: move 1.2s forwards
    }
    .ul:last-of-type > .harmony {
      top: auto;
      bottom: 10px;
      transform: translateY(-50%);
      filter: url(#blur)
    }

    svg {
      width: 0;
      height: 0
    }

    @keyframes move {
      to { transform: none }
    }

    /* @keyframes container-move {
      to { margin-top: 0 }
    } */
  </style>
</head>
<body>
  <div class="container">
    <ul class="ul">
      <li class="harmony"></li>
    </ul>
    <ul class="ul">
      <li class="harmony"></li>
    </ul>
  </div>

  <svg>
    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="0 6"/>
    </filter>
  </svg>

  <script>
    const filter = document.querySelector('feGaussianBlur')
    
    const clearFilter = () => {
      const value = parseFloat(filter.getAttribute('stdDeviation').split(' ')[1]) - 0.06
      
      if (value > 0) {
        filter.setAttribute('stdDeviation', `0 ${value}`)
        requestAnimationFrame(clearFilter)
      } else {
        return
      }
    }

    setTimeout(clearFilter, 1200)
  </script>
</body>
</html>

粘连跑马灯

image.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            marhin: 0;
        }

        html,
        body {
            background-color: black;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }

        :root {
            --main-color: rgb(255, 255, 255);
        }

        .loader {
            position: absolute;
            width: 240px;
            height: 240px;
            background-color: black;
            filter: blur(4px) contrast(20);
            overflow: hidden;
        }

        .loader>.box {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 90%;
            height: 90%;
            border: 10px solid var(--main-color);
            overflow: hidden;
            transform: translate(-50%, -50%);
            box-sizing: border-box;
            border-radius: 100%;
        }

        .loader>.box::before {
            content: "Loading Loading Loading";
            position: absolute;
            top: 50%;
            left: 50%;
            color: var(--main-color);
            font-size: 60px;
            letter-spacing: 1px;
            font-weight: bolder;
            white-space: nowrap;
            transform: translate(100%, -50%);
            animation: marquee 4.25s infinite linear;
            text-shadow: 0px 60px 10px rgba(255, 255, 255, 0.6);
        }

        .loader>.box::after {
            content: "";
            position: absolute;
            bottom: -20px;
            left: 50%;
            margin-left: -20px;
            width: 40px;
            height: 30px;
            background: var(--main-color);
            border-radius: 50%;
            transform-origin: 50% -100px;
            transform: rotateZ(90deg);
            animation: rotate 8s 0.2s infinite linear;
        }

        @keyframes marquee {
            from {
                transform: translate(-34%, -50%);
            }

            to {
                transform: translate(-68%, -50%);
            }
        }

        @keyframes rotate {
            from {
                transform: rotateZ(0deg);
            }

            to {
                transform: rotateZ(360deg);
            }
        }
    </style>
</head>

<body>
    <div class="loader">
        <div class="box"></div>
    </div>

</body>

</html>

炫酷的列表点击样式

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    :root {
      font-size: 15px;
      font-family: Helvetica;

      --body-width: 480px;
      --card-width: 420px;
      --card-height: 280px;
      --img-height: 226px;
      --img-height-expanded: 320px;

      background-color: #333;
    }

    body {
      width: var(--body-width);
      background-color: #eee;
      margin: auto;
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
      padding: 1rem 0;
    }

    body.noscroll {
      overflow: hidden;
    }

    .card {
      width: var(--card-width);
      height: var(--card-height);
      background-color: #fff;
      border-radius: 1rem;
      box-shadow: 0 .2rem 2rem rgba(0, 0, 0, .1);
      margin: 1rem 0;
      transition: .3s all cubic-bezier(0, 1, 0.95, 1.05);
    }

    .card img {
      display: block;
      width: 100%;
      height: var(--img-height);
      object-fit: cover;

      border-top-left-radius: 1rem;
      border-top-right-radius: 1rem;
    }

    .card h4 {
      margin: 0;
      font-size: 1.5rem;
      font-weight: bold;
      padding: .8rem 1.2rem;
      background-color: #fff;
      line-height: 2rem;
      letter-spacing: -.5px;
      padding-bottom: 0;
    }

    .card .content-wrapper {
      height: 0;
      overflow: hidden;
      transition: .3s all ease-out;
      opacity: .8;
    }

    .card .content-wrapper .content {
      padding: 0 1.2rem;
      background-color: #fff;
      overflow: auto;
    }

    .card p {
      font-size: 1.2rem;
      line-height: 1.5rem;
    }

    /* active classes below */

    .card.active {
      transform: translateY(var(--data-offset-top)) scale(calc(480/420));
      transform-origin: 50% 0;
      border-radius: 0;
    }

    .card.active h4 {
      padding-bottom: .8rem;
    }

    .card.active img {
      border-top-left-radius: 0;
      border-top-right-radius: 0;
      height: var(--img-height-expanded);
    }

    .card.active .content-wrapper {
      height: 100vh;
      transition: .3s all ease-in;
      opacity: 1;
    }
  </style>
</head>

<body>
  <div class="card">
    <img src="https://source.unsplash.com/900x600/?nature,water,1">
    <h4>APP OF THE DAY</h4>
    <div class="content-wrapper">
      <div class="content">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi dolor veritatis neque cumque. Voluptatibus
          debitis quia unde corrupti laudantium fuga pariatur tenetur dolorum aspernatur laborum iste animi, consequatur
          porro sequi?</p>
        <p>Suscipit, culpa molestiae alias doloribus praesentium omnis tempore impedit deserunt consequatur tempora. Ad
          id eum non officia corrupti dolores earum architecto corporis commodi delectus excepturi, laudantium qui,
          harum aut libero!</p>
        <p>Veritatis nemo deleniti, deserunt iure odit ratione molestiae labore non ipsum obcaecati aperiam officiis
          repudiandae similique architecto quas nostrum quidem enim fugiat optio alias incidunt ipsam dicta. Minus,
          perspiciatis reiciendis!</p>
        <p>Consequuntur facilis cupiditate tempore eius esse! Aut quo iste praesentium recusandae commodi placeat est
          omnis soluta fuga dolore veniam provident culpa, deleniti ullam hic dignissimos fugiat illo nemo veritatis ex.
        </p>
        <p>Ratione eos illo incidunt illum inventore consequatur eligendi, aliquam ducimus voluptatem? Voluptate
          dignissimos quasi vel eum tempore, aperiam nemo, aliquam ratione amet aspernatur nam! Fugit quaerat nemo
          aspernatur. Quia, quis.</p>
      </div>
    </div>
  </div>

  <div class="card">
    <img src="https://source.unsplash.com/900x600/?nature,water,2">
    <h4>APP OF THE DAY</h4>
    <div class="content-wrapper">
      <div class="content">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi dolor veritatis neque cumque. Voluptatibus
          debitis quia unde corrupti laudantium fuga pariatur tenetur dolorum aspernatur laborum iste animi, consequatur
          porro sequi?</p>
        <p>Suscipit, culpa molestiae alias doloribus praesentium omnis tempore impedit deserunt consequatur tempora. Ad
          id eum non officia corrupti dolores earum architecto corporis commodi delectus excepturi, laudantium qui,
          harum aut libero!</p>
        <p>Veritatis nemo deleniti, deserunt iure odit ratione molestiae labore non ipsum obcaecati aperiam officiis
          repudiandae similique architecto quas nostrum quidem enim fugiat optio alias incidunt ipsam dicta. Minus,
          perspiciatis reiciendis!</p>
        <p>Consequuntur facilis cupiditate tempore eius esse! Aut quo iste praesentium recusandae commodi placeat est
          omnis soluta fuga dolore veniam provident culpa, deleniti ullam hic dignissimos fugiat illo nemo veritatis ex.
        </p>
        <p>Ratione eos illo incidunt illum inventore consequatur eligendi, aliquam ducimus voluptatem? Voluptate
          dignissimos quasi vel eum tempore, aperiam nemo, aliquam ratione amet aspernatur nam! Fugit quaerat nemo
          aspernatur. Quia, quis.</p>
      </div>
    </div>
  </div>

  <div class="card">
    <img src="https://source.unsplash.com/900x600/?nature,water,3">
    <h4>APP OF THE DAY</h4>
    <div class="content-wrapper">
      <div class="content">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi dolor veritatis neque cumque. Voluptatibus
          debitis quia unde corrupti laudantium fuga pariatur tenetur dolorum aspernatur laborum iste animi, consequatur
          porro sequi?</p>
        <p>Suscipit, culpa molestiae alias doloribus praesentium omnis tempore impedit deserunt consequatur tempora. Ad
          id eum non officia corrupti dolores earum architecto corporis commodi delectus excepturi, laudantium qui,
          harum aut libero!</p>
        <p>Veritatis nemo deleniti, deserunt iure odit ratione molestiae labore non ipsum obcaecati aperiam officiis
          repudiandae similique architecto quas nostrum quidem enim fugiat optio alias incidunt ipsam dicta. Minus,
          perspiciatis reiciendis!</p>
        <p>Consequuntur facilis cupiditate tempore eius esse! Aut quo iste praesentium recusandae commodi placeat est
          omnis soluta fuga dolore veniam provident culpa, deleniti ullam hic dignissimos fugiat illo nemo veritatis ex.
        </p>
        <p>Ratione eos illo incidunt illum inventore consequatur eligendi, aliquam ducimus voluptatem? Voluptate
          dignissimos quasi vel eum tempore, aperiam nemo, aliquam ratione amet aspernatur nam! Fugit quaerat nemo
          aspernatur. Quia, quis.</p>
      </div>
    </div>
  </div>

  <div class="card">
    <img src="https://source.unsplash.com/900x600/?nature,water,4">
    <h4>APP OF THE DAY</h4>
    <div class="content-wrapper">
      <div class="content">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi dolor veritatis neque cumque. Voluptatibus
          debitis quia unde corrupti laudantium fuga pariatur tenetur dolorum aspernatur laborum iste animi, consequatur
          porro sequi?</p>
        <p>Suscipit, culpa molestiae alias doloribus praesentium omnis tempore impedit deserunt consequatur tempora. Ad
          id eum non officia corrupti dolores earum architecto corporis commodi delectus excepturi, laudantium qui,
          harum aut libero!</p>
        <p>Veritatis nemo deleniti, deserunt iure odit ratione molestiae labore non ipsum obcaecati aperiam officiis
          repudiandae similique architecto quas nostrum quidem enim fugiat optio alias incidunt ipsam dicta. Minus,
          perspiciatis reiciendis!</p>
        <p>Consequuntur facilis cupiditate tempore eius esse! Aut quo iste praesentium recusandae commodi placeat est
          omnis soluta fuga dolore veniam provident culpa, deleniti ullam hic dignissimos fugiat illo nemo veritatis ex.
        </p>
        <p>Ratione eos illo incidunt illum inventore consequatur eligendi, aliquam ducimus voluptatem? Voluptate
          dignissimos quasi vel eum tempore, aperiam nemo, aliquam ratione amet aspernatur nam! Fugit quaerat nemo
          aspernatur. Quia, quis.</p>
      </div>
    </div>
  </div>
</body>

</html>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
  $('.card').on('click', function (e) {
    let card = $(e.currentTarget)
    let card_offset_scrolltop = $(card).offset().top - $(window).scrollTop()

    $(card).css('--data-offset-top', card_offset_scrolltop * -1 + 'px')

    $(card).toggleClass('active')

    let ratio = 480 / 420
    let height = $(window).height()
    height -= $(card).find('img').outerHeight() * ratio
    height -= $(card).find('h4').outerHeight() * ratio
    height /= ratio

    $(card).find('.content').css('height', height)

    if ($(card).hasClass('active')) {
      $('body').addClass('noscroll')
    } else {
      $('body').removeClass('noscroll')
    }
  })
</script>

炫酷的滚动样式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    :root {
  --device-width: 770px;
  --device-height: 1336px;
  --ui-width: 640px;
  font-size: 15px;
}

body {
  background-color: #000;
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  font-family: Helvetica;
  padding: 4rem 0;
}

h2 {
  color: #6e6e73;
  text-align: center;
  font-size: 4.5rem;
  font-weight: 600;
  margin: 6rem 0;
}

h2 p {
  margin: 0;
  color: #fff;
}

#iphone {
  position: relative;
  width: var(--device-width);
  height: var(--device-height);
}

#hardware {
  width: 100%;
  height: 100%;
  background-image: url(https://assets.codepen.io/2002878/iphone12-5g_on_phone.jpg);
  background-size: var(--device-width) var(--device-height);
  
  mask-image: url(https://assets.codepen.io/2002878/iphone12-5g_on_phone_mask.png);
  -webkit-mask-image: url(https://assets.codepen.io/2002878/iphone12-5g_on_phone_mask.png);
  
  mask-size: var(--device-width) var(--device-height);
  -webkit-mask-size: var(--device-width) var(--device-height);
  
}

#ui {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
}

#ui .top-ui {
  display: block;
  width: var(--ui-width);
  height: auto;
  margin: 70px auto 0;
  padding-bottom: 30px;
  border-bottom: 1px solid #222;
}

#ui ul {
  list-style: none;
  margin: 0;
  padding: 0;
  
  --progress: 0;
}

#ui ul li img {
  display: block;
  width: var(--ui-width);
  height: auto;
  margin: 10px auto;
  padding-bottom: 10px;
  border-bottom: 1px solid #222;
  transform: scale(calc(1.8 - (0.8 * var(--progress)))) translateY(calc(-60px * (1 - var(--progress))));
  opacity: var(--progress);
}
  </style>
</head>
<body>
  <h2>
    Superfast wireless
    <p>Hello 5G.</p>
  </h2>
  
  <div id="iphone">
    <div id="hardware"></div>
    <div id="ui">
      <img src="https://assets.codepen.io/2002878/iphone12-5g_top_ui.jpg" class="top-ui" alt="">
      
      <ul>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_01.jpg" />
        </li>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_02.jpg" />
        </li>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_03.jpg" />
        </li>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_04.jpg" />
        </li>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_05.jpg" />
        </li>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_06.jpg" />
        </li>
        <li>
          <img src="https://assets.codepen.io/2002878/iphone12-5g_show_07.jpg" />
        </li>
      </ul>
    </div>
  </div>
</body>
</html>
<script>
  const rows = document.querySelectorAll('#ui ul li')
const html = document.documentElement

document.addEventListener('scroll', (e) => {
  let scrolled = html.scrollTop / (html.scrollHeight - html.clientHeight)
  
  let total =  1 / rows.length
  
  for (let [index, row] of rows.entries()) {
    let start = total * index
    let end = total * (index + 1)
    
    let progress = (scrolled - start) / (end - start)
    if (progress >= 1) progress = 1
    if (progress <= 0) progress = 0
    
    row.style.setProperty('--progress', progress)
  }
})
</script>