I am an experienced web developer with an eye for a solid UI/UX design. I have specialized in front-end development, responsive web design, modern web frameworks, and Content Management Systems. I also have experience in mobile apps development and back-end coding with PHP, Node.js, and Java. So I am a Full Stackish web developer with a strong passion for a beautiful front-end.
Published on January 1, 2018. Modified on January 2, 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.
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
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>
.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.
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.
.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!
24.10.2019
12.06.2019
26.03.2019
02.12.2018
10.11.2018
02.05.2018
04.04.2018
28.03.2018
25.10.2019
07.08.2019
10.07.2019
11.06.2019
09.06.2019
23.03.2019
23.03.2019
09.12.2018