Полоса хода, выполненная из сплошной линии, с точками в виде шагов

Я пытаюсь создать вертикальную полосу прогресса с 8 точками на сплошной линии (с восьмым на конце), где каждая точка обозначает один шаг в этом процессе. См. Прилагаемый скриншот (внизу, чтобы этот вопрос не был разбит).

Конечно, я попытался сделать некоторые вещи в HTML и CSS, которые вы можете увидеть в этой скрипке (код ниже). Проблема заключается в том, что я не могу найти способ создать 7 точек на светло-зеленой линии, не добавляя еще 8 divs (8, потому что первая также должна быть там).

Функционально, я хочу, чтобы JS проверял value progressNow -div, умножил его на 100 и добавил, что в качестве высоты CSS для classа progressNow . Проблема заключается в том, что точка будет двигаться, а не заполнять бар. (Имеет ли это смысл?)

Это заставило меня подумать о создании элемента SVG в форме, которую вы можете увидеть на скриншоте, с gradleиентом, который изменяет местоположение на основе n-го шага в этом процессе. Я знаю, что это сработает, и я знаю, что смогу заставить его работать, но мне было интересно, есть ли другой, возможно, более простой способ достичь того, чего я пытаюсь достичь.

HTML

 

CSS

 #progress { position: relative; } #progress .progressBar { height: 800px; width: 6px; background: #8fe4bf; position: absolute; } #progress .progressNow { height: 100px; width: 6px; background: #00b164; position: absolute; } #progress .progressNow::after { content: ""; width: 16px; height: 16px; border-radius: 50%; background: #00b164; display: block; margin-left: -5px; position: absolute; top: 90px; } 

Желаемый результат (в этом случае value progressNow равно 2 )

введите описание изображения здесь

Мое решение похоже на @ Stewartside, за исключением того, что использует Flexbox для размещения всех одинаково. Также очень легко изменить высоту.

 ul.progress-bar { height: 300px; list-style: none; margin: 0; padding: 0; position: relative; display: flex; flex-direction: column; justify-content: space-between; overflow: hidden; } ul.progress-bar::after { content: ""; position: absolute; top: 0; left: 5px; background: #777; width: 5px; height: 100vh; } ul.progress-bar li { background: #000; border-radius: 100px; width: 15px; height: 15px; z-index: 1; position: relative; } ul.progress-bar li.stop ~ li { background: #777; } ul.progress-bar li.stop ~ li::after { height: 0; } ul.progress-bar li::after { content: ""; position: absolute; bottom: 0; left: 5px; background: #000; width: 5px; height: 100vh; } 
 

Вот CSS-решение с минимальным отсутствием. элементов. В этом подходе мы используем комбинацию linear-gradients и radial-gradients для создания вертикальной линии и точек.

Элемент parent #progress-bar создает светлую (начальную) линию и круги, в то время как одни и те же gradleиенты добавляются к элементу child #progress-now который позиционируется абсолютно относительно родителя. Единственное различие заключается в том, что height элемента #progress-now определяется на основе атрибута value .

Решение будет работать, даже если значения находятся во фракциях. Я знаю, что вы используете его для отслеживания шагов, но это просто дополнительное использование (дует моя собственная труба: D).

 window.onload = function() { var val = document.getElementById('progress-now').getAttribute('value'); var progress = (val * 50 > 400) ? 400 : val*50; /* 50 is 1/8th of height, 400 is height */ document.getElementById('progress-now').setAttribute('style', 'height: ' + progress + 'px'); } 
 #progress-bar { position: relative; height: 400px; width: 200px; background: linear-gradient(to bottom, lightgreen 99.9%, transparent 99.9%), radial-gradient(circle at 50% 50%, lightgreen 25%, transparent 30%); background-position: 50% 0%, 50% 15px; /* 15px is 30% of 50px */ background-size: 5px 100%, 50px 50px; /* 5px is the thickness of the bar, 50px is 1/8th of the height */ background-repeat: no-repeat, repeat-y; } #progress-now { position: absolute; width: 200px; background: linear-gradient(to bottom, darkgreen 99.9%, transparent 99.9%), radial-gradient(circle at 50% 50%, darkgreen 25%, transparent 30%); background-position: 50% 0%, 50% 15px; background-size: 5px 100%, 50px 50px; background-repeat: no-repeat, repeat-y; z-index: 1; } 
  

CSS

Мое решение CSS основано на нескольких div , которые позволяют вам иметь столько, сколько вам нравится, и определять, сколько из них выполнено.

 .complete { width: 5px; height: 50px; position: relative; background: green; margin-left: 8px; } .complete:after { content: ''; width: 20px; height: 20px; border-radius: 50%; position: absolute; bottom: -7.5px; left: -8px; background: green; z-index: 100; } .not_complete { width: 5px; height: 50px; background: lightgreen; position: relative; margin-left: 8px; } .not_complete:after { content: ''; width: 20px; height: 20px; border-radius: 50%; position: absolute; bottom: -7.5px; left: -8px; background: lightgreen; z-index: 100; } 
 

Вы можете использовать box-shadow для достижения этого эффекта. Это может быть достигнуто с использованием одного элемента, поскольку он использует box-shadow s, но будет трудно изменить цвет с помощью javascript

Примечание. Я использовал jquery, чтобы показать эффект добавления большего количества в индикатор выполнения, щелкнув в любом месте тела, чтобы увидеть результат

 $('body').click(function () { var x = parseInt($('.progressNow').css('top')) + 10; $('.progressNow').css({ top: x }) if (x > 90 - 800) { $('.circle').css('background','#00b164') } if(x > 180 -800){ $('.circle').css('box-shadow','0 90px 0 0 #00b164, 0 180px 0 0 #8fe4bf, 0 270px 0 0 #8fe4bf, 0 360px 0 0 #8fe4bf, 0 450px 0 0 #8fe4bf, 0 540px 0 0 #8fe4bf') } if(x > 270 -800){ $('.circle').css('box-shadow','0 90px 0 0 #00b164, 0 180px 0 0 #00b164, 0 270px 0 0 #8fe4bf, 0 360px 0 0 #8fe4bf, 0 450px 0 0 #8fe4bf, 0 540px 0 0 #8fe4bf') } }) 
 #progress { overflow:hidden; width:15px; padding-left:5px; height:800px; position: relative; } #progress .progressBar { height: 800px; width: 6px; background: #8fe4bf; position: absolute; } #progress .progressNow { height: 800px; top:-800px; width: 6px; background: #00b164; position: absolute; } .circle{ content:""; width: 16px; height: 16px; border-radius: 50%; background: #8fe4bf; display: block; margin-left: -5px; position: absolute; top: 90px; box-shadow:0 90px 0 0 #8fe4bf, 0 180px 0 0 #8fe4bf, 0 270px 0 0 #8fe4bf, 0 360px 0 0 #8fe4bf, 0 450px 0 0 #8fe4bf, 0 540px 0 0 #8fe4bf; } 
  

Мой комментарий превратился в ответ. Он использует скрытый за emty

чтобы нарисовать нужный результат.

Это не очень гибко, CSS должен быть написан заранее для вариантов 5/6: 0,20%, 40%, 60%, 80%, 100%

 .hide-it { position: absolute; left: -100%; } #myprogress { height: 25em; position: relative; float: left; width: 0.5em; background: linear-gradient(to bottom, #00B18E 0%, #CFF8F0 0%, #CFF8F0); margin: 1em 9em 1em 1em; color:#00B18E; box-shadow:0 0 15em 1em black; } #myprogress:after { content: ' Progress 0%'; position:relative; z-index: 1; white-space: pre; top:-1%; } #myprogress:before { content: ''; position: absolute; z-index: 1; top: -0.2em; left: -.25em; width: 1em; height: 1em; border-radius: 50%; box-shadow: inset 0 0 0 15px #00B18E; } [value="20"] + #myprogress { background: linear-gradient(to bottom, #00B18E 20%, #CFF8F0 20%, #CFF8F0); } [value="20"] + #myprogress:before { box-shadow: inset 0 0 0 15px #00B18E, 0 5em 0 0 #00B18E; } [value="20"] + #myprogress:after { content:' Progress 20%'; top:19%; } [value="40"] + #myprogress { background: linear-gradient(to bottom, #00B18E 40%, #CFF8F0 40%, #CFF8F0); } [value="40"] + #myprogress:before { box-shadow: inset 0 0 0 15px #00B18E, 0 5em 0 0 #00B18E, 0 10em 0 0 #00B18E; } [value="40"] + #myprogress:after { content:' Progress 40%'; top:39%; } [value="60"] + #myprogress { background: linear-gradient(to bottom, #00B18E 60%, #CFF8F0 60%, #CFF8F0); } [value="60"] + #myprogress:before { box-shadow: inset 0 0 0 15px #00B18E, 0 5em 0 0 #00B18E, 0 10em 0 0 #00B18E, 0 15em 0 0 #00B18E; } [value="60"] + #myprogress:after { content:' Progress 60%'; top:59%; } [value="80"] + #myprogress { background: linear-gradient(to bottom, #00B18E 80%, #CFF8F0 80%, #CFF8F0); } [value="80"] + #myprogress:before { box-shadow: inset 0 0 0 15px #00B18E, 0 5em 0 0 #00B18E, 0 10em 0 0 #00B18E, 0 15em 0 0 #00B18E, 0 20em 0 0 #00B18E; } [value="80"] + #myprogress:after { content:' Progress 80%'; top:79%; } [value="100"] + #myprogress { background: linear-gradient(to bottom, #00B18E 100%, #CFF8F0 100%, #CFF8F0); } [value="100"] + #myprogress:before { box-shadow: inset 0 0 0 15px #00B18E, 0 5em 0 0 #00B18E, 0 10em 0 0 #00B18E, 0 15em 0 0 #00B18E, 0 20em 0 0 #00B18E, 0 25em 0 0 #00B18E; } [value="100"] + #myprogress:after { content:' Progress 100%'; top:99%; } 
   

SVG

Вот функциональная полоса прокрутки с рядом точек.
Точки – это один путь. Эффект прокрутки на панели представляет собой линейный gradleиент, измененный с помощью javascript.
Процентный текст представляет собой текстовый элемент svg, а javascript изменяет атрибут y этого элемента.

(Я потратил много времени на это решение)

 var start = document.getElementById("gradstart"); var stop = document.getElementById("gradstop"); var max = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight); max -= document.documentElement.clientHeight; var process = document.getElementById("process"); function gradientScroll() { var top = (window.pageYOffset || document.documentElement.scrollTop) var amount = Math.round((top / max) * 100.0); process.setAttribute("y", (amount) + "%"); process.innerHTML = amount + "%"; start.setAttribute("offset", amount + "%"); stop.setAttribute("offset", amount + "%"); } window.addEventListener("scroll", function() { window.requestAnimationFrame(gradientScroll); }); 
         Amount