32

I'm trying to change the background color of a dialog element's backdrop using a custom CSS property but it won't take. Is this a bug in Chrome or is there a reason for this?

document.querySelector('dialog').showModal();
:root {
  --color-backdrop: red;
}

dialog::backdrop {
  background: var(--color-backdrop);
}
<dialog>
  <p>This is a dialog. My backdrop should be red.</p>
</dialog>

2 Answers 2

29

Updated answer (29/02/2024)

As pointed out by Wes Goulet, this will change (or has changed) and we may have the expected behaviour of the original poster. So, the following probably works on all major browsers:

document.querySelector('dialog').showModal();
:root {
  --color-backdrop: red;
}

dialog::backdrop {
  background: var(--color-backdrop);
}
<dialog>
  <p>This is a dialog. My backdrop should be red.</p>
</dialog>

We can check its status following these links:

Outdated answer

The spec states the following about ::backdrop pseudo-element:

It does not inherit from any element and is not inherited from. No restrictions are made on what properties apply to this pseudo-element either.

And to quote Xindorn Quan, a member of WHATWG, regarding CSS Custom Properties:

CSS variables are propagated via inheritance into descendants, so if a pseudo-element doesn't inherit from anything, CSS variables which are not defined for the pseudo-element directly would have no effect on the pseudo-element.

Finally, this is one solution for this kind of problem:

document.querySelector('dialog').showModal();
::backdrop {
  --color-backdrop: red;
}

dialog::backdrop {
  background: var(--color-backdrop);
}
<dialog><p>This is a dialog. My backdrop should be red.</p></dialog>

It seems to be useful for multiple modals with ::backdrop, as a way of organizing their "root", so to speak.

3
  • 1
    Oh I see, so it won't inherit custom properties set on :root at all... that's a little annoying as we keep all our "config" in one file and they're all set on :root. Having to set one specific config variable on ::backdrop (as well as :root as it's used by other things too) will be a little annoying.
    – powerbuoy
    Commented Aug 12, 2020 at 14:33
  • 17
    :root, ::backdrop { --color-backdrop: red; } Then it's available to both
    – Phil
    Commented Aug 15, 2020 at 4:20
  • This solution does not work for css props piercing a shadow dom. Commented Oct 13, 2023 at 11:50
9

2023 Update

The spec has been updated to allow ::backdrop to inherit from the originating element, which allows backdrop to recognize CSS vars. Each major browser has bugs for updating their implementation.

So soon the OP example will work :)

5
  • 1
    This should be a comment, not an answer.
    – TylerH
    Commented Jan 2 at 20:10
  • 2
    @TylerH this answer has even more value at least for me rather than accepted one; and i would never read it if it was a comment
    – ilia
    Commented Jan 14 at 10:09
  • @IliaLiachin This post does not provide a new solution. It only explains an update about a solution provided by the accepted answer. Thus it should be a comment under that answer or a suggested edit to that answer.
    – TylerH
    Commented Jan 15 at 15:42
  • 2
    @TylerH people come here to get answers; this answer is exactly what i was looking for when opened this SO link; thus this is a proper answer, at least for me; probably there are more such people, and you're suggesting to make their lives harder just because you don't like this answer; ...vegetarians style
    – ilia
    Commented Jan 16 at 13:26
  • So do what I did and upvote this answer.
    – Rolf
    Commented Feb 8 at 10:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.