Auralinna.blogTero Auralinna's blog about intriguing world of web development.

I'm a Full Stackish developer with a strong passion to a beautiful front end. I have mainly focused on front-end development, responsive web design, back end coding with PHP and Java, Content Management Systems, modern web frameworks and DevOps.

Navigation wizard example with equal width steps and flexible width of last step

01.01.2018

Title of this blog post is a little bit monstrous but I try my best to explain it. I had an interesting challenge at work a while ago. My task was to create a navigation wizard which all steps should have equal width except a last one. Width of the last step should be depended on text width. However the last step width shouldn't exceed other steps width either.

Navigation wizard example

In the end it was pretty easy to implement with CSS Flexbox, calc and counters. Following demo probably explains this better than a thousand words. This example is not optimized for a small mobile screen sizes. It scales but in some point it won't fit anymore.

Embedded content: https://codepen.io/teroauralinna/pen/MrmryX

1. First version of the navigation wizard

HTML

Let's start by creating a simple list and links for the wizard steps.

<ul class="wizard">
  <li class="wizard-step">
    <a href="#1" class="wizard-step-link">
      This is the first step
    </a>
  </li>
  <li class="wizard-step">
    <a href="#2" class="wizard-step-link">
      This is the second step
    </a>
  </li>
  <li class="wizard-step">
    <a href="#3" class="wizard-step-link">
      This is the third step
    </a>
  </li>
  <li class="wizard-step">
    <a href="#4" class="wizard-step-link">
      This is the fourth step
    </a>
  </li>
  <li class="wizard-step">
    <a href="#5" class="wizard-step-link">
      This is the last step with flexible width
    </a>
  </li>
</ul>

CSS

.wizard {
  counter-reset: stepNo;
  display: -webkit-flex;
  display: -ms-flex;
  display: flex;
  margin: 0;
  padding: 0;
}

.wizard-step {
  -webkit-flex: 1 0 0px;
      -ms-flex: 1 0 0px;
          flex: 1 0 0px;
  list-style: none;
  padding: 0 2% 0 0;
  position: relative;
}
.wizard-step::before {
  border-top: 3px solid #333;
  content: "";
  left: 0;
  position: absolute;
  right: 0;
  top: 25px;
}
.wizard-step:last-child {
  border: 0;
  margin: 0;
  padding: 0;
}
.wizard-step:last-child::before {
  border: 0;
}

.wizard-step-link {
  color: #333;
  display: block;
  font-size: 1rem;
  font-weight: bold;
  position: relative;
  text-decoration: none;
  z-index: 10;
}
.wizard-step-link:before {
  background: #333;
  color: #fff;
  counter-increment: stepNo;
  content: counter(stepNo) ".";
  display: block;
  font-size: 2rem;
  height: 50px;
  line-height: 50px;
  margin-bottom: 12px;
  text-align: center;
  width: 50px;
}
.wizard-step-link:hover,
.wizard-step-link:focus {
  color: #000;
  text-decoration: none;
}
.wizard-step-link:hover:before,
.wizard-step-link:focus:before {
  background: #fff;
  border: 1px solid #333;
  color: #333;
}

CSS counter feature is used to generate step numbering. This easily keeps step numbers dynamic regardless of how many steps there are.

2. Add flexible width to the last step

Now we have the navigation wizard with equal width steps. We need to change the last step styles slightly to make it flexible based on a text width.

CSS

.wizard-step:last-child {
  -webkit-flex: 0 0 auto;
      -ms-flex: 0 0 auto;
          flex: 0 0 auto;
}
.wizard-step:last-child:nth-child(2) {
  max-width: calc(100% / 2);
}
.wizard-step:last-child:nth-child(3) {
  max-width: calc(100% / 3);
}
.wizard-step:last-child:nth-child(4) {
  max-width: calc(100% / 4);
}
.wizard-step:last-child:nth-child(5) {
  max-width: calc(100% / 5);
}
.wizard-step:last-child:nth-child(6) {
  max-width: calc(100% / 6);
}
.wizard-step:last-child:nth-child(7) {
  max-width: calc(100% / 7);
}
.wizard-step:last-child:nth-child(8) {
  max-width: calc(100% / 8);
}
.wizard-step:last-child:nth-child(9) {
  max-width: calc(100% / 9);
}
.wizard-step:last-child:nth-child(10) {
  max-width: calc(100% / 10);
}

Calc is pretty well supported by browsers but to broaden browser support you can of course calculate max-width by yourself.

Following SCSS for loop snippet can be used to generate CSS rules and calculate max-width values.

@for $i from 2 through 10 {
  .wizard-step:last-child:nth-child(#{$i}) {
    max-width: (100% / $i);
  }
}

Let me know if you have any thoughts about the implementation or tips how to improve!

Latest blog posts

Latest CodePens

View all CodePens