I want to add background-color: #f8f8f8 class in step class. But when i added it then black horizontal line is not displaying after 1, 2. Where is the actual problem?
.main-progress {
text-align: center;
position: relative;
margin-top: 30px;
}
.step{
}
/*progressbar*/
#progressbar {
margin-bottom: 30px;
overflow: hidden;
/*CSS counters to number the steps*/
counter-reset: step;
}
#progressbar li {
list-style-type: none;
color: #12bd2a;
font-size: 14px;
width: 33.33%;
float: left;
position: relative;
font-weight: 600;
}
#progressbar .not-active:before {
color: #ffffff;
background: #4650ec;
}
#progressbar li:last-child{
color: #4650ec;
}
#progressbar li:before {
content: counter(step);
counter-increment: step;
width: 36px;
height: 36px;
line-height: 36px;
display: block;
font-size: 16px;
color: #ffffff;
background-color: #12bd2a;
border-radius: 25px;
margin: 0 auto 10px auto;
}
/*progressbar connectors*/
#progressbar li:after {
content: '';
width: 100%;
height: 5px;
background: black;
position: absolute;
left: -50%;
top: 16px;
z-index: -1; /*put it behind the numbers*/
}
#progressbar li:first-child:after {
/*connector not needed before the first step*/
content: none;
}
/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
#progressbar li.active:before, #progressbar li.active:after {
/*background-color: #12bd2a;*/
color: white;
}
<section class="step">
<div class="container">
<div class="row">
<div class="col-12">
<div class="main-progress">
<ul id="progressbar">
<li class="active">Upload Photos</li>
<li class="active">Model Settings</li>
<li class="not-active">Get Photos</li>
</ul>
</div>
</div>
</div>
</div>
</section>
try this code
css
.main-progress {
text-align: center;
position: relative;
margin-top: 30px;
z-index:9;
}
.step{
background-color: #f8f8f8;
}
/*progressbar*/
#progressbar {
margin-bottom: 30px;
overflow: hidden;
/*CSS counters to number the steps*/
counter-reset: step;
}
#progressbar li {
list-style-type: none;
color: #12bd2a;
font-size: 14px;
width: 33.33%;
float: left;
position: relative;
font-weight: 600;
}
#progressbar .not-active:before {
color: #ffffff;
background: #4650ec;
}
#progressbar li:last-child{
color: #4650ec;
}
#progressbar li:before {
content: counter(step);
counter-increment: step;
width: 36px;
height: 36px;
line-height: 36px;
display: block;
font-size: 16px;
color: #ffffff;
background-color: #12bd2a;
border-radius: 25px;
margin: 0 auto 10px auto;
}
/*progressbar connectors*/
#progressbar li.active:after {
content: '';
width: 100%;
height: 5px;
background:black;
position: absolute;
left: -50%;
top: 16px;
z-index: -1; /*put it behind the numbers*/
}
#progressbar li.not-active:after {
content: '';
width: 100%;
height: 5px;
background: black;
position: absolute;
left: -50%;
top: 16px;
z-index: -1; /*put it behind the numbers*/
}
#progressbar li:first-child:after {
/*connector not needed before the first step*/
content: none;
}
/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
#progressbar li.active:before, #progressbar li.active:after {
/*background-color: #12bd2a;*/
color: white;
}
#progressbar:before,#progressbar:after{content:"";display:block;clear:both;}
Add this line and then you will be able to add. It will work for sure.
You see the only problem to your code was the z-index, you put the line before the .step in the z-index. Might be good if you put some z-index to all affected elements.
.main-progress {
text-align: center;
position: relative;
margin-top: 30px;
}
.step {
background: grey;
z-index: -1;
}
/*progressbar*/
#progressbar {
margin-bottom: 30px;
overflow: hidden;
/*CSS counters to number the steps*/
counter-reset: step;
}
#progressbar li {
list-style-type: none;
color: #12bd2a;
font-size: 14px;
width: 33.33%;
float: left;
position: relative;
font-weight: 600;
}
#progressbar .not-active:before {
color: #ffffff;
background: #4650ec;
}
#progressbar li:last-child {
color: #4650ec;
}
#progressbar li:before {
content: counter(step);
counter-increment: step;
width: 36px;
height: 36px;
line-height: 36px;
display: block;
font-size: 16px;
color: #ffffff;
background-color: #12bd2a;
border-radius: 25px;
margin: 0 auto 10px auto;
}
/*progressbar connectors*/
#progressbar li:after {
content: '';
width: 100%;
height: 5px;
background: black;
position: absolute;
left: -50%;
top: 16px;
z-index: 1;
/*put it behind the numbers*/
}
#progressbar li:first-child:after {
/*connector not needed before the first step*/
content: none;
}
/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
#progressbar li.active:before,
#progressbar li.active:after {
/*background-color: #12bd2a;*/
color: white;
}
<section class="step">
<div class="container">
<div class="row">
<div class="col-12">
<div class="main-progress">
<ul id="progressbar">
<li class="active">Upload Photos</li>
<li class="active">Model Settings</li>
<li class="not-active">Get Photos</li>
</ul>
</div>
</div>
</div>
</div>
</section>
Related
I was created a simple progressbar with CSS & HTML. Here I used three classes active, inactive & done.
.container {
width: 600px;
margin: 100px auto;
}
.progressbar li {
list-style-type: none;
width: 25%;
float: left;
font-size: 12px;
position: relative;
text-align: center;
color: #7d7d7d;
}
.progressbar li:before {
width: 30px;
height: 30px;
content: "";
line-height: 30px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
border-radius: 50%;
background-color: white;
}
.progressbar li:after {
width: 100%;
height: 2px;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active {
color: green;
}
.progressbar li.active:before {
border-color: #55b776;
background-color: #55b776;
}
.progressbar li.active+li:after {
background-color: #55b776;
}
.progressbar li.done:before {
border-color: #55b776;
background-color: #55b776;
}
.progressbar li.done+li:after {
background-color: #55b776;
}
.progressbar li.inactive:before {
border-color: #7d7d7d;
background-color: #7d7d7d;
}
.progressbar li.inactive+li:after {
background-color: #7d7d7d;
}
<div class="container">
<ul class="progressbar">
<li class="done"></li>
<li class="active"></li>
<li class="inactive"></li>
</ul>
</div>
If the class is active it will show the circle with background-color: green,
If the class is inactive it will show the circle with background-color: grey
What i want is while using class 'done' i need to show the circle with background-color: green and tick mark inside the green circle like this. I tried a lot but not able to finish it. Please someone help me. Here is my working fiddle link
Use tick mark in content: "✓";
.container {
width: 600px;
margin: 100px auto;
}
.progressbar li {
list-style-type: none;
width: 25%;
float: left;
font-size: 12px;
position: relative;
text-align: center;
color: #7d7d7d;
}
.progressbar li:before {
width: 30px;
height: 30px;
content: "";
line-height: 30px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
border-radius: 50%;
background-color: white;
}
.progressbar li.done:before {
content: "✓";
color: #ffffff;
font-size: 20px;
}
.progressbar li:after {
width: 100%;
height: 2px;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active {
color: green;
}
.progressbar li.active:before {
border-color: #55b776;
background-color: #55b776;
}
.progressbar li.active + li:after {
background-color: #55b776;
}
.progressbar li.done:before {
border-color: #55b776;
background-color: #55b776;
}
.progressbar li.done + li:after {
background-color: #55b776;
}
.progressbar li.inactive:before {
border-color: #7d7d7d;
background-color: #7d7d7d;
}
.progressbar li.inactive + li:after {
background-color: #7d7d7d;
}
<div class="container">
<ul class="progressbar">
<li class="done"></li>
<li class="active"></li>
<li class="inactive"></li>
</ul>
</div>
As per your Requirements using css
.container {
width: 600px;
margin: 100px auto;
}
.progressbar li {
list-style-type: none;
width: 25%;
float: left;
font-size: 12px;
position: relative;
text-align: center;
color: #7d7d7d;
}
.progressbar li:before {
width: 30px;
height: 30px;
content: "";
line-height: 30px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
border-radius: 50%;
background-color: white;
}
.progressbar li:after {
width: 100%;
height: 2px;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active {
color: green;
}
.progressbar li.active:before {
border-color: #55b776;
background-color: #55b776;
}
.progressbar li.active + li:after {
background-color: #55b776;
}
.progressbar li.done:before {
border-color: #55b776;
background-color: #55b776;
}
.progressbar li.done + li:after {
background-color: #55b776;
}
.progressbar li.inactive:before {
border-color: #7d7d7d;
background-color: #7d7d7d;
}
.progressbar li.inactive + li:after {
background-color: #7d7d7d;
}
.progressbar li.done {
font-size: 16px;
position: relative;
}
.progressbar li.done:after {
content: " ";
display: block;
width: 0.3em;
height: 0.6em;
border: solid white;
border-width: 0 0.2em 0.2em 0;
position: absolute;
left: 4.2em;
top: 26%;
margin-top: -0.2em;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
z-index:9;
background-color: #55b776;
}
<div class="container">
<ul class="progressbar">
<li class="done"></li>
<li class="active"></li>
<li class="inactive"></li>
</ul>
</div>
You only need to set the content to the tick mark when the done class is applied.
.progressbar li.done:before {
content: "✔";
}
Wirking fiddle: https://jsfiddle.net/ordmpf59/
I already figure out to do the circle steps horizontally. But to do like the picture below is quite stressful. Can you figure out how to do this?
Here is code
.container-progress {
margin: 100px auto;
font-size: 24px;
font-weight: bold;
font-family: Verdana;
color: white;
margin-top: 50px;
padding: 0;
}
.progressbar {
margin: 0;
padding: 0;
counter-reset: step;
}
.progressbar li {
list-style-type: none;
width: 16%;
float: left;
font-size: 12px;
position: relative;
text-align: center;
text-transform: uppercase;
}
.progressbar li:before {
width: 5em;
height: 5em;
content: counter(step);
counter-increment: step;
line-height: 90px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
padding: 0;
border-radius: 50%;
background-color: black;
font-size: 18px;
font-weight: bold;
}
.progressbar li:after {
margin-top: 30px;
width: 100%;
height: .5em;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active {
color: white;
}
.progressbar li.active:before {
border-color: dodgerblue;
background: dodgerblue;
}
.progressbar li.active+li:after {
/*background-color: dodgerblue;*/
}
.progressbar label {
color: black;
}
<div class="container-progress">
<ul class="progressbar">
<li class="active active-step">
<label>step 1</label>
</li>
<li>
<label>step 2</label>
</li>
<li>
<label>step 3</label>
</li>
<li>
<label>step 4</label>
</li>
<li>
<label>step 5</label>
</li>
<li>
<label>step 6</label>
</li>
</ul>
</div>
Fiddle link
This uses a border on the ul to create your connecting lines and uses position:absolute to position the individual steps. You will probably need to tweak it a bit more but it could get you moving in the right direction.
Edit
To get the first three label to appear above ther cirlces, swap :before with :after. I've updated my code to reflect this.
.container-progress {
margin: 100px auto;
font-size: 24px;
font-weight: bold;
font-family: Verdana;
color: white;
margin-top: 50px;
padding: 0;
}
.progressbar {
margin: 0 50px;
padding: 0;
counter-reset: step;
position:relative;
border: 2px solid #7d7d7d;
border-left:none;
min-height:200px;
}
.progressbar li {
list-style-type: none;
width: 16%;
/*float: left;*/
font-size: 12px;
position: absolute;
text-align: center;
text-transform: uppercase;
}
/*First Three*/
.progressbar li:nth-child(-n+3)
{
top:-45px
}
/*Last Three*/
.progressbar li:nth-last-child(-n+3)
{
bottom:-75px
}
/*Left*/
.progressbar li:nth-child(1), .progressbar li:nth-child(6)
{
left:-45px
}
/*Middle*/
.progressbar li:nth-child(2), .progressbar li:nth-child(5)
{
left:calc(50% - 45px);
}
/*Right*/
.progressbar li:nth-child(3), .progressbar li:nth-child(4)
{
left:calc(100% - 45px);
}
.progressbar li:nth-last-child(-n+3):before, .progressbar li:nth-child(-n+3):after {
width: 5em;
height: 5em;
content: counter(step);
counter-increment: step;
line-height: 90px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
padding: 0;
border-radius: 50%;
background-color: black;
font-size: 18px;
font-weight: bold;
}
/*.progressbar li:after {
margin-top: 30px;
width: 100%;
height: .5em;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}*/
/*.progressbar li:first-child:after {
content: none;
}*/
.progressbar li.active {
color: white;
}
.progressbar li.active:before, .progressbar li.active:after {
border-color: dodgerblue;
background: dodgerblue;
}
.progressbar li.active+li:after {
/*background-color: dodgerblue;*/
}
.progressbar label {
color: black;
}
<div class="container-progress">
<ul class="progressbar">
<li class="active active-step">
<label>step 1</label>
</li>
<li>
<label>step 2</label>
</li>
<li>
<label>step 3</label>
</li>
<li>
<label>step 4</label>
</li>
<li>
<label>step 5</label>
</li>
<li>
<label>step 6</label>
</li>
</ul>
</div>
Something like below:
My Less looks as below at the moment.
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
&:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 13px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec ;
background: #27ae60 ;
border-radius: 19px;
margin: 0 auto 4px;
}
&:after {
content: '';
width: 85%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: -42%;
top: 10px;
z-index: 0;
}
&:first-child:after {
content: none;
}
}
.progress-payment li {
width: 50%;
}
.progressbar li.active{
&:after, &:before {
background: #success-btn;
color: #success-btn;
}
}
HTML
<ul class="progressbar">
<li class="active">Order Placed</li>
<li>Shipped</li>
<li>Completed</li>
<li>Settled</li>
</ul>
Please help
You can do this by using a linear-gradient background for the pseudo element that is producing the bar. The gradient is half-and-half, with completed color for first half and the pending color for rest.
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
background: linear-gradient(to right, #27ae60 50%, #B9B9B9 50%);
color: white;
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
If you want a slightly curved half-fill for the progress bar then you could use radial-gradient for the background like in the below snippet.
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
background: radial-gradient(50% 300% at 25% 50%, #27ae60 50%, #B9B9B9 40%);
color: white;
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
Note: Both the solutions assume that your target browsers are those that support gradients (IE10+).
Another approach is to use animation for this.
Since you are already using both pseudoelements in your list items. We will use a pseudoelement in the ul element to provide the empty progress line.
We will keep your other classes just for demo purposes but you can optimize this method way further. The principle would have to change to take into consideration the whole process from 0 to 100% from step 1 to 4, not to 1 to 2, 2 to 3, etc.
Here we go:
First we create our pseudoelement in the ul element just for the grey fallback.
.progressbar::after {
content: '';
width: 68%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: 17%;
top: 17px;
z-index: -2;
}
Then we scale down the ::after pseudoelement of the list item to 0 in the main axis. (use one : if you are providing older browser support).
Here we are keeping your class just as a selector, like I previously said you can make this even better but it would require changing some logic.
Here we also declare an animation we will create in the next step. What will it do? It will just scale back to 1 our pseudoelement.
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 100ms linear forwards;
background-color: #27ae60;
}
We define the keyframe:
#keyframes fill {
to {
transform: scaleX(1);
}
}
So far we get this:
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
position: relative;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar::after {
content: '';
width: 68%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: 17%;
top: 17px;
z-index: -2;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.half-complete:before {
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 3s linear forwards;
background-color: #27ae60;
}
#keyframes fill {
to {
transform: scaleX(1);
}
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
We are not quite there yet, we got the animation, but it starts from the center and we want a specific frame, when the bar is at 50%.
Since the browser creates multiple frames when you create an animation, you can get the one you want with the property animation-delay, normally you would use a positive value, but when you use a negative one, the animation starts from that point.
Lets make the animation start from the left with transform-origin: left and finish all the way to the right without using animation-delay yet:
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
position: relative;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar::after {
content: '';
width: 68%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: 17%;
top: 17px;
z-index: -2;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.half-complete:before {
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 3s linear forwards;
transform-origin: left;
background-color: #27ae60;
}
#keyframes fill {
to {
transform: scaleX(1);
}
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
Now using an animation-delay with a negative value:
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
position: relative;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar::after {
content: '';
width: 68%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: 17%;
top: 17px;
z-index: -2;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.half-complete:before {
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 3s linear forwards;
transform-origin: left;
animation-delay: -1.5s;
background-color: #27ae60;
}
#keyframes fill {
to {
transform: scaleX(1);
}
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
Since the total duration of the animation in the demo is 3s you just use half that as a negative value to get the 50%, see how the animation starts from there.
Then we just use animation-play-state: paused; to prevent the transition.
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
position: relative;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar::after {
content: '';
width: 68%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: 17%;
top: 17px;
z-index: -2;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.half-complete:before {
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 3s linear forwards;
transform-origin: left;
animation-delay: -1.5s;
animation-play-state: paused;
background-color: #27ae60;
}
#keyframes fill {
to {
transform: scaleX(1);
}
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
We can then clean it a little bit and in this demo we use some javascript to see how this can be manipulated:
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 100ms linear forwards; /* Use an easier value to represent percentages in a progress bar*/
transform-origin: left;
animation-delay: inherit; /* We inherit the animation-delay from the `li` element, which we can easily manipulate with javascript*/
animation-play-state: paused;
background-color: #27ae60;
}
Final Result:
var progress = document.getElementById("progress");
var progressBarLastItem = document.querySelector(".progressbar li:last-child");
progress.addEventListener("change", function() {
progressBarLastItem.style.animationDelay = "-" + this.value + "ms";
});
/*progressbar*/
.progressbar {
margin-bottom: 30px;
margin-top: 10px;
counter-reset: step;
clear: both;
list-style: none;
position: relative;
}
.progressbar li {
font-size: 12px;
width: 24%;
float: left;
position: relative;
text-align: center;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 25px;
line-height: 25px;
display: block;
font-size: 12px;
color: transparent;
border: 6px solid #ececec;
background: #27ae60;
border-radius: 19px;
margin: 0 auto 4px;
}
.progressbar li:after {
content: '';
width: 85%;
height: 3px;
position: absolute;
left: -42%;
top: 17px;
z-index: -1;
}
.progressbar::after {
content: '';
width: 68%;
height: 3px;
background: #B9B9B9;
position: absolute;
left: 17%;
top: 17px;
z-index: -2;
}
.progressbar li:first-child:after {
content: none;
}
.progress-payment li {
width: 50%;
}
.progressbar li.active:after,
.progressbar li.active:before {
background: #27ae60;
color: white;
}
.progressbar li.half-complete:before {
color: white;
}
.progressbar li.complete:after {
background: #27ae60;
}
.progressbar li.half-complete:after {
transform: scaleX(0);
color: white;
animation: fill 100ms linear forwards;
transform-origin: left;
animation-delay: inherit;
animation-play-state: paused;
background-color: #27ae60;
}
#keyframes fill {
to {
transform: scaleX(1);
}
}
<ul class="progressbar">
<li class="complete">Order Placed</li>
<li class="complete">Shipped</li>
<li class="active">Completed</li>
<li class="half-complete">Settled</li>
</ul>
<input id="progress" type="range" min="0" max="100">
We have used a pure css base progress bar.
The main css part is as below.
.container {
width: 600px;
margin: 20px auto;
}
.progressbar {
margin: 0;
padding: 0;
counter-reset: step;
}
.progressbar li {
list-style-type: none;
width: 25%;
float: left;
font-size: 12px;
position: relative;
text-align: center;
text-transform: uppercase;
color: #7d7d7d;
}
.progressbar li:before {
width: 30px;
height: 30px;
content: counter(step);
counter-increment: step;
line-height: 30px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
border-radius: 50%;
background-color: white;
}
.progressbar li:after {
width: 100%;
height: 2px;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
...............
The html
<div class="container">
<ul class="progressbar">
<li class="active">login</li>
<li>choose interest</li>
........
Complete sample could be found at https://jsfiddle.net/wbj7e79p/.
As you can see it mess up for seven step. The reason is .progressbar li width which is fixed to 25% we wanted to make it dynamic base on number of steps.
So we tried width : calc (100% / steps) or calc (100% / counter(steps)) but none of them worked. Any idea !
Please consider that we are building a component which build a progress bar on the fly, so we can not find the actual number of steps
Did you consider flexbox?
body {
font-family: 'Alegreya Sans', sans-serif;
margin: 0;
padding: 0;
}
.container {
margin: 20px auto;
}
.progressbar {
margin: 0;
padding: 0;
counter-reset: step;
display: flex;
}
.progressbar li {
list-style-type: none;
flex: 1;
font-size: 12px;
position: relative;
text-align: center;
text-transform: uppercase;
color: #7d7d7d;
}
.progressbar li:before {
width: 30px;
height: 30px;
content: counter(step);
counter-increment: step;
line-height: 30px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
border-radius: 50%;
background-color: white;
}
.progressbar li:after {
width: 100%;
height: 2px;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active {
color: green;
}
.progressbar li.active:before {
border-color: #55b776;
}
.progressbar li.active + li:after {
background-color: #55b776;
}
<h1>Four Steps</h1>
<div class="container">
<ul class="progressbar">
<li class="active">login</li>
<li>choose interest</li>
<li>add friends</li>
<li>View map</li>
</ul>
</div>
<h1> Seven Steps</h1>
<div class="container">
<ul class="progressbar">
<li class="active">login</li>
<li>choose interest</li>
<li>add friends</li>
<li>remove</li>
<li>fix users</li>
<li>review</li>
<li>save all</li>
</ul>
</div>
I have this progressbar and when it stands outside the <header> the lines between the steps is showing, but because of a needed z-index the lines doesn't show when its inside the <header> tag.
Like this:
If I change the z-index the line goes through the boxes like this:
I don't know if there's a workaround this, but if you have any ideas, please let me know!
My code for the relevant parts:
body {
background: #000;
}
header {
background-image: url("http://texturemate.com/image/view/1560/_original");
background-repeat: no-repeat;
background-size: cover;
padding: 0;
}
/*form styles*/
#msform {
width: 400px;
margin: 50px auto;
text-align: center;
position: relative;
}
/*progressbar*/
#progressbar {
margin-bottom: 30px;
overflow: hidden;
/*CSS counters to number the steps*/
counter-reset: step;
}
#progressbar li {
list-style-type: none;
color: white;
text-transform: uppercase;
font-size: 9px;
width: 33.33%;
float: left;
position: relative;
}
#progressbar li:before {
content: counter(step);
counter-increment: step;
width: 50px;
line-height: 50px;
display: block;
font-size: 10px;
color: #333;
background: white;
border-radius: 50%;
margin: 0 auto 5px auto;
}
/*progressbar connectors*/
#progressbar li:after {
content: '';
width: 100%;
height: 2px;
background: white;
position: absolute;
left: -50%;
top: 25px;
z-index: -1; /*put it behind the numbers*/
}
#progressbar li:first-child:after {
/*connector not needed before the first step*/
content: none;
}
/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
#progressbar li.active:before, #progressbar li.active:after{
background: #27AE60;
color: white;
}
<header>
<div class="container">
<div class="navbar">
<div class="navbar-brand">
<a href="/" id="logo" class="logo" alt="Home">
<img src="logo.png" class="hidden-sm"/>
</a>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12 progressbar">
<form id="msform">
<!-- progressbar -->
<ul id="progressbar">
<li class="active">Account Setup</li>
<li>Social Profiles</li>
<li>Personal Details</li>
</ul>
</form>
</div>
</div>
</div>
</header>
You can decrease the width of lines then adjust Left position to put it between circles ( from outer border of circles not from center ), also don't forget to set z-index: 1 for lines.
Something like this:
body {
background: #000;
}
header {
background-image: url("http://www.solidbackgrounds.com/images/2880x1800/2880x1800-air-force-dark-blue-solid-color-background.jpg");
background-repeat: no-repeat;
background-size: cover;
padding: 0;
}
/*form styles*/
#msform {
width: 400px;
margin: 50px auto;
text-align: center;
position: relative;
}
/*progressbar*/
#progressbar {
margin-bottom: 30px;
overflow: hidden;
/*CSS counters to number the steps*/
counter-reset: step;
}
#progressbar li {
list-style-type: none;
color: white;
text-transform: uppercase;
font-size: 9px;
width: 33.33%;
float: left;
position: relative;
}
#progressbar li:before {
content: counter(step);
counter-increment: step;
width: 50px;
line-height: 50px;
display: block;
font-size: 10px;
color: #333;
background: white;
border-radius: 50%;
margin: 0 auto 5px auto;
}
/*progressbar connectors*/
#progressbar li:after {
content: '';
width: 60%; /* Changed */
height: 2px;
background: white;
position: absolute;
left: -30%; /* Changed */
top: 25px;
z-index: 1; /* Changed */
}
#progressbar li:first-child:after {
/*connector not needed before the first step*/
content: none;
}
/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
#progressbar li.active:before, #progressbar li.active:after{
background: #27AE60;
color: white;
}
<header>
<div class="container">
<div class="navbar">
<div class="navbar-brand">
<a href="/" id="logo" class="logo" alt="Home">
<img src="logo.png" class="hidden-sm"/>
</a>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12 progressbar">
<form id="msform">
<!-- progressbar -->
<ul id="progressbar">
<li class="active">Account Setup</li>
<li>Social Profiles</li>
<li>Personal Details</li>
</ul>
</form>
</div>
</div>
</div>
</header>