css 在` `栏上的伪元素之前插入a::< progress>before

oogrdqng  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(120)

我尝试在<progress>条上显示::before伪元素,就像带有value属性的标签一样。(v1.61.109),虽然它不会出现在Safari中(17.1.2)和Firefox(121.0).不过我还是遇到了一个关于伪元素高度的考虑问题,我觉得伪元素本身自然对流量没有直接的影响,不过,我想找到一个有效的解决方案。
除了显示元素外,我还希望它在父框的高度中被考虑,特别是.card。我正在寻找一个动态解决方案。


的数据
下面是HTML代码:

<div class="card">
    <p>Item 1</p>
    <p>Item 2</p>
    <progress max="100" value="100"></progress>
</div>

字符串
下面是相关的CSS:

.card {
    display: flex;
    flex-direction: column;
    width: 300px;
    background: beige;
}

progress[value] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    width: 100%;
}

progress {
    position: relative;
}

progress:before {
    content: attr(value) '% some text here';
    font-size: 2rem;
    color: black;
    text-align: center;
    height: 2rem;
    line-height: normal;
}

progress[value]::-webkit-progress-value {
    background-color: green;
    border-radius: .2rem;
}

progress[value]::-moz-progress-bar {
    background-color: green;
    border-radius: .2rem;
}


有没有人知道如何解决这个问题?

dly7yett

dly7yett1#

我遇到了你的问题,到目前为止,我唯一能想到的解决办法是使用JavaScript来更新进度%,而不是CSS中的attr()。
我选择JS有两个原因,
1.很简单
1.我们可以避开使用:before伪元素时出现的一些问题。(::before伪元素在Safari中似乎不太好用,并且伪元素不被认为在父元素的高度内。)
现在,使用一个div <div id="progress-label"></div>来包含progress %,我们可以确保progress %位于父元素(.card)中,因为它是一个块级元素,并且是静态定位的。JS代码段在执行时只会更新DOM中div中的文本内容。
您可以尝试使用此模板并编辑它以满足您的需求。请在此处查看codepen以获得演示。https://codepen.io/Jun-Wen-Soh/pen/ZEPQgGR
HTML

<div class="card">
  <p>Item 1</p>
  <p>Item 2</p>
  <div class="wrapper">
    <div id="progress-label"></div>
    <label for="progress-bar">Progress:</label>
    <progress id="progress-bar" max="100" value="100"></progress>
  </div>
</div>

字符串
CSS

.card {
  display: flex;
  flex-direction: column;
  width: 300px;
  background: beige;
  padding: 15px;
}

.wrapper {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

progress[value] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: none;
  width: 100%;
}

progress {
  position: relative;
}

#progress-label {
  font-size: 2rem;
  color: black;
  text-align: left;
  height: 2rem;
  line-height: normal;
}

progress[value]::-webkit-progress-value {
  background-color: green;
  border-radius: .2rem;
}

progress[value]::-moz-progress-bar {
  background-color: green;
  border-radius: .2rem;
}


JS

const progressBar = document.getElementById('progress-bar');
const progressLabel = document.getElementById('progress-label');

progressLabel.textContent = progressBar.value + '% some text here';

sgtfey8w

sgtfey8w2#

在CSS中使用伪元素的问题

  1. before伪元素位于标签内的内容之前,而不是标签的打开之前。因此,flex规则永远不会正确应用,因为它针对.car的直接子元素,而:befoer伪元素是<progress>的第一个子元素。
    1.此外,如文档here中所述,不可能在内容未出现在文档树中的HTML元素上使用伪元素。
    1.此外,CSS生成的内容不能被屏幕阅读器访问。CSS生成的内容不影响页面理解是至关重要的。
    因此,解决方案涉及如下修改HTML代码:
<div class="card">
    <p>Item 1</p>
    <p>Item 2</p>
    <label for="progress">% some text here</label>
    <progress id="progress" max="100" value="100">toto</progress>
</div>

字符串
一个类似这样的JavaScript:

const progressElement = document.getElementById('progress');
const progressLabelElement = document.querySelector('[for=progress]');
const initialTextContent = progressLabelElement.textContent;

function updateValue() {
    progressLabelElement.textContent = progressElement.value + initialTextContent;
}
// this is not needed if the value does not change
progressElement.addEventListener('input', updateValue);

updateValue()

相关问题