【问题标题】:CSS content: attr() on HTML5 progress doesn't workCSS 内容:HTML5 进度上的 attr() 不起作用
【发布时间】:2013-08-12 07:51:58
【问题描述】:

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); }

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

目标

在 HTML5 &lt;progress&gt; 元素之前和之后注入 CSS 生成的内容。这可能吗?

JsFiddle 演示

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

更新

当我使用以下 CSS 时,它可以工作。

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

结论

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

【问题讨论】:

  • 我认为这是不可能的,因为如果浏览器已经可以绘制进度条,progress 元素中的内容将永远不会显示,类似于objectiframe 中的内容。
  • @Pankaj Parashar:是的,我们是。我们谈论的是在 progress 元素内的内容之前和之后生成的内容。
  • 我不同意你的意见。因为当我们将 content: attr(data-value); 更改为 content: '213'; 时,它可以工作!所以问题在于在 content 属性中使用 css attr。
  • 这不是和IMG标签类似的问题吗(关于:before:after)?
  • 进一步阅读,进度元素不遵循void 内容模型。它使用phrasing content model,因此理论上您应该能够使用文本执行此操作。对我来说,这似乎仍然是一个奇怪的用例,但您可能应该使用 mozilla 和 chromium 提交一个错误。

标签: html css


【解决方案1】:

在我原来的评论中,我说:

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

换句话说,这会将progress 归类为replaced element。就像传统的input和其他被替换元素的表单元素一样,还有imgCSS2.1对于使用生成的内容没什么好说的:

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

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


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

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

也许问题的根源在于您正试图将生成的内容添加到其他伪元素中,无论出于什么奇怪的原因,这似乎在 WebKit 浏览器中仍然有效。与上述在替换元素中生成内容的问题不同,当前的 Selectors 3 规范和即将发布的 Selectors 4 规范都非常清楚这一点:每个复杂选择器不应该有多个伪元素。当然,WebKit 在实现伪元素方面臭名昭著地藐视了各种规则,所以事后看来,看到 WebKit 搞砸了,我并不感到惊讶。

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

【讨论】:

  • 我想我开始明白你不喜欢 WebKit 的原因了。不过,我怀疑在任何完整的解释中都有相当长的博文。
  • @David Thomas:我一直想再次写博客。我真的应该尽快对那个着陆页做点什么。但你是对的:我通常不会写为什么我完全不喜欢 WebKit,我很高兴曾经这样做过一次。
  • 或者,你知道,Twitter 的东西......顺便说一下,宣泄通常是一件好事,而且值得,即使只是在某些情况下,让其他人看到推理。话虽如此,虽然我喜欢 Chrome,但我也开始厌倦 WebKit 对标准的“解释”。只是不足以切换回 Firefox 或迁移到 Opera(尤其是因为他们决定自己采用 WebKit)。
  • 原始小提琴在 safari 6.0.5 (8536.30.1) i.imgur.com/s2GpLk5.png 上工作,而添加内容完全破坏了进度元素的 chrome 渲染。再想一想,你是对的。允许这种行为应该是错误。即使进度元素允许有文本子元素,它的子元素也不应该是可见的,除非该元素不受支持,类似于 canvas 或 iframe 元素。
  • @KerryLiu 你说得对,Safari 确实显示了带有 CSS 生成内容的 ::before::after 伪元素,但 @BoltClock 提出的观点足够有效。
【解决方案2】:
<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;
    }

【讨论】:

  • 感谢您的回答,但您真的错过了我的意思!问题是关于使用带有伪元素的 css 生成内容,但你的回答最终嘲笑了我的尝试:)
【解决方案3】:

看来@BoltClock 是正确的——content: attr(value) 正在寻找-webkit-progress-value 的影子DOM 元素上的value 属性,而不是实际的&lt;progress&gt; 元素:

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>

【讨论】:

    猜你喜欢
    • 2014-02-26
    • 2015-04-02
    • 1970-01-01
    • 2013-10-30
    • 2021-02-03
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多