JD.com app product details page at the top of the tab switch, the following red caterpillar effect is how to achieve?

JD.com app product details page at the top of the tab switch, how is the following red caterpillar effect achieved?

Mar.04,2022

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Tab Line Index</title>
    <style type="text/css">
    .clear-fix:after {content:'\200B';clear:both;height:0;visibility:hidden;display:block;}

    .tab-list {position:relative;font-size:24px;border:1px solid -sharpCCC;}
    .tab-list .tab {float:left;padding:0.25em 1em;}
    .tab-list .line {position:absolute;height:3px;background-color:-sharpF00;}
    /** /
    .tab-list .line-next {transition: left ease-out 0.2s, right ease-in 0.2s;}
    .tab-list .line-prev {transition: left ease-in 0.2s, right ease-out 0.2s;}
    /**/
    /**/
    .tab-list .line-next {transition: left cubic-bezier(0,1,1,1) 0.2s, right cubic-bezier(1,0,1,1) 0.2s;}
    .tab-list .line-prev {transition: left cubic-bezier(1,0,1,1) 0.2s, right cubic-bezier(0,1,1,1) 0.2s;}
    /**/
    </style>
    <script>
    document.addEventListener('DOMContentLoaded', function(){

        let rectTabList, rect;

        let lineBaseX, lineBaseY;

        let domTabList = document.querySelector('.tab-list');
        let domLine    = domTabList.querySelector('.line');

        rectTabList = domTabList.getBoundingClientRect();
        rect        = domLine.getBoundingClientRect();
        lineBaseX   = rect.x;
        lineBaseY   = rect.y;

        let arrDomTab = domTabList.querySelectorAll('.tab');
        let i, domTab;
        let lineY = 0;
        for(i=0; i<arrDomTab.length; iPP)
        {
            domTab = arrDomTab[i];
            rect   = domTab.getBoundingClientRect();

            domTab.setAttribute('data-xl', Math.floor(rect.x - rectTabList.x));
            domTab.setAttribute('data-xr', Math.floor(rectTabList.x + rectTabList.width - rect.x - rect.width));

            lineY = Math.max(lineY, rect.bottom);
        }

        domLine.style.top = Math.floor(lineY - lineBaseY)+'px';

        domTabList.addEventListener('click', function($evt){
            let dom = $evt.target;
            if(dom.classList.contains('tab') === false)
                return;

            let xl = parseInt(dom.getAttribute('data-xl'), 10);
            let xr = parseInt(dom.getAttribute('data-xr'), 10);

            rect = domLine.getBoundingClientRect();
            if(xl > rect.x)
            {
                // next
                domLine.className = 'line line-next';
                setTimeout(function(){
                    domLine.style.left = xl+'px';
                    domLine.style.right = xr+'px';
                }, 1);
            }
            else
            {
                // prev
                domLine.className = 'line line-prev';
                setTimeout(function(){
                    domLine.style.left = xl+'px';
                    domLine.style.right = xr+'px';
                }, 1);
            }

        });
    });
    </script>
</head>
<body>
<div class="tab-list clear-fix">
    <div class="tab">Tab</div>
    <div class="tab"></div>
    <div class="tab">Label</div>
    <div class="line"></div>
</div>
</body>
</html>

excessive left right

Menu