Search code examples
htmlcssflexbox

How to overlay two divs when using flexbox?


I'm using a parent div which is a flexbox. inside it, i require two child divs, each spanning the complete width of the parent div (width:100%) such that they are on top of each other (overlayed). This way, when you change the width of one child div, it shouldn't re-position the other child div in any way.

for example: i'm trying to create an progress bar of sorts like below: enter image description here

for this, i'm using two divs - the outer div (grey background) which renders the progress bar outline, and inner div (green background) which will show the progress. I also require to show the numerical percentage in the middle (81%). the inner div (green bg) width value will wary according to the numerical percentage. The numerical percentage should always be at the center of the OUTER DIV regardless of the progress (inner div width).

Could you please tell me how this can be achieved? Thanks.


Solution

  • For styling a basic progress bar

    It's probably best to make use of position: absolute to overlay elements (text label and bar progress) over top of a relative container.

    You could make use of flexbox for positioning purposes, however since you would already need to use position:absolute (for layering the text label) then you may as well use top, left and transform to position it (center-center).

    The inverse would be keeping the text relative,and using text-align:centeror flexbox rules to center it, meanwhile applyingposition:absolute` to the colored progress bar.

    For controlling the progress bar (dynamically)

    You would use Javascript to continually update the progress bar state. Exactly how you do this could be a variety of ways like binding (using libraries like React or Vue), passing data via HTML attributes or simply just doing an update to raw CSS via JS. In any case, control of the progress bar originates from JS.

    Alternatively if you just want a dummy progress bar with motion, without any direct control over the actual progress, then you could just simply animate the "fill" element by using CSS animation rules.

    Sample HTML+CSS static progress bar Codepen

    #container {
      position: relative;
      width: 400px;
      height: 40px;
      background-color: grey;
      border: 2px solid black;
    }
    
    #text {
        position: absolute;
        top: 50%;  
        left: 50%;
        transform: translate(-50%,-50%); 
    }
    
    #fill {
      background-color: green;
      width: 80%;
      height: 100%;
    }
    <div id="container">
      <div id="text">80%</div>
      <div id="fill">&nbsp;</div>
    </div>