简体   繁体   中英

Make foreground transparent, but not the background

I'm experimenting a little bit, and I've set the following challenge, which I now cannot solve. I'm making user script for Flyspray bug tracker. In a list of issues, there's a column indicating percent complete:

在此处输入图片说明

The system is rather old, which gives it a certain beauty of simplicity. This is the HTML for the progress:

<td class="task_progress">
    <img src="/themes/Bluey/percent-70.png" alt="70%">
</td>

Clean and simple. Now what I'd like to do is to move the progress on mouse move above the <img> , without changes to HTML. This could be done if I could make the ` foreground semi-transparent and set a CSS gradient background.

I could solve this by wrapping the <img> in <span> , but it's very clumsy.

 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://i.stack.imgur.com/lymku.png" /></span> 

The main problem with the above solution: The wrapper's height does not match the <img> height, which means that background dimensions had to be set exactly to a pixel.

在此处输入图片说明

Is there a way to do this without any wrapper element?

Please note that this is an exercise/learning kind of question, solutions that solve the entire thing through other means are of no use to me.

Don't use gradient with transparent color. Use only the solid color and control the background-size then simply make the img block element to avoid the whitespace issue:

Not sure if it's possible without a wrapper because you will need an element where you have to apply the gradient:

 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://i.stack.imgur.com/lymku.png" /></span> 

But you can probably consider an idea with multiple background to avoid the image and have one element at the end that will replace the image:

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM