skip to Main Content

I have multiple segments in a progress bar, in this example representing two states – achieved and planned values. The planned segment should have a border and nearing the end of the progress bar it should get the same border-radius as the background.

My problem is the following. Either the the radius is also visible within the progress bar, or I don’t use a border-radius for the right corner and use overflow: hidden; to "cut off" the unwanted overflowing part of the segment but then I lose the border on the radius.

Difficult to explain, images are probably better.

This is my current output:
output screenshot

This is basically how I want it to look. Is it possible with a reasonably simple solution?

how? (img)

.progress-bar {
  position: relative;
  height: 40px;
  width: 400px;
  background: lightgray;
  border-radius: 24px;
  .segment {
    position: absolute;
    height: 40px;
    box-sizing: border-box;
    &:first-of-type {
      border-radius: 24px 0 0 24px;
      width: 70%;
      background: blue;
    }
    &:last-of-type {
      left: 70%;
      width: 28%;
      background: lightblue;
      border: 1px solid blue;
    }
  }
}
<div class="progress-bar">
  <div class="segment"></div>
  <div class="segment"></div>
</div>

2

Answers


  1. This is almost what you want:

    .progress-bar {
      position: relative;
      height: 40px;
      width: 400px;
      
      .segment {
        position: absolute;
        height: 40px;
        box-sizing: border-box;
        
        &:first-of-type {
          border-radius: 24px 0 0 24px;
          width: 70%;
          background: blue;
        }
        
        &:last-of-type {
          left: 70%;
          width: 30%;
          background: linear-gradient(to left, transparent 10px, blue 10px 11px, lightblue 11px), radial-gradient(circle at right, lightgray, white);
          border: 1px solid blue;
          border-radius: 0 24px 24px 0;
        }
      }
    }
    

    Setting border-right: none doesn’t quite get the last part.

    Hope this helps!

    Login or Signup to reply.
  2. To create a really simple CSS progress-bar, use a single DIV element with a linear-gradient background-image.
    Pass the percentage value using CSS Custom Properties (Variables) like i.e:
    --percent:80; or just --p:80;

    .progress-bar {
      --p: 0;
      margin: 0.5em;
      height: 2rem;
      border-radius: 2rem;
      border: 1px solid blue;
      background-image: linear-gradient(90deg, blue calc(var(--p)*1%), lightblue calc(var(--p)*1%));
    }
    <div class="progress-bar" style="--p:80;"></div>
    <div class="progress-bar" style="--p:20;"></div>

    If you need the value visible inside the progress-bar, use a ::before or ::after pseudo-element:

    .progress-bar {
      --p: 0; 
      margin: 0.5em;
      height: 2rem;
      border-radius: 2rem;
      border: 1px solid blue;
      background-image: linear-gradient(90deg, blue calc(var(--p)*1%), lightblue calc(var(--p)*1%));
      overflow: hidden;
      
      &::after {
        counter-reset: p var(--p);
        content: counter(p) "%";
        line-height: 2em;
        color: #fff;
        margin-left: max(0rem, calc(var(--p)*1% - 2rem));
      }
    }
    <div class="progress-bar" style="--p:80"></div>
    <div class="progress-bar" style="--p:20"></div>

    If you need multiple segments, use multiple --p* properties

    .progress-bar {
      --p: 0; 
      margin: 0.5em;
      height: 2rem;
      border-radius: 2rem;
      border: 1px solid blue;
      background-image: linear-gradient(90deg,
        blue      calc(var(--p1)*1%),
        lightblue calc(var(--p1)*1%),
        lightblue calc(var(--p2)*1%),
        lightgray calc(var(--p2)*1%)
      );
    }
    <div class="progress-bar" style="--p1:50; --p2:80;"></div>
    <div class="progress-bar" style="--p1:20; --p2:90;"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search