1

Similar question to How do I overlay a gradient background over an existing background with CSS? and of course How do I combine a background-image and CSS3 gradient on the same element?, but in this case I do not have control over the background image URL.

Case in point

As part of some styling I was implementing to improve my Facebook experience, I wrote this piece of CSS:

.jewelCount > span { /* replaces notification color with a more neutral tone of red */
    background-color: #ab5151;
}
.jewelButton > div { /* adds a faint overlay on top of notification icons to achieve a more neutral shade of white */
    background-image: linear-gradient(rgba(66, 103, 178, 0.1), rgba(66, 103, 178, 0.1)), url(/rsrc.php/v3/yc/r/rZKhvPo9Lsv.png) !important;
}

(using the Stylish extension for Firefox).

and it works,

fb notifications - edited

but in the meantime, the background image URL changed from /rsrc.php/v3/yc/r/rZKhvPo9Lsv.png to /rsrc.php/v3/y1/r/vZXeFuzjfGs.png and I had to update my style manually, which sucks.

Since I'm not changing the background image's url() at all (I'm only reusing it in the background-image property to achieve the overlay effect), is there a way to "preppend" the linear-gradient function to whatever background-image is already in use for that element?

If it's not possible in CSS (and I'm guessing it's not), I'll settle with a solution using javascript for use with Greasemonkey (no jQuery, though).

Thanks.

Community
  • 1
  • 1
Marc.2377
  • 7,807
  • 7
  • 51
  • 95

2 Answers2

1

You can not get what you want only with CSS.

You have 2 alternative ways to get the same effect:

inset shadow

You can set a inset shadow with the color

div {
    width: 100px;
    height: 100px;
    background: linear-gradient(yellow, white);
    box-shadow: inset 0px 0px 0px 1000px rgba(0,0,255,0.4);
}
<div></div>

Pseudo element

You can set a pseudo element on the div with the color that you want. (you need to position the div relative to get the pseudo position ok)

div {
    width: 100px;
    height: 100px;
    background: linear-gradient(yellow, white);
    position: relative;
}

div:after {
    content: "";
    width: inherit;
    height: inherit;
    position: absolute;
    left: 0;
    top: 0;
    
    background: rgba(0,0,255,0.2);
}
<div></div>
vals
  • 61,425
  • 11
  • 89
  • 138
  • Nice. While not precisely what my question asked, I'm accepting this because you make it clear that was not possible. I went with your first solution, but declaring 4 length values for `box-shadow` (like `0 0 0 50px`) to achieve a sharp overlay. Thanks. – Marc.2377 Jun 10 '18 at 20:13
  • 1
    Happy that it helped. Unfortunately, there is no way to keep part of a property and override the other part in pure CSS – vals Jun 10 '18 at 20:39
0

For the time being I solved this with an user script.

// ==UserScript==
// @name     Facebook notification icon color
// @version  1
// @match    https://www.facebook.com/*
// @run-at   document-start
// @grant    none
// ==/UserScript==

(function start(){
    var jewels = document.querySelectorAll('.jewelButton');
    if(!jewels[0]) {
      setTimeout(start, 50);
      return;
    }
    jewels.forEach(function(elem) {
      var url = window.getComputedStyle(elem.firstChild).getPropertyValue('background-image');
      elem.firstChild.style.setProperty('background-image', 'linear-gradient(rgba(66, 103, 178, 0.1), rgba(66, 103, 178, 0.1)), ' + url, 'important');
    });

})();
Marc.2377
  • 7,807
  • 7
  • 51
  • 95