简体   繁体   中英

How to make first li value 0 and then increment by 2 using css counter?

I am trying to make a steps progress bar. When i use the css counter it starts from 2 and goes like 2 4 6 8 10 12. i want it to be 0 2 4 6 8 10 instead. i tried changing the counter reset to 0 but that changes it to be 0 on all elements.

Here is my code

<div>
  <ul className="progressbar">
    <li id="0" onClick={ ()=> {this.changeColor(0)}} className=""></li>
    <li id="2" onClick={ ()=> {this.changeColor(2)}} className=""></li>
    <li id="4" onClick={ ()=> {this.changeColor(4)}} className=""></li>
    <li id="6" onClick={ ()=> {this.changeColor(6)}} className=""></li>
    <li id="8" onClick={ ()=> {this.changeColor(8)}} className=""></li>
    <li id="10" onClick={ ()=> {this.changeColor(10)}} className=""></li>
  </ul>
</div>

CSS for it:

.container {
  width: 600px;
  margin: 100px auto; 
}
.progressbar {
  counter-reset: step;
}
.progressbar li {
  list-style-type: none;
  width: 15%;
  float: left;
  font-size: 12px;
  position: relative;
  text-align: center;
  text-transform: uppercase;
  color: #7d7d7d;
}
.progressbar li:before {
  width: 30px;
  height: 30px;
  content: counter(step);
  counter-increment: step 2;
  line-height: 30px;
  border: 2px solid #7d7d7d;
  display: block;
  text-align: center;
  margin: 0 auto 10px auto;
  border-radius: 50%;
  background-color: white;
}
.progressbar li:after {
  width: 100%;
  height: 2px;
  content: '';
  position: absolute;
  background-color: #7d7d7d;
  top: 15px;
  left: -50%;
  z-index: -1;
}
.progressbar li:first-child:after {
  content: none;
}
.progressbar li.active:before {
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  margin-top: -4px;
  background-color: #FF5A66;
  border-color: #FF5A66;
  color: white;
}

Method to change the className of an element to highlight onClick

changeColor = (id) => {
  var value1 = document.getElementById("0");
  var value2 = document.getElementById("2");
  var value3 = document.getElementById("4");
  var value4 = document.getElementById("6");
  var value5 = document.getElementById("8");
  var value6 = document.getElementById("10");

  if (id == 0) {
    console.log(id);
    value1.className = "active";
    value2.className = "";
    value3.className = "";
    value4.className = "";
    value5.className = "";
    value6.className = "";
    this.setState({
      imageToShow: "images/icons/blob/good-blob.svg",
      textToShow: "I'm good"
    });
  }
}

When you reset a counter without stating the value (2nd param), the default is 0. However, counter increments are applied immediately, so if a counter's initial value is 0 , an element ( li::before in your code) which both displays an increments the counter would have a value of 2 and not 0 . If you need an element to have a counter of 0 , set the initial counter value to - the set value ( -2 in your case).

In your code - reset the counter to -2 , and the 1st increment will raise it to 0 :

.progressbar {
  counter-reset: step -2;
}

Example (HTML and not React):

 .progressbar { counter-reset: step -2; }.progressbar li { list-style-type: none; width: 15%; float: left; font-size: 12px; position: relative; text-align: center; text-transform: uppercase; color: #7d7d7d; }.progressbar li::before { width: 30px; height: 30px; content: counter(step); counter-increment: step 2; line-height: 30px; border: 2px solid #7d7d7d; display: block; text-align: center; margin: 0 auto 10px auto; border-radius: 50%; background-color: white; }.progressbar li::after { width: 100%; height: 2px; content: ''; position: absolute; background-color: #7d7d7d; top: 15px; left: -50%; z-index: -1; }.progressbar li:first-child::after { content: none; }.progressbar li.active::before { width: 40px; height: 40px; line-height: 40px; text-align: center; margin-top: -4px; background-color: #FF5A66; border-color: #FF5A66; color: white; }
 <div> <ul class="progressbar"> <li id="0"></li> <li id="2"></li> <li id="4"></li> <li id="6"></li> <li id="8"></li> <li id="10"></li> </ul> </div>

The second property of counter-reset is an optional integer which allows you to reset the counter to whatever you want. As yours starts at 2 you want to deduct/reset with -2

try the following

.progressbar {
  counter-reset: step -2;
}

In addition to the answers regarding your CSS question I adjusted your react code as a learning experience for myself.

I made some changes: Instead of clicking the buttons on the progressbar, it reacts to clicks on the complete bar and counts up on each click, reseting after being progressed to 100% at the end.

import React from "react";
import "./progress-bar.css";

class ProgressBar extends React.Component {
  constructor(props) {
    super(props);

    // the state defines the value of the last circle to set the class "active" to
    this.state = {
      value: 0
    };
  }

  // increment the state value by +1, 
  // or reset it to 0 if we reached the end of the progress bar
  increment() {
    this.setState((prevState, props) => {
      return {
        ...prevState,
        value: prevState.value === 5 ? 0 : prevState.value + 1
      };
    });
  }

  render() {
    let items = [];
    // create the corresponding circles with the IDs 0 - 10, incrementing by 2 each
    for (let id in [0, 2, 4, 6, 8, 10]) {
      items.push(
        <li
          id={id}
          key={id}
          // setting the className by comparing with the `state.value
          className={this.state.value >= id ? "active" : ""}
        ></li>
      );
    }

    return (
      <div onClick={() => this.increment()}>
        <ul className="progressbar">{items}</ul>
      </div>
    );
  }
}

export default ProgressBar;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM