我正在尝试创建一个垂直进度条,实线上有8个点(结尾处是第8个),其中每个点代表该过程中的一个步骤。请参阅随附的屏幕截图(在底部以防止此问题被分解)。
当然,我尝试用HTML和CSS制作一些东西,你可以在this fiddle(下面的代码)中看到。问题是,我找不到在浅绿线上创建7个点的方法,而不添加8个div(8个因为第一个也必须在那里)。
功能方面,我希望JS检查value
- div的progressNow
,将它多重显示100,并将其作为CSS高度添加到progressNow
- 类。问题在于点会移动,而不是条形填充。 (这有意义吗?)
这让我想到了在屏幕截图中可以看到的形状创建一个SVG元素,它具有一个基于过程中第n步改变位置的渐变。我知道这会起作用,我知道我可以让它工作,但我想知道是否还有另一种,也许更容易实现我想要实现的目标。
HTML
<div id="progress">
<div class="progressBar"></div>
<div class="progressNow" value="1"></div>
<div class="progressTotal"></div>
</div>
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
的{{1}}为progressNow
)
答案 0 :(得分:11)
我的解决方案与@ 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;
}
&#13;
<ul class="progress-bar">
<li>
<li>
<li>
<li class="stop">
<li>
</ul>
&#13;
出于某种原因,底部片段似乎没有显示在stacksnippet中,因此它位于jsfiddle上。
答案 1 :(得分:9)
这是一个非常小的编号的CSS解决方案。元素。在这种方法中,我们使用linear-gradients
和radial-gradients
的组合来生成垂直线和点。
父#progress-bar
元素生成lightgreen(初始)行和圆圈,同时将相同的渐变添加到子#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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id='progress-bar'>
<div id='progress-now' value='1.85'></div>
</div>
以下是填充动画效果的版本。
window.onload = function() {
var val = 0, progress = 0;
function progressBar() {
val += 0.005;
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');
if (val <= 8) anim = window.requestAnimationFrame(progressBar);
}
progressBar();
}
#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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id='progress-bar'>
<div id='progress-now'></div>
</div>
答案 2 :(得分:6)
我的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;
}
<div class="progress">
<div class="complete"></div>
<div class="complete"></div>
<div class="not_complete"></div>
<div class="not_complete"></div>
<div class="not_complete"></div>
<div class="not_complete"></div>
<div class="not_complete"></div>
<div class="not_complete"></div>
</div>
这也可以使用SVG g
元素并将其与不同的填充一起使用。
请记住,SVG的高度需要与放在一起的所有元素相同或更大。
<svg width="20" height="445" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="completed">
<line x1="0" y1="5" x2="0" y2="40" style="stroke:green;stroke-width:3;" />
<circle style="fill:green; stroke-width:0;" cx="0" cy="50" r="10" />
</g>
<g id="not_complete">
<line x1="0" y1="5" x2="0" y2="40" style="stroke:lightgreen;stroke-width:3;" />
<circle style="fill:lightgreen; stroke-width:0;" cx="0" cy="50" r="10" />
</g>
</defs>
<use x="10" y="00" xlink:href="#completed" />
<use x="10" y="55" xlink:href="#completed" />
<use x="10" y="110" xlink:href="#not_complete" />
<use x="10" y="165" xlink:href="#not_complete" />
<use x="10" y="220" xlink:href="#not_complete" />
<use x="10" y="275" xlink:href="#not_complete" />
<use x="10" y="330" xlink:href="#not_complete" />
<use x="10" y="385" xlink:href="#not_complete" />
</svg>
答案 3 :(得分:5)
你可以使用box-shadow
来实现这种效果。这可以使用单个元素来实现,因为它使用box-shadow
但是使用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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div id="progress">
<div class="progressBar"></div>
<div class="circle"></div>
<div class="progressNow" value="1"></div>
</div>
答案 4 :(得分:5)
我的评论变成了答案。
它使用隐藏的<progress>
后面的emty <div>
来绘制所需的输出。
这不是很灵活,必须事先为5/6选项编写CSS: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%;
}
<progress class="hide-it" value="0" max="100">
</progress>
<div id="myprogress"></div>
<progress class="hide-it" value="20" max="100">
</progress>
<div id="myprogress"></div>
<progress class="hide-it" value="40" max="100">
</progress>
<div id="myprogress"></div>
<progress class="hide-it" value="60" max="100">
</progress>
<div id="myprogress"></div>
<progress class="hide-it" value="80" max="100">
</progress>
<div id="myprogress"></div>
<progress class="hide-it" value="100" max="100">
</progress>
<div id="myprogress"></div>
答案 5 :(得分:3)
这是一个带有一系列点的功能滚动条 点是单一路径。 栏上的滚动效果是通过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);
});
<svg height="800px" viewBox="0 0 100 700" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="0" x2="0" y1="0%" y2="100%" id="grad">
<stop id="gradstart" offset="50%" stop-color="firebrick" />
<stop id="gradstop" offset="50%" stop-color="pink" />
</linearGradient>
</defs>
<path fill="url(#grad)" d="m20,0 0,50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
v50
a10 10 0 0 0 0,20
h5
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-50
a10 10 0 0 0 0,-20
v-100Z"></path>
<text id="process" text-anchor="middle" x="60" y="50">Amount</text>
</svg>