Search code examples
javascripthtmlcsstimelinespacing

even spacing of html elements along timeline


I am trying to build a timeline that will scale, and add evenly spaced markers along side the 'timeline' so that the user can add additional times within an admin panel.

for instance, if there was 4 markers they would automatically split across 1/4 of the timeline regardless of width.

So like this <--|--|--|--|-->

Here is the code:

<style>

    body {
        background: black;
    }
#timeline {
    width:49.5%;
    background: url(http://brendonwells.co.uk/CPD/ice-training/img/timeline.png) center center no-repeat;
    background-size: 100%;
    height: 30px;
    position: relative;
}

.checkpoint {
    position: absolute;
    width: 1px;
    height: 13px;
    top: 13px;
    margin-left: auto;
    margin-right: auto;
    background: white;
    cursor: pointer;
}

.checkpoint:hover {
    background: white;
}

.checkpoint p {
    position: absolute;
    height: 30px;
    width:0;
    bottom: -35px!important;
    margin-left: auto;
    margin-right: auto;
    opacity: 0;
    transition: 0.4s;
    -o-transition: 0.4s;
    -ms-transition: 0.4s;
    -moz-transition: 0.4s;
    -webkit-transition: 0.4s;
}

.checkpoint:hover p {
    opacity: 1;
}

</style>

<div id="timeline">
                        <div class="checkpoint" >
                            <div class="rel">
                                <p>5 Minutes</p>
                            </div>
                        </div>

                        <div class="checkpoint" >
                            <p>10 Minutes</p>
                        </div>

                        <div class="checkpoint" >
                            <p>15 Minutes</p>
                        </div>

                        <div class="checkpoint" >
                            <p>20 Minutes</p>
                        </div>

                        <div class="checkpoint" >
                            <p>25 Minutes</p>
                        </div>

                        <div class="checkpoint" >
                            <p>30 Minutes</p>
                        </div>

                        <div class="checkpoint" >
                            <p>35 Minutes</p>
                        </div>
                    </div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

        <script>


        //Set slide times
        var time1 = 300;
        var time2 = 600;
        var time3 = 900;
        var time4 = 1200;
        var time5 = 1500;
        var time6 = 1800;
        var time7 = 2100;

        //Array to keep all the times
        var times = [time1, time2, time3, time4, time5, time6, time7];

        //variable to iterate through all of them
        var chosenTime = 0;

        //placement needs multiplier
        var multiplier = 1;

        function deliverTimes() {
            $('.checkpoint').each(function() {
                $(this).data("time", times[chosenTime]);
                //console.log("The data is " +  $(this).data('time'));
                chosenTime++;
                //console.log('running');
                placement($(this));
            });
        }

        //Call the function
        deliverTimes();

        //Clicking checkpoints
        $('.checkpoint').click(function() {
            video.currentTime = $(this).data("time");
        });

        //place the checkpoints

        function placement($div) {
            var width = $('#timeline').width();

            var margin = ((width/$('.checkpoint').length) - 10) * multiplier;
            console.log(margin);
            $div.css("left", margin + "px");
            multiplier++;
        }
                </script>

http://brendonwells.co.uk/timeline.html

I also prepared a link so that the CSS could be messed with etc..

Thanks


Solution

  • You can achieve your desired look utilizing CSS3 flexbox to handle the spacing and width. Add and remove checkpoints in the html and css will handle the rest. No JS required.

    HTML

    <div id="timeline">
        <div class="checkpoint">
            <div class="rel">
                <p>5 Minutes</p>
            </div>
        </div>
    
        <div class="checkpoint" >
            <p>10 Minutes</p>
        </div>
    
        <div class="checkpoint" >
            <p>15 Minutes</p>
        </div>
    
        <div class="checkpoint" >
            <p>20 Minutes</p>
        </div>
    
        <div class="checkpoint" >
            <p>25 Minutes</p>
        </div>
    
        <div class="checkpoint" >
            <p>30 Minutes</p>
        </div>
    
        <div class="checkpoint" >
            <p>35 Minutes</p>
        </div>
    </div>
    

    CSS

    body {
      background: #000;
    }
    
    #timeline {
      border-left: 1px solid #fff;
      border-right: 1px solid #fff;
      color: #fff;
      height: 30px;
      display: flex;
      position: relative;
    }
    #timeline::after {
      content: "";
      position: absolute;
      width: 100%;
      border-top: 1px dashed #fff;
      top: 50%;
      left: 0;
    }
    #timeline .checkpoint {
      flex: 1;
      position: relative;
      height: 50%;
      margin-top: 15px;
      border-right: 1px solid #fff;
    }
    #timeline .checkpoint:last-child {
      border-right: none;
    }
    #timeline .checkpoint p {
      width: 0;
      margin: 0;
      cursor: pointer;
      opacity: 0;
      transition: all .3s ease;
    }
    #timeline .checkpoint p:hover {
      opacity: 1;
    }
    

    https://jsfiddle.net/s5rL5eja/