Search code examples
javascriptcsshtmldivider

Progress Bar with Cycle Divider


I am trying to create a progress bar and I want a cycle divider so that I can divide the situations I have enter image description here

Can someone give me a solution ?


Solution

  • I tried to recreate your progress bar, see my fiddle here.

    Just add a class .current to the .cycle you want to be currently highlighted. I used pure CSS on this with floats for better compatibility.

    You can add numbers to the circles by adding .counter class to the .progress element.

    .progress, .progress * { box-sizing: border-box; }
    .progress {
        width: 410px;
        padding: 15px;
        padding-left: 25px;
        margin: 20px;
        border-radius: 3px;
        background: #ddd;
    }
    .progress .cycle {
        width: 90px;
        height: 10px;
        border: 1px solid #111;
        float: left;
        position: relative;
        background: #555;
    }
    .progress .cycle:first-of-type {
        width: 0px;
    }
    .progress .cycle.current ~ .cycle {
        background: #fff;
    }
    .progress .cycle:after {
        content: '';
        width: 30px;
        height: 30px;
        border: 1px solid #111;
        border-radius: 50%;
        position: absolute;
        top: -12px;
        right: -15px;
        z-index: 2;
        background: #555;
    }
    .progress .cycle.current:after {
        background: deepskyblue;
    }
    .progress .cycle.current ~ .cycle:after {
        background: #fff;
    }
    /* With Counters */
    .progress.counter {
        counter-reset: cycle; 
    }
    .progress.counter .cycle:after {
        counter-increment: cycle;
        content: counter(cycle);
        line-height: 30px;
        text-align: center;
        font-family: Arial;
    }
    Using Floats
    <div class="progress">
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle current"></div>
        <div class="cycle"></div>
        <div style="clear: both; height: 0px;">&nbsp;</div>
    </div>
    <div class="progress">
        <div class="cycle"></div>
        <div class="cycle current"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div style="clear: both; height: 0px;">&nbsp;</div>
    </div>
    <div class="progress counter">
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle current"></div>
        <div style="clear: both; height: 0px;">&nbsp;</div>
    </div>


    I also created another demo here using the CSS3 flex-box approach.

    The contents of the .progress element will now adjust according to the width of the element. This gives way to adding more cycles dynamically and adjusting the progress bar width without worrying about fixed widths. Also, this prevents the cycles from wrapping in very compressed widths.

    body { font-family: Arial; font-weight: normal;}
    .progress, .progress * { box-sizing: border-box; }
    .progress {
        padding: 25px;
        margin: 20px;
        border-radius: 3px;
        display: flex;
        flex-flow: row nowrap;
        background: #ddd;
    }
    .progress .cycle {
        height: 10px;
        border: 1px solid #111;
        flex: 1 0 auto;
        position: relative;
        background: #555;
    }
    .progress .cycle:first-of-type {
        width: 0px;
        flex: 0 0;
    }
    .progress .cycle.current ~ .cycle {
        background: #fff;
    }
    .progress .cycle:after {
        content: '';
        width: 30px;
        height: 30px;
        border: 1px solid #111;
        border-radius: 50%;
        position: absolute;
        top: -12px;
        right: -15px;
        z-index: 2;
        background: #555;
    }
    .progress .cycle.current:after {
        background: deepskyblue;
    }
    .progress .cycle.current ~ .cycle:after {
        background: #fff;
    }
    /* With Counters */
    .progress.counter {
        counter-reset: cycle; 
    }
    .progress.counter .cycle:after {
        counter-increment: cycle;
        content: counter(cycle);
        line-height: 30px;
        text-align: center;
        font-family: Arial;
    }
    /* Fixed Width */
    .fixed1 {
        width: 400px;
    }
    .fixed2 {
        width: 300px;
    }
    <h2>Using Flex</h2>
    6 cycles (fixed width)
    <div class="progress fixed1">
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle current"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div style="clear: both; height: 0px;">&nbsp;</div>
    </div>
    9 cycles (100% width)
    <div class="progress">
        <div class="cycle"></div>
        <div class="cycle current"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
    </div>
    5 cycles (fixed width, numbered)
    <div class="progress counter fixed2">
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle current"></div>
    </div>
    7 cycles (100%, numbered)
    <div class="progress counter">
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
        <div class="cycle current"></div>
        <div class="cycle"></div>
        <div class="cycle"></div>
    </div>

    The only problem for the CSS3 flexbox approach is browser support. If the browser support is alright with you, then go for the flex-box approach :)