How to create progress steps in CSS - css

I have a list of items that I want to turn into a progress steps in CSS.
ol {
width: 800px;
}
li {
display: inline-block;
color: transparent;
height: 25px;
width: 25px;
background-color: #abc;
border-radius: 50%;
border: 2px solid #08f;
margin-right: 150px;
}
li:last-child {
margin-right: 0;
}
li:not(:last-child)::before {
content: "";
border: 2px solid #08f;
margin-left:25px;
width: 153px;
display: inline-block;
}
<ol>
<li>Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
</ol>
What I ideally want to do is:
Stop Step 4 from disappearing off the bottom
Use the content of the <li> as a label above the circle
Make the total width equal to 80% of the viewport width
I'm just trying to teach myself some more advanced CSS, and I've seen this pattern used somewhere else - but I've been trying for an hour or so to get there with no joy.
This is a learning exercise for me, so would love some explanation with the answer if you have the time.
Thanks,

body {
display: grid;
place-items: center;
margin: 0;
padding: 36px;
}
ol {
display: flex;
width: 80%;
padding: 12px 0;
}
li {
position: relative;
padding: 0;
flex-grow: 1;
height: 2px;
background: #08f;
display: flex;
align-items: center;
}
li:last-child {
margin-right: 0;
flex-grow: 0;
}
li::after {
content: "";
position: absolute;
left: 0;
display: inline-block;
color: transparent;
height: 24px;
width: 24px;
background: #abc;
border-radius: 50%;
border: 2px solid #08f;
}
span {
position: absolute;
top: -36px;
left: 12px;
width: max-content;
transform: translateX(-50%);
z-index: 1;
}
<ol>
<li><span>Step 1</span></li>
<li><span>Step 2</span></li>
<li><span>Step 3</span></li>
<li><span>Step 4</span></li>
</ol>
In my code the nodes are the pseudo elements, and I use the flex-grow property so that the rules (that are the li tags) are properly distributed. font-size: 0 hides the text and removes it from the content-size of the elements as well.
---- edit:
I removed the font-size: 0 and added span tags for the labels and the css to position it.

Related

Display flex pseudo content has wrong width

I'm using pseudo content and a flex layout. Why does li:before not have the 10px width that Ive set?
https://codepen.io/adsfdsfhdsafkhdsafjkdhafskjds/pen/MWmwyOE
<ul>
<li>
<p>Lorum 123 dfjsd 3ijfadsifj sdfjoifj oijas fdjasf ijaio</p>
</li>
<li>
<p>37dkj dfjkasdfjdsijf dksdjf jfjiasdfmdafom</p>
</li>
</ul>
ul {
width: 150px;
margin: 0;
padding: 0;
list-style: none;
}
li {
display: flex;
margin-bottom: 20px
}
li:before {
content: "";
display: flex;
width: 10px;
flex-basis: 10px;
height: 10px;
background: red;
}
p {
margin: 0;
}
By default flex items don't shrink below their minimum content size. To change this, set the item's min-width or min-height.
https://developer.mozilla.org/en-US/docs/Web/CSS/flex
by default flex is setting the shrink value to 1.
If you add flex: 0 0 auto; to the pseudo element your code works.
ul {
width: 150px;
margin: 0;
padding: 0;
list-style: none;
}
li {
display: flex;
margin-bottom: 20px
}
li:before {
content: "";
display: flex;
width: 10px;
flex-basis: 10px;
height: 10px;
background: red;
flex: 0 0 auto;
}
p {
margin: 0;
}
<ul>
<li>
<p>Lorum 123 dfjsd 3ijfadsifj sdfjoifj oijas fdjasf ijaio</p>
</li>
<li>
<p>37dkj dfjkasdfjdsijf dksdjf jfjiasdfmdafom</p>
</li>
</ul>
try this
https://codepen.io/MuhammadRizwan/pen/bGWdpxB
update your class properties
li:before {
content: "";
display: flex;
width:100%;
min-width: 10px;
flex-basis: 10px;
height: 10px;
background: red;
}

CSS Progress Stepper not working on first step

I followed a tutorial to make the following progress stepper. It won't show step 1 when it is set to active. The other steps work when they are set to active. Can someone please help me understand what needs to be changed in the CSS to allow step 1 to show as active?
I realize I could choose a different stepper, but I like this one because it's CSS only and I would like to learn from this issue.
.container {
width: 100%;
position: absolute;
z-index: 1;
}
.progressbar li {
float: left;
width: 20%;
position: relative;
text-align: center;
list-style: none;
}
.progressbar {
counter-reset: step;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 30px;
height: 30px;
border: 2px solid #bebebe;
display: block;
margin: 0 auto 10px auto;
border-radius: 50%;
line-height: 27px;
background: white;
color: #bebebe;
text-align: center;
font-weight: bold;
}
.progressbar li:after {
content: '';
position: absolute;
width: 100%;
height: 3px;
background: #979797;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active+li:after {
background: #3aac5d;
}
.progressbar li.active+li:before {
border-color: #3aac5d;
background: #3aac5d;
color: white
}
<div class="container">
<ul class="progressbar">
<li class="active">Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
</ul>
</div>
If you add the active class to each <li> after it's done, then simply removing the +li from your selectors seems to work:
Fiddle: https://jsfiddle.net/fwpadbty/

long text in li disturbing the design

I have implemented the custom design for the progress. I have used ul-li for that. It's working fine when li has short text but failing with long text. Here is the jsfiddle for same. Can you please help here?
HTML
<div class="stepProgressBarContainer">
<ul class="stepProgessBar">
<li class="completed">Step 1 2 3 4 5 5</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
</ul>
</div>
SCSS
.stepProgressBarContainer {
width: 100%;
.stepProgessBar {
display: flex;
flex-direction: row;
justify-content: stretch;
padding: 0px;
li {
list-style-type: none;
position: relative;
text-align: center;
flex-grow: 1;
&:before{
content: '';
display: block;
width: 18px;
height: 18px;
-moz-border-radius: 9px;
-webkit-border-radius: 9px;
border-radius: 9px;
background: #FFFFFF;
border: 4px solid #CCCCCC;
box-sizing: border-box;
text-align: center;
margin: 0px auto 7.5px auto;
}
&:after{
content: '';
position: absolute;
width: 100%;
height: 4px;
background-color: #DDDDDD;
top:7px;
left: -50%;
z-index: -1;
}
&:first-child:after{
content: none;
}
&:last-child:before{
border-color:#2266E3;
}
&.completed{
+ :after{
background: linear-gradient(0deg, #2266E3, #2266E3);
}
&:before{
content: '\E73E';
border: 0;
background: #2266E3;
}
}
}
}
}
Note: It should be responsive.
Thanks in advance.
Problem with adding justify-content: stretch; in your code. I have replaced justify-content: space-between; for equal spacing between steps. And also added width: 100%; for your list to make it full width.
* {
box-sizing: border-box;
position: relative;
}
.stepProgressBarContainer {
width: 100%;
}
.stepProgressBarContainer .stepProgessBar {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0px;
}
.stepProgressBarContainer .stepProgessBar li {
list-style-type: none;
position: relative;
text-align: center;
display: block;
width: 100%;
}
.stepProgressBarContainer .stepProgessBar li:before {
content: '';
display: block;
width: 18px;
height: 18px;
-moz-border-radius: 9px;
-webkit-border-radius: 9px;
border-radius: 9px;
background: #fff;
border: 4px solid #ccc;
box-sizing: border-box;
text-align: center;
margin: 0px auto 7.5px auto;
}
.stepProgressBarContainer .stepProgessBar li:after {
content: '';
position: absolute;
width: 100%;
height: 4px;
background-color: #ddd;
top: 7px;
left: -50%;
z-index: -1;
}
.stepProgressBarContainer .stepProgessBar li:first-child:after {
content: none;
}
.stepProgressBarContainer .stepProgessBar li:last-child:before {
border-color: #2266e3;
}
.stepProgressBarContainer .stepProgessBar li.completed +:after {
background: linear-gradient(0deg, #2266e3, #2266e3);
}
.stepProgressBarContainer .stepProgessBar li.completed:before {
content: '\E73E';
border: 0;
background: #2266e3;
content: "\f007";
font-family: 'Font Awesome\ 5 Free';
font-weight: 900;
}
<div class="stepProgressBarContainer">
<ul class="stepProgessBar">
<li class="completed">Step 1 2 3 4 5 5</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
</ul>
</div>
Considering the responsive mode, something like this:
#media only screen and (max-width: 360px) {
.stepProgressBarContainer .stepProgessBar li {
min-width: 70px;
}
}
#media only screen and (min-width: 361px) {
.stepProgressBarContainer .stepProgessBar li {
min-width: 84px;
}
}

Setting overflow-y auto also sets overflow-x

I am trying to make a dropdown box with submenus appearing horizontally, which can also scroll vertically.
I have gotten everything working except for the scroll.
.dropdown-container {
background: white;
border: 1px solid #666;
cursor: pointer;
line-height: 24px;
height: 24px;
position: relative;
width: 150px;
}
.dropdown-container a {
color: black;
padding: 0 10px;
text-decoration: none;
}
.dropdown-container:after {
color: #666;
content: '\f107';
font-family: FontAwesome;
position: absolute;
right: 2px;
top: 0px;
}
.dropdown-container:before {
content: attr(data-content);
padding: 0 10px;
}
.dropdown-container li > a:not(:only-child):after {
content: '\f105';
font-family: FontAwesome;
position: absolute;
right: 4px;
top: 0px;
}
.dropdown-container ul {
background: white;
border: 1px solid #666;
display: none;
right: 1px; /*Why is it being nudged 1px right relative to parent?*/
list-style: none;
margin: 0;
max-height: 80px;
overflow-x: visible;
overflow-y: auto; /*This is the problematic line, remove this and the rest works*/
padding: 0;
position: relative;
width: 100%;
}
.dropdown-container:hover > ul {
display: block;
}
.dropdown-container ul li {
background: white;
position: relative;
}
.dropdown-container ul li:hover {
background: rgba(173, 216, 230, 0.6);
}
.dropdown-container ul li:hover > ul {
display: block;
}
.dropdown-container ul ul {
display: none;
position: absolute;
left: 150px;
width: 150px;
top: -1px; /*Another 1px adjustment required, why aren't they already aligned?*/
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<div class="dropdown-container" role="nav" data-content="Title">
<ul class="dropdown">
<li>
Select 1
</li>
<li>
Select 2
<ul>
<li>
Select 2.1
<ul>
<li>
Select 2.1.1
</li>
</ul>
</li>
<li>
Select 2.2
</li>
</ul>
</li>
<li>
Select 3
</li>
<li>
Select 4
</li>
</ul>
</div>
See JSfiddle here.
But if I set overflow-y on the <ul> to auto to enable scrolling then my submenus get hidden as in the snippet above.
I believe the problem is the same as in this question: when overflow-y: auto and overflow-x: visible, overflow-x is treated as auto too.
Unfortunately the solution suggested (wrapping the <ul> in a position: relative element) has not worked for me.
Does anyone know of another way around this?

How to create a horizontal node branch using bootstrap?

How do I create something like this in bootstrap ?
I was thinking of making 4 columns each one of the nodes using the grid layout. But the center node is taking more space than it should take.
Here is the bootply http://www.bootply.com/5ni6EJeTWM
As of now it looks like this
Here is what I came up with. It is not perfect but it should help you get on the track.
UPDATED the code - FULLY RESPONSIVE NOW !!!
.node-list {
margin-bottom: 10px;
overflow: hidden;
width: 100%;
padding: 0px;
margin: 0px;
}
.node-list li {
list-style-type: none;
color: white;
text-transform: uppercase;
font-size: 14px;
width: 25%;
float: left;
position: relative;
text-align: center;
}
.node-list li p {
color: #000;
font-weight: bold;
}
.node-list li:after {
content: '';
width: 20px;
height: 20px;
line-height: 20px;
display: block;
font-size: 18px;
color: #000;
background: #fff;
border: 10px solid #000;
margin: 0 auto 5px auto;
}
.node-list li:before {
content: '';
width: 100%;
height: 6px;
background: #000;
position: absolute;
left: -50%;
bottom: 20px;
z-index: -1
}
.node-list li:first-child:before {
content: none;
}
<ul class="node-list">
<li class="active">
<p>ABC</p>
</li>
<li class="">
<p>ABC</p>
</li>
<li class="">
<p>ABC</p>
</li>
<li class="">
<p>ABC</p>
</li>
</ul>

Resources