skip to Main Content

Trying to make a progress bar (for music playback), but when width of the #progress bar is 100%, it doesn’t fill up the whole container .progress-bar (as seen in photo)(Light grey part depicts whole duration). I assume this is due to flexbox, as the dot fills up part of the space, but don’t know a workaround for this so that the dot stays at the end of #progress.

.progress-bar {
  display: flex;
  flex-direction: row;
  width: 50%;
  margin: 20px auto;
  background-color: #b3b3b3;
  height: 10px;
  border-radius: 10px;
}

#progress {
  background-color: #535353;
  position: relative;
  height: 100%;
  width: 100%;
  border-radius: 10px;
}

#progress-dot {
  position: relative;
  height: 25px;
  width: 25px;
  transform: translate(-12.5px, -7px);
  background-color: #000000;
  border-radius: 50%;
}
<div class="progress-bar">
  <div id="progress"></div>
  <div id="progress-dot"></div>
</div>

IMAGE
https://phpout.com/wp-content/uploads/2024/03/Olub3.png

2

Answers


  1. The issue is that the thumb is inside of the progress container and hence space must be allowed for it in a flex container.

    The transform is purely visual and does not affect actual layout.

    I’d suggest "removing" it from the flow by positioning it absolutely.

    .progress-bar {
      display: flex;
      flex-direction: row;
      width: 50%;
      margin: 20px auto;
      background-color: #b3b3b3;
      height: 10px;
      border-radius: 10px;
      position: relative;
    }
    
    #progress {
      background-color: #535353;
      height: 100%;
      width: 100%;
      /* equivalent to value */
      border-radius: 10px;
    }
    
    #progress-dot {
      position: absolute;
      left: 100%;
      /* equivalent to value */
      height: 25px;
      width: 25px;
      transform: translate(-50%, -7px);
      background-color: #000000;
      opacity: .25;
      border-radius: 50%;
    }
    <div class="progress-bar">
      <div id="progress"></div>
      <div id="progress-dot"></div>
    </div>
    Login or Signup to reply.
  2. You can position the components absolutely. You can also do this with just one element. Note that I’ve used a variable (custom property) to avoid value repetition.

    :root {
      --progress-dot-size: 25px;
      --progress-value: 75%;
    }
    
    .progress-bar {
      display: flex;
      flex-direction: row;
      align-items: center;
      width: 50%;
      margin: 20px auto;
      background-color: #b3b3b3;
      height: 10px;
      border-radius: 10px;
      position: relative;
    }
    
    .progress-bar::before {
      content: '';
      background-color: #535353;
      position: absolute;
      height: 100%;
      width: var(--progress-value);
      border-radius: 10px;
    }
    
    .progress-bar::after {
      content: '';
      position: absolute;
      left: var(--progress-value);
      transform: translateX(calc(0px - var(--progress-dot-size) / 2));
      height: var(--progress-dot-size);
      width: var(--progress-dot-size);
      background-color: #000000;
      border-radius: 50%;
      opacity: 0.2;
    }
    <div class="progress-bar"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search