Kombo
Kombo

Reputation: 294

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.

Upvotes: 1

Views: 6147

Answers (3)

Kalnode
Kalnode

Reputation: 11306

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>

Upvotes: 4

Temani Afif
Temani Afif

Reputation: 272965

No need flexbox or any complex stuff, you can simply use background for this:

.progress {
  width:200px;
  line-height:50px;
  margin:5px;
  text-align:center;
  font-size:30px;
  background:
    linear-gradient(green,green) left no-repeat,
    grey;
}
<div class="progress">
  100%
</div>

<div class="progress" style="background-size:50% 100%">
  50%
</div>

<div class="progress" style="background-size:75% 100%">
  75%
</div>

You can add more coloration to get closer to the visual you want:

.progress {
  width:200px;
  line-height:50px;
  margin:5px;
  text-align:center;
  font-size:30px;
  background:
    /*light overlay on the half top*/
    linear-gradient(rgba(255,255,255,0.3),rgba(255,255,255,0.3)) top/100% 50%,
    /*the two bars*/
    linear-gradient(#539041,#539041) left/5px 100%,
    linear-gradient(#539041,#539041) var(--p,100%) 0/5px 100%,
    /*the progress*/
    linear-gradient(#53e15a,#53e15a) left/var(--p,100%) 100%,
    /*the outer coloration*/
    #bbbbbb;
  background-repeat:no-repeat;
}
<div class="progress">
  100%
</div>

<div class="progress" style="--p:50%">
  50%
</div>

<div class="progress" style="--p:75%">
  75%
</div>

Upvotes: 1

Tarik Ayoub
Tarik Ayoub

Reputation: 1

Not sure if I understood well... Is it something like this that you want to achieve?

HTML

<section class="parent">
  <article class="child">
  </article>
  <article class="child">
  </article>
</section>

CSS

.parent {
  display: flex;
  width: 100vw;
  justify-content: space-around;
}

.child {
  width: 50%;
  height: 60px;
}

Link to codePen

Upvotes: -1

Related Questions