How do I set a value of `inherit` to a CSS custom property? [duplicate]
Asked Answered
C

1

10

Setting a custom property to a value of inherit does exactly what you’d expect for every other CSS property: it inherits the same property value of its parent.

normal property inheritance:

<style>
  figure {
    border: 1px solid red;
  }
  figure > figcaption {
    border: inherit;
  }
</style>
<figure>this figure has a red border
  <figcaption>this figcaption has the same border
    as its parent because it is inherited</figcaption>
</figure>

custom property inheritance (explicit):

<style>
  figure {
    --foobar: 1px solid green;
  }
  figure > figcaption {
    --foobar: inherit;
    border: var(--foobar);
  }
</style>
<figure>this figure has no border
  <figcaption>this figcaption has a green border
    because it explicitly inherits --foobar</figcaption>
</figure>

custom property inheritance (implicit):

all custom properties (unlike border) are inherited by default

<style>
  figure {
    --foobar: 1px solid green;
  }
  figure > figcaption {
    border: var(--foobar);
  }
</style>
<figure>this figure has no border
  <figcaption>this figcaption has a green border
    because it implicitly inherits --foobar</figcaption>
</figure>

my question

How do you set a literal value of inherit to a custom property, when you want its value to actually calculate to the keyword inherit?

<style>
  figure {
    border: 1px solid red;
    --foobar: 1px solid green;
  }
  figure > figcaption {
    border: var(--foobar);
  }
  figure > figcaption:hover {
    --foobar: inherit;
  }
</style>
<figure>this figure has a red border
  <figcaption>this figcaption has a green border
    because it inherits --foobar</figcaption>
</figure>
<!-- on hover -->
<figure>this figure has a red border
  <figcaption>I want this figcaption
    to have a red border (inherited from figure)
    but its border is green!</figcaption>
</figure>

In this example, I want the second figcaption (on hover) to inherit its parent’s red border, so I set --foobar to inherit. However as shown in example 2, this does not calculate to inherit, it calculates to the value that is inherited from the parent’s property --foobar (if it has one), which in this case is green.

I completely understand why the CSS authors designed it this way: --foobar is just like any other CSS property, so setting inherit should inherit its value. So I guess I’m asking if there is a workaround for getting the second figcaption to inherit its parent’s border.

Note, I considered doing

figure > figcaption:hover {
  border: inherit;
}

but this defeats the purpose of using a CSS variable.

In the case that there are many other properties in figure > figcaption that all use the value var(--foobar), I don’t want to redefine them all over again for the hover scenario. I'd rather set these properties only once, and then reassign the variable based on context.

Cooperman answered 5/10, 2016 at 19:5 Comment(6)
--foobar isn't a property...it's a property value. Only properties can be inherited.Proudfoot
Look at it this way...--foobar: inherit; would compile to 1px solid green: inherit which makes no sense.Proudfoot
@Proudfoot I don't think that's right. They're technically called custom properties, and they are inherited, as demonstrated in my examples. See the W3C spec and MDN.Cooperman
Regardless of what they are called your demo doesn't work as you think it does. In the first example the figcaption has a green border because that's what you've told it to have...not because it's inherited. As I said 1px solid green: inherit makes no sense.Proudfoot
1px solid green: <anything>; makes no sense, yet --foobar: <anything>; is still valid (whether or not the <anything> is inherit). I believe you aren't properly making the distinction between --foobar, a property, and var(--foobar), a value. You are partially correct: in my second (not first) example, the border is green because border: var(--foobar); calculates to border: 1px solid green;. And while you are also correct that border itself is not inherited, the custom property --foobar is inherited, which gives the border its value.Cooperman
Related: #55271616 Other related: #53240380Complice
C
-2

I did some thinking and this solution just hit me. I can use custom properties in conjunction with preprocessor mixins.

<style type="text/less">
  // NOTE: not syntactically valid CSS!
  .mx-border(@arg) {
    border: @arg;
  }
  figure {
    .mx-border(1px solid red);
    --foobar: 1px solid green;
  }
  figure > figcaption {
    .mx-border(var(--foobar));
  }
  figure > figcaption:hover {
    .mx-border(inherit);
  }
</style>
<figure>this figure has a red border
  <figcaption>this figcaption has a green border
    because it inherits --foobar</figcaption>
</figure>
<!-- on hover -->
<figure>this figure has a red border
  <figcaption>This figcaption
    has a red border because the mixin
   sets the `border` property to `inherit`.</figcaption>
</figure>

This way, I can encapsulate all the dependent styles into the .mx-border() mixin. Doing this doesn’t take advantage of CSS custom properties, but it does alleviate the hassle of writing everything a second time for the :hover.

Essentially it is the same as writing border: inherit;, with the added ability of putting more styles into the mixin and not having to duplicate them.

Cooperman answered 7/10, 2016 at 0:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.