<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="h5">Basic</div>
<div class="multi-step">
<ul class="multi-step-list">
<li class="multi-step-item current">
<div class="item-wrap">
<p class="item-title">Step One</p>
</div>
</li>
<li class="multi-step-item">
<div class="item-wrap">
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item">
<div class="item-wrap">
<p class="item-title">Step Three</p>
</div>
</li>
<li class="multi-step-item">
<div class="item-wrap">
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
<div class="h5">Clickable</div>
<div class="multi-step">
<ul class="multi-step-list">
<li class="multi-step-item active current">
<div class="item-wrap">
<p class="item-title">Step One</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Three</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
<div class="h5">Numbered - <code>.numbered</code></div>
<div class="multi-step numbered">
<ul class="multi-step-list">
<li class="multi-step-item active current">
<div class="item-wrap">
<p class="item-title">Step One</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Three</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
<div class="h5">Checked - <code>.checked</code></div>
<div class="multi-step checked">
<ul class="multi-step-list">
<li class="multi-step-item active completed">
<div class="item-wrap">
<p class="item-title">Step One</p>
</div>
</li>
<li class="multi-step-item active completed">
<div class="item-wrap">
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item active completed">
<div class="item-wrap">
<p class="item-title">Step Three</p>
</div>
</li>
<li class="multi-step-item active current">
<div class="item-wrap">
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
<div class="h5">Validation</div>
<div class="multi-step">
<ul class="multi-step-list">
<li class="multi-step-item active current">
<div class="item-wrap">
<p class="item-title">Step One</p>
</div>
</li>
<li class="multi-step-item active error">
<div class="item-wrap">
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item active error">
<div class="item-wrap">
<p class="item-title">Step Three</p>
</div>
</li>
<li class="multi-step-item active error">
<div class="item-wrap">
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
<div class="h5">Subtitle</div>
<div class="multi-step">
<ul class="multi-step-list">
<li class="multi-step-item active current">
<div class="item-wrap">
<p class="item-title">Step One</p>
<p class="item-subtitle">Information about this step.</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Two</p>
<p class="item-subtitle">Information about this step.</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Three</p>
<p class="item-subtitle">Information about this step.</p>
</div>
</li>
</ul>
</div>
<div class="h5">Badges</div>
<div class="multi-step">
<ul class="multi-step-list">
<li class="multi-step-item active current">
<div class="item-wrap">
<p class="item-title">Step One</p>
<p class="badge">10</p>
</div>
</li>
<li class="multi-step-item active">
<div class="item-wrap">
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item active error">
<div class="item-wrap">
<p class="item-title">Step Three</p>
<p class="badge">2</p>
</div>
</li>
<li class="multi-step-item active error">
<div class="item-wrap">
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
<div class="h5">Loading Step</div>
<div class="multi-step">
<ul class="multi-step-list">
<li class="multi-step-item active current multi-step-loading">
<div class="item-wrap">
<div class="busy-css"></div>
<p class="item-title">Step One</p>
</div>
</li>
<li class="multi-step-item active multi-step-loading">
<div class="item-wrap">
<div class="busy-css"></div>
<p class="item-title">Step Two</p>
</div>
</li>
<li class="multi-step-item active error multi-step-loading">
<div class="item-wrap">
<div class="busy-css"></div>
<p class="item-title">Step Three</p>
</div>
</li>
<li class="multi-step-item active error multi-step-loading">
<div class="item-wrap">
<div class="busy-css"></div>
<p class="item-title">Step Four</p>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
// Variables
$base-margin: 2em;
$base-padding: 1em;
$base-border-radius: .2em;
$screen-xs-max: 786px;
$text-color: #263238;
$text-color-inverted: #fff;
$clickable-hover: #d8f1ff;
$brand-primary: #3e5fd6;
$brand-success: #26a25f;
$brand-danger: #f82502;
$accent-dark: #253c8e;
$accent-light: #3855bd;
$accent-lighter: #ffffff;
$icon-danger: '!';
$icon-success: '✓';
$animation-time: 0.5s;
html, body {
background-color: #efefef;
}
// Multi-step code
.multi-step {
margin: ($base-margin / 2) 0;
}
// Setting up flexbox for list
.multi-step-list {
position: relative;
display: flex;
flex-direction: row;
justify-content: space-between;
list-style-type: none;
padding: 0;
.multi-step-item:first-child { margin-left: 0; }
.multi-step-item:last-child { margin-right: 0; }
}
// Defaults for each 'step'
.multi-step-item {
position: relative;
width: 100%;
margin: 0 ($base-margin / 6);
@media only screen and (max-width: $screen-xs-max) {
margin: 0 ($base-margin / 6);
}
z-index: 2;
border-radius: $base-border-radius;
// Step title and subtitle defaults
.item-title,
.item-subtitle {
position: relative;
margin: 0;
z-index: 2;
}
@media only screen and (max-width: $screen-xs-max) {
.item-subtitle { display: none; }
}
.item-title {
color: $brand-primary;
font-weight: 600;
margin: 0;
}
// Different step states [ active, current, completed, error]
&.active:hover { cursor: pointer; }
&.current .item-title,
&.current .item-subtitle {
color: $text-color-inverted;
}
&.active.current:hover .item-title,
&.active.current:hover .item-subtitle {
color: $brand-primary;
}
&.error:after {
position: absolute;
top: 50%;
z-index: 2;
transform: translateY(-50%);
right: .5em;
content: $icon-danger;
color: $brand-danger;
}
}
// Creates the 'arrow' effect / background colors
.item-wrap {
padding: $base-padding;
position: relative;
height: 100%;
&:before, &:after {
position: absolute;
left: 0;
content: ' ';
width: 100%;
height: 50.5%;
z-index: 1;
background-color: $accent-lighter;
}
// Top of the arrow
&:before {
top: 0;
transform: skew(20deg);
border-radius: .2em .2em 0 0;
}
// Bottom of the arrow
&:after {
bottom: 0;
transform: skew(-20deg);
border-radius: 0 0 .2em .2em;
}
}
// Changing arrow colors based on state
.current .item-wrap:before,
.current .item-wrap:after {
background-color: $brand-primary;
}
.active:hover .item-wrap:before,
.active:hover .item-wrap:after {
background-color: $clickable-hover;
}
.multi-step-item.error {
.item-title,
.item-subtitle {
padding-right: ($base-padding * 2);
}
}
// Changing step styles based on :first/:last step
.multi-step-item:first-child .item-wrap,
.multi-step-item:last-child .item-wrap {
width: 100%;
border-radius: $base-border-radius;
&:before, &:after { width: 50%; }
}
// If first step, only point on the right
.multi-step-item:first-child .item-wrap {
background: linear-gradient(to right, $accent-lighter 95%, transparent 5%);
&:before, &:after { left: 50%; }
}
.active.multi-step-item:first-child:hover .item-wrap {
background: linear-gradient(to right, $clickable-hover 95%, transparent 5%);
}
.current.multi-step-item:first-child .item-wrap {
background: linear-gradient(to right, $brand-primary 95%, transparent 5%);
}
// If last step, only indent on the left
.multi-step-item:last-child .item-wrap {
background: linear-gradient(to left, $accent-lighter 95%, transparent 5%);
&:before, &:after { right: 50%; }
}
.active.multi-step-item:last-child:hover .item-wrap {
background: linear-gradient(to left, $clickable-hover 95%, transparent 5%);
}
.current.multi-step-item:last-child .item-wrap {
background: linear-gradient(to left, $brand-primary 95%, transparent 5%);
}
// MSI Checked & Complete
.checked .multi-step-item.completed:after {
position: absolute;
top: 50%;
z-index: 2;
transform: translateY(-50%);
right: .5em;
content: $icon-success;
color: $brand-success;
}
// MSI Numbered
.numbered .multi-step-item {
counter-increment: step-counter;
.item-wrap { padding-left: ($base-padding * 5); }
// Adds number to step
&:before {
content: counter(step-counter);
position: absolute;
top: 50%;
left: .75em;
transform: translateY(-50%);
min-width: 1.65em;
padding: ($base-padding / 2) $base-padding;
z-index: 2;
font-size: .85em;
background-color: $accent-light;
color: $text-color-inverted;
font-weight: 600;
text-align: center;
border-radius: $base-border-radius;
}
}
// MSI w/ badge counts
.item-wrap .badge {
position: absolute;
right: .5em;
top: 50%;
transform: translateY(-50%);
z-index: 3;
}
.error .item-wrap .badge {
right: 2em;
~ .item-title,
~ .item-subtitle {
padding-right: 3em;
}
}
// MSI CSS Loader
.multi-step-loading { opacity: .75; }
.current.multi-step-loading:before {
border-color: $text-color-inverted;
border-top-color: transparent;
opacity: 1;
}
.busy-css {
z-index: 3;
content: '';
position: absolute;
top: 50%;
left: 50%;
margin-top: -.5em;
margin-left: -.5em;
border-radius: 50%;
width: 1em;
height: 1em;
border: .25em solid $accent-dark;
border-top-color: transparent;
animation: spin ($animation-time * 2) infinite linear;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
View Compiled
This Pen doesn't use any external JavaScript resources.