skip to Main Content

I am putting together a bootstrap progress bar with a number of step, each step is assigned against a variable (in %).

I am trying to position these variables on the bar.

The below picture is the current result I get to

enter image description here

This is not satisfactory as the awesomefont icons are contained within the bar and would like to have them on top like in this example. The problem on this picture is obviously that the bar length is not the same as the length used to position the icons.

enter image description here

Finally, it seems the left side of the icon starts at the % required to achieved the step. I would ideally prefer to have them centered on the targeted % – if the target is 5%, instead of having the icon start at 5% on the bar, I would like to have it so that the center of the icon is at 5%.

Any takers?

css

.bar-step {
    position:absolute;
    margin-top:-4px;
    z-index:1;
    font-size:12px;
}


.label-line {
    background: #000;
    height:50px;
    width:1px;
    margin-left: 5px;
}

.label-percent {
    margin-left: 5px;   
}

.dot {
    height: 25px;
    width: 25px;
    background-color: #bbb;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    outline: 2px solid white;
  }
  
  .dot i {
    position: initial;

  }
  .progress {
    position: relative;
  }

html

                    <div class="progress">

                        {% for venue_id, reward_position_on_bar in reward_positions.items %}
                        {%if venue_id == key%}
                        {%for reward_position_on_bar in reward_position_on_bar%}
                        <div class="bar-step" style="left: {{reward_position_on_bar.2}}%">
                          
                          <div class="dot">
                            <i class="fa-solid fa-gift fa-lg" style="color: #ffffff;"></i>
                          </div>
                        </div>
                        
                        {%endfor%}
                        {%endif%}

                        {% endfor %}

                        <div class="progress-bar bg-success" role="progressbar" style="width: {{value}}%; left: 0;" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="100"></div>

                    </div>

2

Answers


  1. Here’s one approach:

    <!-- Demonstration Purposes Only -->
    document.querySelector("button").addEventListener("click", e =>{
      document.querySelector(".bar").style.width = document.querySelector("input").value + "px";
    })
    :root {
      --icon-padding: 6px;
      --icon-width: 16px; /* Default FontAwesome Icon size */
      
      /* We need to calculate this offset in order to center the icons according to the percentage values */
      --icon-offset: calc( ( var(--icon-width) / 2 ) + ( var(--icon-padding) ) );
    }
    .bar {
      height: 20px;
      background: gray;
      width: 200px;
      position: relative;
      
      /* Demonstration Purposes Only */
      transition: width 500ms ease;
    }
    
    .bar i {
      position: absolute;
      left: 0;
      
      /* Vertical Centering: */
      top: 50%;
      transform: translateY(-50%);
    }
    i {
      background: white;
      padding: var(--icon-padding);
      border-radius: 50%;
      border: 1px solid black;
      box-sizing: border-box;
      opacity: 0.6; /* Visual debugging purposes */
    }
    i:before {
      box-sizing: border-box;
    }
    #p5 {
      left: calc(5% - var(--icon-offset));
    }
    #p15 {
      background: orange;
      left: calc(15% - var(--icon-offset));
    }
    #p50 {
      background: tomato;
      left: calc(50% - var(--icon-offset) );
    }
    #p75 {
      background: skyblue;
      left: calc(75% - var(--icon-offset));
    }
    #p100 {
      background: yellowgreen;
      left: calc(100% - var(--icon-offset));
    }
    /* Debugging Purposes only */
    i:after {
      display: block;
      color: black;
      font-size: 12px;
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      bottom: -25px;
    }
    i#p5:after {
      content: "5%";
    }
    i#p15:after {
      content: "15%";
    }
    i#p50:after {
      content: "50%";
    }
    i#p75:after {
      content: "75%";
    }
    i#p100:after {
      content: "100%";
    }
    .bar:after {
      content: "";
      display: block;
      position: absolute;
      height: 100px;
      background: black;
      width: 1px;
      left: 50%;
      top: -50%;
    }
    .bar:before {
      content: "";
      display: block;
      position: absolute;
      height: 100px;
      background: black;
      width: 1px;
      left: 100%;
      top: -50%;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"/>
    
    <div class="bar">
      <i id="p5" class="fa-solid fa-gift"></i>
      <i id="p15" class="fa-solid fa-gift"></i>
      <i id="p50" data-percentage="50%" class="fa-solid fa-gift"></i>
      <i id="p75" class="fa-solid fa-gift"></i>
      <i id="p100" class="fa-solid fa-gift"></i>
    </div>
    
    <!-- Demonstration Purposes Only -->
    <p style="margin-top: 100px;">
      <input type="number" value="200" />
      <button>Change Bar Width</button>  
    </p>

    Notes:

    You can ignore the CSS section that’s for visual debugging purposes.

    Basically, we use some CSS variables to set the icon size along with the padding that we add for styling purposes and then use that to calculate an offset in order to center the icons right at the percentage point in the bar.

    Login or Signup to reply.
  2. Changed your css a bit. Marked the imported lines with comments.

    .progress-container {
      margin: 1.5rem;
      padding: 1.5rem;
      background: tomato;
      font-size: 12px;
    }
    
    .progress {
      position: relative;
      overflow: visible !important; /* override the rule in bootstrap */
    }
    
    .bar-step {
      position: absolute;
      align-self: center;
    }
    
    .dot {
      height: 25px;
      width: 25px;
      margin-left: -12.5px; /* to center the icon at the percentage line */
      background-color: #bbb;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      outline: 2px solid white;
    }
    
    .marker-lines {
      width: 100%;
      margin-top: .75rem;
      padding: .2rem;
      color: green;
      border: 2px solid green;
      border-top: 0;
      border-bottom: 0;
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer"
    />
    
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    
    
    <div class="progress-container">
      <div class="progress">
        <div class="bar-step" style="left: 0%;">
          <div class="dot">
            <i class="fa-solid fa-gift fa-lg" style="color: #ffffff;"></i>
          </div>
        </div>
    
        <div class="bar-step" style="left: 20%;">
          <div class="dot">
            <i class="fa-solid fa-gift fa-lg" style="color: #ffffff;"></i>
          </div>
        </div>
    
        <div class="bar-step" style="left: 100%;">
          <div class="dot">
            <i class="fa-solid fa-gift fa-lg" style="color: #ffffff;"></i>
          </div>
        </div>
    
        <div class="progress-bar bg-success" role="progressbar" style="width: 50%; left: 0;" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="100"></div>
    
      </div>
      <div class="marker-lines">
        <span>0</span>
        <span class="float-end">100</span>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search