how to change element width based on current width in transition 0 to 100

Viewed 219

So basically am trying to make a progress bar with pure css, i have ten percentage the progress bar will increase in with from 10% to 100%, depending on class which get added on click of a button, for example if button Add 10 is clicked .ten-progress is added to the element css and so on for other 9 buttons. My problem is suppose i am on 80% of the progress bar and i click the button Add 20, the transition starts from beginning to 20% or if am on 20% of the progress bar and want to go to 50% i click the Add 50 button and it goes from beginning to 50% what i wanted is a way to make the progress bar increase or decrease based current progress so if the current progress is 20% and i click on Add 50 it should go to 50% from 20% and not from 0%.

Here is my css:

.progress {
    background-size: 23em 0.25em;
    height: 12px;
    position: relative;
    background-color: #e04542;
    display: flex;
}

.the-loading.zero-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 0%;
    animation: cssload-width-zero 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-zero 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-zero 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-zero 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-zero 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-zero {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    100% {
        width: 0%;
    }
}

@-o-keyframes cssload-width-zero {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    100% {
        width: 0%;
    }
}

@-ms-keyframes cssload-width-zero {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    100% {
        width: 0%;
    }
}

@-webkit-keyframes cssload-width-zero {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    100% {
        width: 0%;
    }
}

@-moz-keyframes cssload-width-zero {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    100% {
        width: 0%;
    }
}

.the-loading.absolute.ten-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 10%;
    animation: cssload-width-ten 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-ten 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-ten 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-ten 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-ten 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-ten {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 10%;
    }
}

@-o-keyframes cssload-width-ten {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 10%;
    }
}

@-ms-keyframes cssload-width-ten {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 10%;
    }
}

@-webkit-keyframes cssload-width-ten {
    10%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 10%;
    }
}

@-moz-keyframes cssload-width-ten {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 10%;
    }
}

.the-loading.absolute.twenty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 20%;
    animation: cssload-width-twenty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-twenty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 20%;
    }
}

@-o-keyframes cssload-width-twenty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 20%;
    }
}

@-ms-keyframes cssload-width-twenty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 20%;
    }
}

@-webkit-keyframes cssload-width-twenty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 20%;
    }
}

@-moz-keyframes cssload-width-twenty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 20%;
    }
}

.the-loading.absolute.thirty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 30%;
    animation: cssload-width-thirty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-thirty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 30%;
    }
}

@-o-keyframes cssload-width-thirty {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 30%;
    }
}

@-ms-keyframes cssload-width-thirty {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 30%;
    }
}

@-webkit-keyframes cssload-width-thirty {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 30%;
    }
}

@-moz-keyframes cssload-width-thirty {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 30%;
    }
}

.the-loading.absolute.fourty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 40%;
    animation: cssload-width-fourty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-fourty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-fourty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-fourty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-fourty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-fourty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 40%;
    }
}

@-o-keyframes cssload-width-fourty {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 40%;
    }
}

@-ms-keyframes cssload-width-fourty {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 40%;
    }
}

@-webkit-keyframes cssload-width-fourty {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 40%;
    }
}

@-moz-keyframes cssload-width-fourty {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 40%;
    }
}

.the-loading.absolute.fifty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 50%;
    animation: cssload-width-fifty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-fifty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-fifty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-fifty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-fifty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-fifty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 50%;
    }
}

@-o-keyframes cssload-width-fifty {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 50%;
    }
}

@-ms-keyframes cssload-width-fifty {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 50%;
    }
}

@-webkit-keyframes cssload-width-fifty {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 50%;
    }
}

@-moz-keyframes cssload-width-fifty {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 50%;
    }
}

.the-loading.absolute.sixty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 60%;
    animation: cssload-width-sixty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-sixty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-sixty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-sixty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-sixty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-sixty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 60%;
    }
}

@-o-keyframes cssload-width-sixty {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 60%;
    }
}

@-ms-keyframes cssload-width-sixty {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 60%;
    }
}

@-webkit-keyframes cssload-width-sixty {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 60%;
    }
}

@-moz-keyframes cssload-width-sixty {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 60%;
    }
}

.the-loading.absolute.seventy-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 70%;
    animation: cssload-width-seventy 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-seventy 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-seventy 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-seventy 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-seventy 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-seventy {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 70%;
    }
}

@-o-keyframes cssload-width-seventy {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 70%;
    }
}

@-ms-keyframes cssload-width-seventy {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 70%;
    }
}

@-webkit-keyframes cssload-width-seventy {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 70%;
    }
}

@-moz-keyframes cssload-width-seventy {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 70%;
    }
}

.the-loading.absolute.eighty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 80%;
    animation: cssload-width-eighty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-eighty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-eighty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-eighty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-eighty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-eighty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 80%;
    }
}

@-o-keyframes cssload-width-eighty {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 80%;
    }
}

@-ms-keyframes cssload-width-eighty {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 80%;
    }
}

@-webkit-keyframes cssload-width-eighty {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 80%;
    }
}

@-moz-keyframes cssload-width-eighty {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 80%;
    }
}

.the-loading.absolute.ninty-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 90%;
    animation: cssload-width-ninty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-ninty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-ninty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-ninty 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-ninty 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-ninty {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 90%;
    }
}

@-o-keyframes cssload-width-ninty {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 90%;
    }
}

@-ms-keyframes cssload-width-ninty {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 90%;
    }
}

@-webkit-keyframes cssload-width-ninty {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 90%;
    }
}

@-moz-keyframes cssload-width-ninty {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    0% {
        width: 0%;
    }
    100% {
        width: 90%;
    }
}

.the-loading.absolute.filled-progressFilled {
    background-color: #e04542;
    height: 10px;
    position: relative;
    width: 100%;
    animation: cssload-width-filled 3.45s cubic-bezier(0.45, 0, 1, 1);
    -o-animation: cssload-width-filled 3.45s cubic-bezier(0.45, 0, 1, 1);
    -ms-animation: cssload-width-filled 3.45s cubic-bezier(0.45, 0, 1, 1);
    -webkit-animation: cssload-width-filled 3.45s cubic-bezier(0.45, 0, 1, 1);
    -moz-animation: cssload-width-filled 3.45s cubic-bezier(0.45, 0, 1, 1);
}

@keyframes cssload-width-filled {
    0%,
    100% {
        transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 100%;
    }
}

@-o-keyframes cssload-width-filled {
    0%,
    100% {
        -o-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 100%;
    }
}

@-ms-keyframes cssload-width-filled {
    100% {
        -ms-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 100%;
    }
}

@-webkit-keyframes cssload-width-filled {
    0%,
    100% {
        -webkit-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 100%;
    }
}

@-moz-keyframes cssload-width-filled {
    0%,
    100% {
        -moz-transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
    }
    0% {
        width: 0%;
    }
    100% {
        width: 100%;
    }
}
1 Answers

This is JS based. You can make use of multiple functions with multiple increase/decrease amounts set as long as you're acting on the same element. To test it: give a placeholder value to scaleX() in CSS and set increase/decrease amount(amt) - I named it increase but it's irrelevant.

const increaseProgress = document.querySelector('.add');

increaseProgress.addEventListener('click', increase);

function increase(amt) {
    //manipulate the amount
    amt = 0.2;
    const progressBar = document.querySelector('.progress-bar');

    // get current scaleX value
    const currentScale = getComputedStyle(progressBar).transform;
    // this spits out a matrix(a, b, c, a, b, c ) following two lines extract scaleX
    const matrixArray = currentScale.replace('matrix(', '').split(',');
    let scaleX = parseFloat(matrixArray[0]);

    // 0.7.99984 -> 0.8 (preventing weird decimals)
    scaleX = Math.round(scaleX * 10) / 10;

    progressBar.style.transform = `scaleX(${scaleX + amt})`;
    // console.log(bg);
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    gap: 20px;
}

.container {
    width: 200px;
    height: 100px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    border: 1px solid #222;
    overflow: hidden;
}

.progress-bar {
    box-sizing: border-box;
    height: 0.5rem;
    width: 100%;
    background-color: salmon;
    transform-origin: left;
    transform: scaleX(0);
    -webkit-transform: scaleX(0);
    -moz-transform: scaleX(0);
    -ms-transform: scaleX(0);
    -o-transform: scaleX(0);
    transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1);
    -webkit-transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1);
    -moz-transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1);
    -ms-transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1);
    -o-transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1);
}
<!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" />

        <link rel="stylesheet" href="./style.css" />
        <title>Transition - TEST</title>
    </head>
    <body>
        <div class="container">
            <p>Progress Bar</p>
            <div class="progress-bar"></div>
        </div>

        <button class="add">TOGGLE</button>

        <script src="./app.js"></script>
    </body>
</html>

Related