Makes use of the aria-current="step" state (Docs) to programmatically indicate the current step instead of relying on color/styling.
Completed step
Active Step
Unvisited Step
The CSS:
/*Progress Indicator Styles*/
.wrapper {
width: 100%; /* Sets the width of the component */
}
.steps {
list-style:none; /*Removes the bullets*/
align-items: flex-start; /* Aligns to the top of the line */
display: flex; /*Creates the positioning rule for a flexbox*/
flex-direction: row; /*Positions the list items in a row*/
padding: 0;
}
.step-container {
display: flex; /* Allows for flex positioning of the number and label text */
flex-direction: column; /* Stacks circle and text */
align-items: center; /* Centers them horizontally */
width: 100px; /* Give it enough room for text */
}
.step-circle { /* Draws the circles around the step number*/
height: 40px;
width: 40px;
background-color: #3C66FA;
color: #FFF;
border-radius: 50%;
text-align: center;
line-height: 40px;
flex-shrink: 0; /* Keeps the circles from squishing into ovals when resizing */
}
.step-label { /* The label text beneath the step count */
margin-top: 8px;
font-size: 14px;
text-align: center;
color: #333;
}
.separator { /* The lines between the steps */
margin-top: 20px; /* Half the height of the circle to center the line */
border-top: 2px solid #3C66FA;
flex-grow: 1;
}
.active { /* Stling for the active step number */
background-color: #FFF;
border: 1px solid;
border-color: #3C66FA;
color: #3C66FA;
}
.unvisited { /* Styling for the unvisited step circles */
background-color: #E8E8E8;
border: 1px solid;
border-color: #3C66FA;
color: #000;
}
The HTML:
<div class="wrapper"> <ul class="steps"> <li class="step-container"> <div class="step-circle">1</div> <p class="step-label">Completed step</p> </li> <span class="separator"></span> <li class="step-container" aria-current="step"> <div class="step-circle active">2</div> <p class="step-label">Active Step</p> </li> <span class="separator"></span> <li class="step-container"> <div class="step-circle unvisited">3</div> <p class="step-label">Unvisited Step</p> </li> </ul> </div>
Styles the HTML5 <progress> element.
Note: the JAWS screen reader announces the progress bar role and the "70" as the value. The <span> with the percentage is not necessary for screen reader users but I added it for cognitive benefits. There are users who may not easily identify the percentage represented as changing colors so a textual representation is always good.
The CSS:
/*Progress Bar Styles*/
progress {
border-radius: 7px;
width: 200px;
height: 20px;
box-shadow: 1px 1px 4px rgba( 0, 0, 0, 0.2 );
}
progress::-webkit-progress-bar {
background-color: #E6E6E6; /*The background color of the non-active section*/
border: 1px solid; /*For increased contrast*/
border-radius: 7px; /*Curve those corners*/
}
progress::-webkit-progress-value {
background-color: #1DBA1A; /*Sets the color of the progress section*/
border-radius: 7px; /*More curved corners*/
box-shadow: 1px 0px 3px 1px #1DBA1A; /* Sets the shadow/hue around the progress bar */
}
progress::-moz-progress-bar {
/* style rules */
}
.progress-wrapper {
display: flex;
align-items: center; /* Vertically centers the items */
gap: 10px; /* Adds space between the label, bar, and text */
}
.percentage {
font-weight: bold;
color: #333;
}
The HTML:
<div class="progress-wrapper"> <label for="progressBar">File progress:</label> <progress id="progressBar" max="100" value="70"></progress> <span class="percentage">70%</span> </div>