I have been working on a project where I want to show the monthly progress of a goal for a given year of a budget with a bootstrap progress bar. I would like to show the goal with a vertical line in the progress bar (see the image). I have put what I have been doing and what I would like to be able to do.
What I have:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 46.573611111111106%" aria-valuenow="46.573611111111106" aria-valuemin="0" aria-valuemax="100"></div>
</div>
What I would like to accomplish:
You could use a linear-gradient to achieve something quite close to your diagram
Effectively you would be adding two progress bar backgrounds with this approach.
However there is a complication, because the width
measurement of the target marker would need to be re-calculated every time the width
of the progress bar increases. It should be possible to carry out this recalculation of the marker's position dynamically with jQuery.
For the gradient, make the space between the amount of progress and the progress target with transparency rgba(255, 255, 255, 0.1)
then use whatever colour / width suits your purpose for the end marker:
In this example I have simply added 10% to the width
style of the second progess bar which I called .progress-bar-marker
:
HTML
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 46.573611111111106%" aria-valuenow="46.573611111111106" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar-marker" role="progressbar" style="width: 10%" aria-valuenow="46.573611111111106" aria-valuemin="0" aria-valuemax="100"></div>
</div>
CSS
.progress-bar-marker {
background-image: linear-gradient(90deg, rgba(225, 225, 225, 0.1) 97%, rgba(204, 0, 0, 1) 3%);
}
.progress-bar-marker {
background-image: linear-gradient(90deg, rgba(225, 225, 225, 0.1) 97%, rgba(204, 0, 0, 1) 3%);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 46.573611111111106%" aria-valuenow="46.573611111111106" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar-marker" role="progressbar" style="width: 10%" aria-valuenow="46.573611111111106" aria-valuemin="0" aria-valuemax="100"></div>
</div>
I wanted a progress bar with a target indicator, so I was struggling with this myself for a while too and in the end I think I found an elegant solution by stacking two layers in a grid. My solution is based on the premise of using as much native bootstrap 4 as possible.
I'm just learning CSS myself so I expect people to frown upon my solution and provide feedback for me to learn as well. Regardless, I would've been happy with this code snippet.
/* Css to show a target marker in the progress bar */
/*/* This allows us to overlay two objects. The first object (div) is the background, second object (div) is the foreground. */
.stack {
display: grid;
}
.stack>* {
grid-row: 1;
grid-column: 1;
}
/*/* Create a target box to contain the dot and the actual dot */
.targetdotbox {
margin-left: -17.5px;
padding-right: 17.5px;
}
.targetdot {
position: relative;
height: 20px !important;
width: 35px !important;
border-radius: 5px;
}
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<div class="card h-100">
<div class="card-header d-flex align-items-center justify-content-center" style="min-height: 3rem;">
<div class="text-center">A card with a progress bar and a target</div>
</div>
<div class="card-body">
<div class="d-flex justify-content-between mb-1">
<div class="col pl-0 text-center">
<span class="text-muted font-small d-block mb-2">Starting</span>
<span class="h5 text-dark font-weight-bold">Q1 2020</span>
</div>
<div class="col pl-0 text-center">
<span class="text-muted font-small d-block mb-2">Ending</span>
<span class="h5 text-dark font-weight-bold">Q4 2020</span>
</div>
</div>
<div class="text-center text-muted font-small d-block mb-2">Progression</div>
<div class="stack pl-2 pr-2"> <!-- Accomodate some extra space for the marker to stick out -->
<div class="progress" style="height: 20px">
<div class="progress-bar" role="progressbar" style="width: 50%;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">50%</div>
</div>
<div class="targetdotbox">
<div class="progress progress-bar targetdot bg-success" style="left: 75%">75%</div>
</div>
</div>
</div>
</div>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With