Difference between the CSS inherit and unset keywords

I’m trying to wrap my head around the revert and unset keywords defined in the Cascade module. Could you confirm that this is correct:

The only difference between

.foo { all: unset }


.foo { all: initial }

is that the latter additionally ignores all inherited values.

In other words, all: unset disregards the cascade (completely) for .foo elements, while all: inherit does exactly that, but it additionally disregards inheritance as well, and that’s the only difference between the two.

No, that’s not right.

Neither of these “disregard the cascade”. “initial”, if it wins the cascade as normal, just resolves to the property’s initial value. “inherit” is the same, but resolves to the inherited value from the parent.

Now, “initial”, on a non-inherited property, effectively does the same thing as not applying any value to that property at all; “inherit” is like that for inherited properties. “unset” acts like either “initial” or “inherit”, depending on whether the property is non-inherited or inherited, so you don’t have to remember which category a given property falls into.

I just noticed that all: unset isn’t an all-or-nothing thing, but rather that the cascade runs for each property independently, e.g.

.foo { color: red }
.foo.foo { background-color: purple }
.foo { all: unset } /* reverts color, but not background-color */

This complicates things. I assumed all: unset can just disable the cascade. I’ll need to re-think the potential use cases, to understand how it fits into the picture.

Ok, so unset unsets user agent styles, which makes it much less useful, since the better approach is to selectively override user agent styles, and not to unset them completely. I think.

However, revert is promising. Could someone confirm the following:

.foo {
  color: red;
  border: 1px solid red;
  /* etc. */

.bar {
  all: revert;

In this very simple example, adding the “bar” class to a “foo” element unsets all the properties from the .foo rule. In other words, adding “bar” to “foo” (<em class=“foo bar”>) is effectively the same as removing “foo” (<em class="">). Is this correct? Are there any side effects?

Note to self: Once this question is resolved, my next question will be about how to revert both the cascaded and inherited value, without reverting user agent styles. Note that all: revert only reverts the cascaded value, not the inherited value (demo). I have a feeling that reverting both would be more useful than revert.