2

I've an element with a var property set on it like so:

 <div class="divwithbackground" style="--page-header-section-background: url('myurlimage.jpg');">
 </div>

CSS

 .divwithbackground::after {
     background-image: var(--page-header-section-background);
     background-position: center;
     background-size: cover;
 }

This actually works well. But what if I have another javascript which sets the property:

document.documentElement.style.setProperty('--page-header-section-background', bgDataValue, 'important');

this way. Well this works if I remove style this from the DIV tag:

 style="--page-header-section-background: url('myurlimage.jpg');

But this is not the behavior I want. I would like javascript to replace the already set property. Is this possible ?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Claudio Ferraro
  • 4,551
  • 6
  • 43
  • 78
  • This is actually how the var variables are usually set , targeting the documentElement. As I understand they are kind of global – Claudio Ferraro Mar 12 '20 at 18:08
  • So, sorry for my first comment, I have not seen you're trying to override a global CSS var. – Roko C. Buljan Mar 12 '20 at 18:08
  • not according the documentation. Maybe I'm wrong: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty – Claudio Ferraro Mar 12 '20 at 18:12
  • @ClaudioFerraro could you try `document.documentElement.style['--page-header-section-background'] = bgDataValue` You can change style of element as the above example – Halil İbrahim Özdoğan Mar 12 '20 at 18:16
  • in my implementation the value is dynamically added with php. I used JS for loading the final image. And style= for loading a temporary image. – Claudio Ferraro Mar 12 '20 at 18:18
  • Halil. It didn't work. – Claudio Ferraro Mar 12 '20 at 18:19
  • or in order to replace style property, this is the messy solution but either you can do like `document.documentElement.setAttribute('style', '--page-header-section-background:' + bgDataValue + '!important;');` Of course, document.documentElement is not the correct CSS selector. I wrote due to the fact that you wrote like that in the example – Halil İbrahim Özdoğan Mar 12 '20 at 18:21
  • I just tried this in inspector, simply defining important on html tag and another at body which is not important and it overrides the important anyway. So it has nothing to do with the way it is added, it simply does not work like the way you think it does – Huangism Mar 12 '20 at 18:22
  • Ahahah. You're a genius. This is what will I say to my boss. ;-) – Claudio Ferraro Mar 12 '20 at 18:28
  • You can use js to remove the currently set variables so that the top level will work as an alternative. After some thought, the important is used for css rules, I don't think it has any effect when set for variables. `setProperty` allows you to do it because that's usually used with rules. So the thinking behind important will work on var is wrong, I think – Huangism Mar 12 '20 at 18:30
  • Do You mean: document.documentElement.style.removeProperty('--page-header-section-background'); I tried. It didn't work as well – Claudio Ferraro Mar 12 '20 at 18:40
  • @ClaudioFerraro no you would have to target the div with the variable declaration to remove it. For example, get the elements with the var setting, then just set style="" – Huangism Mar 12 '20 at 18:53
  • That's the point a variable is usually global. As discussed above. not related to DIV – Claudio Ferraro Mar 12 '20 at 18:56
  • You still add the var you want to html or whatever top level element. But you have to remove the declaration from the existing divs or else it will not replace the lower declarations. Basically if you declare the same var in a more specific scope, it will always override the higher level declarations. – Huangism Mar 12 '20 at 18:58
  • The other thing you can do is, on the div - you declare a var calling to another var(the top level var). So the div will have whatever value the top level var has, so when you change the one in the top level it will trigger down to your div. – Huangism Mar 12 '20 at 19:02
  • 1
    an important note here: !important doesn't work with CSS custom properties – Temani Afif Mar 12 '20 at 19:27

1 Answers1

0

You need to either target the element itself to override the variable

setTimeout(function() {
document.querySelector('.divwithbackground').style.setProperty('--b', 'linear-gradient(blue,blue)');
},1500);
.divwithbackground::after {
  content: "";
  display: block;
  height: 50px;
  background-image: var(--b);
}
<div class="divwithbackground" style="--b: linear-gradient(red,red);">
</div>

Or consider a fallback trick if you want to target the root element:

setTimeout(function() {
document.documentElement.style.setProperty('--b', 'linear-gradient(blue,blue)');
},1500);
.divwithbackground::after {
  content: "";
  display: block;
  height: 50px;
  background-image: var(--b,var(--c));
}
<div class="divwithbackground" style="--c: linear-gradient(red,red);">
</div>

You can also set/reset the initial value like you want:

function change() {
  document.documentElement.style.setProperty('--b', 'linear-gradient(blue,blue)');
}

function reset() {
  document.documentElement.style.setProperty('--b', 'initial');
}
.divwithbackground::after {
  content: "";
  display: block;
  height: 50px;
  background-image: var(--b, var(--c));
}
<div class="divwithbackground" style="--c: linear-gradient(red,red);">
</div>

<button onclick="change()">change</button>
<button onclick="reset()">reset</button>

Related questions/answers for more details:

How to store inherit value inside a CSS custom property (aka CSS variables)?

CSS custom properties (variables) for box model

CSS scoped custom property ignored when used to calculate variable in outer scope

Temani Afif
  • 245,468
  • 26
  • 309
  • 415