继承

时间:2018-03-07 11:58:42

标签: css css3

我正在尝试在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的外观):

enter image description here

JSFiddle: https://jsfiddle.net/2gt0nv5f/22/

问题是progresbar的border-size当前必须与包装元素大小匹配才能使颜色渐变正确呈现(红色为0%标记,绿色为100%标记)。我的目标是使这个进度条响应(例如,能够适应任何宽度,同时保持其外观)。

以下是使用background-size: inherit时的外观(这是错误的):

enter image description here

所以我的问题是:有没有办法从包装器继承bar的背景大小?如果没有,你会如何处理这个问题?我可以添加额外的元素和/或包装,但我正在寻找纯CSS解决方案。这是因为我为此构建的网站不允许嵌入任何JavaScript或类似内容。

我尝试了什么:

  1. 我认为可以通过使用background-size的值“inherit”来解决,但这似乎不起作用,即使它应该(至少根据W3Schools)。我还尝试将包装器的后台大小显式设置为“帮助”继承发生,但没有任何积极的影响。
  2. 我使用另一个<div>元素尝试了替代方法,该元素将覆盖指标的“未使用”部分,包含背景颜色(从右侧开始)。不仅看起来很奇怪(在进度结束时没有边界半径,这是预期的),但在某些浏览器上有一些奇怪的渲染错误(并非所有像素都被覆盖)所以我放弃了它。
  3. 说实话,我还是一名CSS初学者,所以我相信我在这里缺少一些明显的东西。如果有人能指出正确的方向,我将非常感激。

3 个答案:

答案 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上声明它们,但是当没有默认值时,您需要在尝试继承子项之前在父项上声明它。