CSS 内容:attr() 在 HTML5 进度上不起作用



HTML

<progress max="100" value="80" data-value="5"></progress>

CSS

progress { margin: 50px; width:250px; border:0; }

CSS(尝试1)

progress:before, progress:after { content: attr(data-value); }

CSS(尝试2)

progress::-webkit-progress-bar:before,
progress::-webkit-progress-bar:after { content: attr(data-value); }
progress::-moz-progress-bar:before,
progress::-moz-progress-bar:after { content: attr(data-value); }

CSS(尝试3)

progress::-webkit-progress-value:before,
progress::-webkit-progress-value:after { content: attr(data-value); }
progress::-moz-progress-value:before,
progress::-moz-progress-value:after { content: attr(data-value); }

上述尝试均未成功。还尝试了以上每个版本的不同CSS代码块,用于:before:after

目标

在HTML5<progress>元素前后注入CSS生成的内容。这可能吗?

JsFiddle演示

http://jsfiddle.net/pankajparashar/MNL2C/

更新

当我使用以下CSS时,它是有效的。

progress::-webkit-progress-bar:before,
progress::-webkit-progress-bar:after { content: '123'; }    

结论

显然,当我们在CSS中注入静态内容时,它是有效的。但如果我们使用data-*中的内容,则不会。

在我最初的评论中,我说:

我认为这是不可能的,因为如果浏览器已经可以绘制进度条,则progress元素中的内容永远不会显示,类似于objectiframe中的内容。

换句话说,这将progress分类为被替换的元素。正如传统的input和其他被替换的形式元素,以及img一样,CSS2.1对使用生成的内容没有太多说明:

注意本规范没有完全定义:before和:after与替换元素(如HTML中的IMG)的交互。这将在未来的规范中进行更详细的定义。

众所周知,基于Gecko的浏览器选择不支持替换元素的生成内容,而基于WebKit的浏览器在某种程度上允许生成内容,至少对于替换元素的表单元素是这样。(有趣的是,progress::beforeprogress::after任何浏览器中都不起作用。)因此,如果你问是否可以进行这种跨浏览器操作,答案是否定的,而且一直都是否定的。


至于为什么WebKit浏览器可以插入字符串而不能插入attr()值,我不确定。CSS2.1和CSS3 Units and Values都指出,attr()应该从生成这些伪元素的实际元素的属性中获取值,因为伪元素本身无论如何都不能有属性。这就是我被难住的地方。

也许浏览器错误地尝试从::-webkit-progress-bar::-webkit-progress-value中获取data-value属性,而不是progress元素,这就是为什么content在使用attr()时失败,但在使用字符串时工作的原因。

也许问题的根源在于,您正试图将生成的内容添加到其他伪元素中,无论出于何种奇怪的原因,这些伪元素似乎在WebKit浏览器中都能正常工作。与上面在替换的元素中生成内容的问题不同,当前的Selectors 3规范和即将推出的Selectors 4规范都非常清楚这一点:每个复杂的选择器不应该有一个以上的伪元素。当然,WebKit在实现伪元素时公然藐视各种规则,所以事后来看,看到WebKit这样做并不奇怪

无论哪种方式,真正的结论是CSS生成内容的实现都非常糟糕,超出了当前CSS2.1+Selectors标准的范围,我指的是为inputprogress等替换元素生成的内容,以及在单个选择器中嵌套伪元素。

<progress></progress>

它不接受文本,你所需要做的就是调整你的css。

HTML:

<progress max="100" value="80" data-value="80"></progress>
<span class="percentage">80% Done</span>

CSS:

progress { margin: 0px; width:250px; border:0; }
/* CSS (Attempt 1) */
    progress:before, progress:after { content: attr(data-value); }
/* CSS (Attempt 2) */
    progress::-webkit-progress-bar:before,
    progress::-webkit-progress-bar:after { content: attr(data-value); }
    progress::-moz-progress-bar:before,
    progress::-moz-progress-bar:after { content: attr(data-value); }
/* CSS (Attempt 3) */
    progress::-webkit-progress-value:before,
    progress::-webkit-progress-value:after { content: attr(data-value); }
    progress::-moz-progress-value:before,
    progress::-moz-progress-value:after { content: attr(data-value); }
    .percentage{
        float: left;
        margin-left:100px;
        margin-top: -20px;
        position: absolute;
        display: block;
        color: #FFF;
    }

看来@BoltClock是正确的-content: attr(value)正在-webkit-progress-value的阴影DOM元素上寻找value属性,而不是在实际的<progress>元素上:

h4 { margin: 2em 0 0; }
progress {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
}
progress::-webkit-progress-value:before {
  position: absolute;
  right: 0;
  bottom: -125%;
}
progress.show-value::-webkit-progress-value:before {
  content: attr(value);
}
progress.show-data-value::-webkit-progress-value:before {
  content: attr(data-value);
}
progress.show-style::-webkit-progress-value:before {
  content: attr(style);
}
progress.show-pseudo::-webkit-progress-value:before {
  content: attr(pseudo);
}
<h4><code>attr(value)</code>:</h4>
<progress class="show-value" max="100" value="80" data-value="5"></progress>
<h4><code>attr(data-value)</code>:</h4>
<progress class="show-data-value" max="100" value="80" data-value="5"></progress>
<h4><code>attr(style)</code>:</h4>
<progress class="show-style" max="100" value="80" data-value="5"></progress>
<h4><code>attr(pseudo)</code></h4>
<progress class="show-pseudo" max="100" value="80" data-value="5"></progress>

最新更新