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.

TylerH
  • 20,799
  • 66
  • 75
  • 101
chharvey
  • 8,580
  • 9
  • 56
  • 95
  • `--foobar` isn't a property...it's a **property value**. Only properties can be inherited. – Paulie_D Oct 05 '16 at 19:23
  • Look at it this way...`--foobar: inherit;` would compile to `1px solid green: inherit` which makes no sense. – Paulie_D Oct 05 '16 at 19:36
  • @Paulie_D 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](https://www.w3.org/TR/css-variables/#defining-variables) and [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables#Inheritance_of_CSS_Variables). – chharvey Oct 06 '16 at 00:49
  • 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. – Paulie_D Oct 06 '16 at 05:35
  • `1px solid green: ;` makes no sense, yet `--foobar: ;` is still valid (whether or not the `` 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. – chharvey Oct 06 '16 at 13:41
  • Related: https://stackoverflow.com/questions/55271116/is-this-a-browser-bug-inheritence-in-variables-with-background-color Other related: https://stackoverflow.com/questions/53239880/how-to-store-inherit-value-inside-a-css-custom-property-aka-css-variables – ADJenks Mar 21 '19 at 17:23

1 Answers1

-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.

chharvey
  • 8,580
  • 9
  • 56
  • 95