Getting my vertical beer indicator to work

I am trying to make a progress indicator that looks like emptying a glass of beer. Unfortunately, I am not a very artistic person, but I am doing my best.

My concept is as follows:

  • There is <div>a background of "beer", 100% vertical. It hides any overflow
  • Inside there is another <div>, located relative to the parent. It contains:
    • White background <div>to hide the “beer” pattern when it is gone.
    • Image of beer foam cap

Here is the concept of the picture:

enter image description here

I almost succeeded in my goal, as you can see in this snippet:

Note: ES6 async / await is required for animation

Promise.timeout = function (delay) {
            return new Promise((resolve) => {
                setTimeout(resolve, delay);
            });
        };
        Promise.animationFrame = function () {
            return new Promise((resolve) => {
                requestAnimationFrame(resolve);
            });
        };
        (async function () {
            const progress = document.querySelector("div.top");
            for (let i = 0, l = 1000; i < l; ++i) {
                progress.style.bottom = (100 - i / 10) + "%";
                await Promise.animationFrame();
            }
        })();
html, body, div {
    margin: 0px;
    padding: 0px;
}
body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
div.progress {
    max-width:300px;
    width: 100vw;
    
    float: left;
    position: relative;
    overflow: hidden;
    height: 100%;
    background-image: url("https://i.imgur.com/SKfSqEv.jpg");
    background-size: 500px;

    border-right: 1px solid black;
}
div.progress div.top {
    height: 100vh;
    position: relative;
    bottom: 100%;
}
div.progress div.top div.white{
    background-color: white;
    width:100%;
    height:100%;
}
div.progress div.top div.beer-top {
    /*background-image is at the bottom since it is bse64 */
    background-repeat: repeat-x;
    background-position-y: bottom;
    background-position-x: left;
    background-size: 302px, 100px;
    height: 100px;
}
/*div.progress div.top {
    background-position: bottom;
    height: 100%;
    background-image: url("img/beer-top.png");
}*/
div.main {
    float: left;
}

div.progress div.top div.beer-top {
    background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png');
}
<div class="progress">
        <div class="top">
            <div class="white"></div>
        <div class="beer-top"></div>
        </div>
        <!--<div class="progress-area">


        </div>-->
    </div>

    <div class="main">

    </div>
Run codeHide result

But there are two big problems:

  • :
     enter image description here
  • div.white height 100%, "100%". . :  enter image description here

?

CSS, (, 40% javascript).

: " div" , .

+4
2

CSS. "" div (, , , tweeking).

. JSfiddle:

            Promise.timeout = function (delay) {
            return new Promise((resolve) => {
                setTimeout(resolve, delay);
            });
        };
        Promise.animationFrame = function () {
            return new Promise((resolve) => {
                requestAnimationFrame(resolve);
            });
        };
        (async function () {
            const progress = document.querySelector("div.top");
            for (let i = 0, l = 1000; i < l; ++i) {
                progress.style.bottom = (100 - i / 10) + "%";
                await Promise.animationFrame();
            }
        })();
html, body, div {
    margin: 0px;
    padding: 0px;
}
body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
div.progress {
    max-width:300px;
    width: 100vw;
    
    float: left;
    position: relative;
    overflow: hidden;
    height: 100%;
    background-image: url("https://i.imgur.com/SKfSqEv.jpg");
    background-size: 500px;

    border-right: 1px solid black;
}
div.progress div.top {
    height: 100vh;
    position: relative;
    bottom: 100%;
}
div.progress div.top div.white{
    background-color: white;
    width:100%;
    height:100%;
}
div.progress div.top div.beer-top {
    /*background-image is at the bottom since it is bse64 */
    background-repeat: repeat-x;
    background-position-y: bottom;
    background-position-x: left;
    background-size: 302px, 100px;
    height: 100px;
}
/*div.progress div.top {
    background-position: bottom;
    height: 100%;
    background-image: url("img/beer-top.png");
}*/
div.main {
    float: left;
}

div.progress div.top div.beer-top {
    background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png');
}

.top {
    background: no-repeat;
    background-position: bottom;
    background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png'),linear-gradient(to top, rgba(0,0,0,0) 1%, rgba(255,255,255,1) 5%);
}
<div class="progress">
        <div class="top">
        </div>
        <!--<div class="progress-area">


        </div>-->
    </div>

    <div class="main">

    </div>
Hide result
+1

, , , :

  • margin-top: -1 div.beer-top, . divs , div .
  • display: flex, div.white , div.beer-top.

      div.progress div.top {
          height: 100%;
          position: relative;
          bottom: 100%;
          /**Modern flexbox layout*/
          display: flex;
          flex-direction: column;
      }
      div.progress div.top div.white{
          background-color: white;
          width:100%;
          /*fill remaining space*/
          flex-grow: 1;
      }
    

Promise.timeout = function (delay) {
            return new Promise((resolve) => {
                setTimeout(resolve, delay);
            });
        };
        Promise.animationFrame = function () {
            return new Promise((resolve) => {
                requestAnimationFrame(resolve);
            });
        };
        (async function () {
            const progress = document.querySelector("div.top");
            for (let i = 0, l = 1000; i < l; ++i) {
                progress.style.bottom = (100 - i / 10) + "%";
                await Promise.animationFrame();
            }
        })();
html, body, div {
    margin: 0px;
    padding: 0px;
}
body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
div.progress {
    max-width:300px;
    width: 100vw;
    
    float: left;
    position: relative;
    overflow: hidden;
    height: 100%;
    background-image: url("https://i.imgur.com/SKfSqEv.jpg");
    background-size: 500px;

    border-right: 1px solid black;
}
div.progress div.top {
    height: 100%;
    position: relative;
    bottom: 100%;
    /**Modern flexbox layout*/
    display: flex;
    flex-direction: column;
}
div.progress div.top div.white{
    background-color: white;
    width:100%;
    /*fill remaining space*/
    flex-grow: 1;
}
div.progress div.top div.beer-top {
    /*background-image is at the bottom since it is bse64 */
    background-repeat: repeat-x;
    background-position-y: bottom;
    background-position-x: left;
    background-size: 302px, 100px;
    height: 100px;
    
    /** this should hide the blinking orange line atop*/
    margin-top:-2px;
}
/*div.progress div.top {
    background-position: bottom;
    height: 100%;
    background-image: url("img/beer-top.png");
}*/
div.main {
    float: left;
}

div.progress div.top div.beer-top {
    background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png');
}
<div class="progress">
        <div class="top">
            <div class="white"></div>
        <div class="beer-top"></div>
        </div>
        <!--<div class="progress-area">


        </div>-->
    </div>

    <div class="main">

    </div>
Hide result
0

Source: https://habr.com/ru/post/1689654/


All Articles