Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a simple react multistep control

I am a newbie with CSS and trying to implement a multistep React control based on some existing code (for the moment the steps are static, I will make things dynamic once I have figured out my problem):

import styles from "./ProgressSteps.module.css";

const ACProgressSteps = () =>{
return(
    <div className={styles.container}>
        <ul className={`${styles.progressbar} ${styles.nobullets}`}>
            <li className={styles.selected}>Aircraft Type</li>
            <li>Weight  Index</li>
            <li>Airport Times</li>
            <li>Documents</li>
            <li>Tada</li>
        </ul>
    </div>
)}

The active step is identified by {styles.selected} (and all previous steps with this style applied should also be marked as green). The corresponding styles are given below (I import them in my control):

.container{
    width: 100%;
    position: absolute;
    z-index: 1;
}

.progressbar{
    counter-reset: step;
}



ul.nobullets {
    list-style-type: none; /* Remove bullets */
    padding: 0; /* Remove padding */
    margin: 0; /* Remove margins */
}

.progressbar li{
    float: left;
    width: 20%;
    position: relative;
    text-align: center;
}

.progressbar li:before{
    counter-increment: step;
    content:counter(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.selected + li:after{
    background: #3aac5d;
}

.progressbar li.selected + li:before{
   border-color: #3aac5d;
   background: #3aac5d;
   color: white
}

However, in the previous example, instead of having the first "step" selected, it's the second is as illustrated below (it seems I am having some kind of "off-by one issue"):

enter image description here

Any help on fixing this would be greatly appreciated!

Edit: as a courtesy to the original author, the example that I adapted can be found here: https://steemit.com/utopian-io/@alfarisi94/how-to-make-step-progress-bar-only-using-css

like image 244
BigONotation Avatar asked Feb 26 '26 12:02

BigONotation


1 Answers

The + sign selector selects the elements that are placed immediately after the specified element, so li.selected + li:before targets <li>Weight Index</li> as it's right after the li with a class name of .selected.

The following will fix it:

.progressbar li.selected:after {
  background: #3aac5d;
}

.progressbar li.selected:before {
  border-color: #3aac5d;
  background: #3aac5d;
  color: white;
}

const ACProgressSteps = () => {
  return (
    <div className='container'>
      <ul className='progressbar nobullets'>
        <li className='selected'>Aircraft Type</li>
        <li>Weight Index</li>
        <li>Airport Times</li>
        <li>Documents</li>
        <li>Tada</li>
      </ul>
    </div>
  );
};

ReactDOM.render(<ACProgressSteps />, document.getElementById('root'));
.container {
  width: 100%;
  position: absolute;
  z-index: 1;
}

.progressbar {
  counter-reset: step;
}

ul.nobullets {
  list-style-type: none; /* Remove bullets */
  padding: 0; /* Remove padding */
  margin: 0; /* Remove margins */
}

.progressbar li {
  float: left;
  width: 20%;
  position: relative;
  text-align: center;
}

.progressbar li:before {
  counter-increment: step;
  content: counter(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.selected:after {
  background: #3aac5d;
}

.progressbar li.selected:before {
  border-color: #3aac5d;
  background: #3aac5d;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
like image 114
Zsolt Meszaros Avatar answered Mar 01 '26 02:03

Zsolt Meszaros



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!