我正在尝试在HTML5 + CSS3 中创建一个非常简单的进度条。自从我发现以来,HTML的<progress>
标签很难在浏览器中正确设置样式,我使用经典 <div>
版本,但现在我正在努力设计。
以下是我当前代码的简化版本:
/* Progressbar wrapper */
.progressbar {
display: inline-block;
box-sizing: border-box;
width: 100px; /* ONLY FOR TESTING PURPOSES */
height: 1em; /* Height should fit to a text line */
padding: 0.231em; /* Equals to 3px in production setup */
background-color: dimgray;
border-radius: 100vmax; /* To make curly sides */
}
/* Progressbar indicator */
.progressbar > div {
height: 100%;
border-radius: inherit;
background-color: green; /* Fallback for browsers that don't support gradients */
background-image: linear-gradient(to right, red 0%, yellow 50%, green 100%);
background-size: 100px; /* FIXME: This MUST match wrapper width. Can't inherit!? */
}
<div class="progressbar"><div style="width: 100%"></div></div> 100 %<br>
<div class="progressbar"><div style="width: 85%"></div></div> 85 %<br>
<div class="progressbar"><div style="width: 75%"></div></div> 75 %<br>
<div class="progressbar"><div style="width: 50%"></div></div> 50 %<br>
<div class="progressbar"><div style="width: 25%"></div></div> 25 %<br>
<div class="progressbar"><div style="width: 15%"></div></div> 15 %
以下是它的外观(以及background-size: <fixednumber>px
的外观):
JSFiddle: https://jsfiddle.net/2gt0nv5f/22/
问题是progresbar的border-size当前必须与包装元素大小匹配才能使颜色渐变正确呈现(红色为0%标记,绿色为100%标记)。我的目标是使这个进度条响应(例如,能够适应任何宽度,同时保持其外观)。
以下是使用background-size: inherit
时的外观(这是错误的):
所以我的问题是:有没有办法从包装器继承bar的背景大小?如果没有,你会如何处理这个问题?我可以添加额外的元素和/或包装,但我正在寻找纯CSS解决方案。这是因为我为此构建的网站不允许嵌入任何JavaScript或类似内容。
我尝试了什么:
<div>
元素尝试了替代方法,该元素将覆盖指标的“未使用”部分,包含背景颜色(从右侧开始)。不仅看起来很奇怪(在进度结束时没有边界半径,这是预期的),但在某些浏览器上有一些奇怪的渲染错误(并非所有像素都被覆盖)所以我放弃了它。说实话,我还是一名CSS初学者,所以我相信我在这里缺少一些明显的东西。如果有人能指出正确的方向,我将非常感激。
答案 0 :(得分:1)
我认为现在是考虑CSS变量的好时机:
.progressbar {
margin:5px;
box-sizing: border-box;
width: var(--size,100px);
height: 1em;
padding: 0.231em;
background-color: grey;
border-radius: calc((1em - 0.231em) * 2);
}
/* Progressbar */
.progressbar>div {
height: 100%;
/* Use as much, as the height of wrapper allows */
border-radius: inherit;
/* Same as wrapper */
background-color: green;
/* Fallback for browsers that don't support gradients */
background-image: linear-gradient( to right, red 0%, yellow 50%, green 100%);
background-size: var(--size,100px);
}
<div class="progressbar">
<div style="width: 50%"></div>
</div>
<div class="progressbar">
<div style="width: 70%"></div>
</div>
<div class="progressbar" style="--size:200px">
<div style="width: 70%"></div>
</div>
<div class="progressbar" style="--size:200px">
<div style="width: 50%"></div>
</div>
您还可以简化代码,如下所示:
.progressbar {
box-sizing: border-box;
margin:10px;
width: var(--s,100px);
height: 1em;
padding: 0.231em;
background:
linear-gradient( to right, red 0%, yellow 50%, green 100%) content-box,
grey;
border-radius: calc((1em - 0.231em) * 2);
box-shadow:calc(-1*var(--p)*var(--s,100px)) 0 0 inset grey;
}
<div class="progressbar" style="--p:0.5">
</div>
<div class="progressbar" style="--p:0.2">
</div>
<div class="progressbar" style="--s:200px;--p:0.7">
</div>
<div class="progressbar" style="--s:250px;--p:0.3">
</div>
答案 1 :(得分:1)
我插入另一个div作为掩码,所以我不需要设置包装宽度,只需设置指标宽度,使用媒体查询,这可能是响应。
/* Emulate standart website setup */
body {
font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
font-size: 13px;
color: #333333;
}
/* Progressbar wrapper */
.progressbar {
overflow: hidden;
display: inline-block;
box-sizing: border-box;
vertical-align: middle;
/* ONLY FOR TESTING PURPOSES */
height: 1em;
/* Height should fit exactly to a text line */
margin-right: 0.4em;
/* Left-offset any text that follows progressbar */
padding: 0.231em;
/* Equals to 3px in current setup */
background-color: brown;
border-radius: 20px;
}
/* Progressbar */
.progressbar .indicator {
height: 100%;
/* Use as much, as the height of wrapper allows */
border-radius: inherit;
/* Same as wrapper */
background-color: green;
/* Fallback for browsers that don't support gradients */
background-image: linear-gradient( to right, red 0%, yellow 50%, green 100%);
background-size: cover;
/* FIXME: This MUST match wrapper width. Can't inherit!? */
}
.mask {
overflow: hidden;
height: 100%;
border-radius: 20px;
}
.small .indicator {
width: 100px;
}
.middle .indicator {
width: 200px;
}
.big .indicator {
width: 300px;
}
<div class="progressbar big">
<div class="mask" style="width: 50%">
<div class="indicator"></div>
</div>
</div>Test text
<hr>
<div class="progressbar small">
<div class="mask" style="width: 70%">
<div class="indicator"></div>
</div>
</div>Test text
<hr>
<div class="progressbar middle">
<div class="mask" style="width: 100%">
<div class="indicator"></div>
</div>
</div>Test text
答案 2 :(得分:-1)
/* Emulate standart website setup */
body {
font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
font-size: 13px;
color: #333333;
}
/* Progressbar wrapper */
.progressbar {
display: inline-block;
box-sizing: border-box;
vertical-align: middle;
width: 100px; /* ONLY FOR TESTING PURPOSES */
height: 1em; /* Height should fit exactly to a text line */
margin-right: 0.4em; /* Left-offset any text that follows progressbar */
padding: 0.231em; /* Equals to 3px in current setup */
background-color: g;
border-radius: calc((1em - 0.231em) * 2); /* Height/2 to make curly sides */
/* ADDED background-size delcaration to the parent element */
background-size: 50px auto;
}
/* Progressbar */
.progressbar > div.aa {
height: 100%; /* Use as much, as the height of wrapper allows */
border-radius: inherit; /* Same as wrapper */
background-color: green; /* Fallback for browsers that don't support gradients */
background-image: linear-gradient(
to right,
red 0%,
yellow 50%,
green 100%
);
/* NOW it can inherit parent background-size property */
background-size: inherit;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Progressbar test</title>
</head>
<body>
<div class="progressbar"><div class="aa" style="width: 50%"></div></div>Test text
</body>
</html>
说明: 您可以继承默认属性而不在paren上声明它们,但是当没有默认值时,您需要在尝试继承子项之前在父项上声明它。