使前景透明,但不要使背景透明。

3

我正在进行一些实验,并设定了以下挑战,但现在无法解决。我正在为Flyspray bug跟踪器制作用户脚本。在问题列表中,有一列指示完成百分比:

enter image description here

这个系统相对较老,但这也使它具有某种简单美感。这是进度条的HTML代码:
<td class="task_progress">
    <img src="/themes/Bluey/percent-70.png" alt="70%">
</td>

简洁明了。现在我想要的是,在不改变HTML的情况下,在鼠标移动上移动进度条,这可以通过使前景半透明并设置CSS渐变背景来实现。我可以通过将包装在中来解决这个问题,但这非常笨拙。

const wrapped = document.querySelector("#wrapped");
const img = wrapped.querySelector("img");
const box = img.getBoundingClientRect();
//wrapped.style.height = (box.bottom-box.top)+"px";

const bg = "linear-gradient(to right, rgba(0,38,114,1) 0%,rgba(0,38,114,1) 50%,rgba(0,38,114,0) 51%,rgba(0,38,114,0) 100%)";
console.log(wrapped);
wrapped.addEventListener("mousemove", (e)=>{
    const box = wrapped.getBoundingClientRect();
    const mousePos = e.clientX - box.left;
    const max = box.right-box.left;
    const perc = 100*(mousePos/max);
    
    const gradient = bg
               .replace("50%", (perc-0.5)+"%")
               .replace("51%", (perc+0.5)+"%");
    //console.log(gradient);
    ///console.log(perc);
    wrapped.style.backgroundImage = gradient;
    wrapped.style.color = "red";
}, {capture: false});
#wrapped {
   display: inline-block;
   margin: 0px;
   padding: -1px;
   border-width: 1px;
   border-color:transparent;
   border-style: solid;
   
   position: relative;
   
   background-position: center center;
   
   background-repeat: no-repeat;
   
   background-size: 0px 0px;
}
#wrapped img {
   margin: 0px;
   padding: 0px;
   
   position: relative;
   
   top:0px;
   left: 0px;
}
#wrapped:hover img {
    opacity: 0.3;
}
#wrapped:hover {
    /*border-color:#002672;*/
    background-size: 100% 8.82px;
}
<span id="wrapped"><img src="https://istack.dev59.com/lymku.webp" /></span>

上述解决方案的主要问题是:包装器的高度与 <img> 的高度不匹配,这意味着必须将背景尺寸设置为像素。

enter image description here

有没有一种方法可以不使用任何包装元素来完成这个操作?

请注意,这是一个练习/学习类型的问题,通过其他方式解决整个问题的解决方案对我没有用。


1
由于线性渐变是一种背景图像,因此您可以控制背景大小。 - Mouser
看起来你在#wrapped元素上有一个1像素的透明边框,然后又给它加了-1像素的内边距(这是不可能的,而且可能没有任何效果)。为什么要这样做?去掉这个应该可以防止边框大小影响任何东西,因为不会有1像素的隐形边框。另外,一般来说,添加* { box-sizing: border-box; }通常是一个好主意,但在这里可能没有什么区别。 - FiniteLooper
1个回答

3
不要使用透明颜色的渐变。只使用纯色并控制background-size,然后将img块元素简单地避免空白问题: 不确定是否可以在没有包装器的情况下实现,因为您需要应用渐变的元素:

const wrapped = document.querySelector("#wrapped");
const img = wrapped.querySelector("img");
const box = img.getBoundingClientRect();
//wrapped.style.height = (box.bottom-box.top)+"px";

const bg = "linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1))";
console.log(wrapped);
wrapped.addEventListener("mousemove", (e)=>{
    const box = wrapped.getBoundingClientRect();
    const mousePos = e.clientX - box.left;
    const max = box.right-box.left;
    const perc = 100*(mousePos/max);

    //console.log(gradient);
    ///console.log(perc);
    wrapped.style.backgroundSize =perc+"% 100%";
    wrapped.style.color = "red";
}, {capture: false});
#wrapped {
   display: inline-block;
   margin: 0px;
   /*padding: -1px; there is no negative padding */
   border-width: 1px;
   border-color:transparent;
   border-style: solid;
   
   background-position:left;
   background-repeat: no-repeat;
}
#wrapped img {
   display:block;
}
#wrapped:hover img {
    opacity: 0.3;
}
#wrapped:hover {
    /*border-color:#002672;*/
    background-image:linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1));
    background-size: 50% 100%;
}
<span id="wrapped"><img src="https://istack.dev59.com/lymku.webp" /></span>

但你可以考虑使用多个背景元素来替代图片,并在最后添加一个元素来代替图片:

const wrapped = document.querySelector("#wrapped");


wrapped.addEventListener("mousemove", (e)=>{
    const box = wrapped.getBoundingClientRect();
    const mousePos = e.clientX - box.left;
    const max = box.right-box.left;
    const perc = 100*(mousePos/max);

    wrapped.style.backgroundSize =perc+"% 100%, 60% 100%";
}, {capture: false});
#wrapped {
   display: inline-block;
   border-width: 1px;
   border-style: solid;
   border-color:rgba(0,38,114,1);
   height:10px;
   width:100px;
    background-image:
      linear-gradient(transparent,transparent),
      linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1));
    background-size: 60% 100%;
   background-position:left;
   background-repeat: no-repeat;
}
#wrapped:hover {
   border-color:rgba(0,38,114,0.5);
    background-image:
      linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1)),
      linear-gradient(rgba(0,38,114,0.5),rgba(0,38,114,0.5));
}
<span id="wrapped"></span>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接