javascriptcsspolyfillscss-cascade

Using CSS's "revert" keyword


So I've been trying to work on some classes that hide and show elements. When an element is supposed to show, it should go from display:none; to display: whatever-it-was-before;. In researching ways to do this, I stumbled across what looks to be the perfect solution: CSS's revert. Unfortunately, Cascading and Inheritance Level 4 is a long ways from being supported, and this feature doesn't appear to be implemented in any of the major browsers on Windows.

To illustrate what I'm trying to do, here's some CSS:

.article-card {
    display: flex;
}
._showdesktop {
    display: none !important;
}
@media screen and (min-width: 1024px) {
    ._showdesktop {
        display: revert !important;
    }
}

And some accompanying HTML:

<div class="article-card _showdesktop">
    ...
</div>

The idea is to have generic classes that can be used on any element, without overriding the intended CSS of an element. This would allow me to show and hide elements that are display:flex;, display:block;, display:inline-block;, or display:inline; all with the same set of classes.

So, I have two questions:

  1. Is there any polyfill out there for this? I tried searching around, but unfortunately the terms "revert" and "polyfill" show up together a lot thanks to version control systems.
  2. Is there any other way to do this with CSS? I was looking in to using visibility:hidden;, as I almost never use the visibility property in my projects, but this doesn't remove an element from the flow, and I couldn't think of any way to remove it that wouldn't conflict with other code.

https://drafts.csswg.org/css-cascade/#default


Update: The answer marked below is as good as I'm going to get for now, but I wanted to update this question with the code I ended up using. I'm not sure how well this will work, considering I do often use max-height, but hopefully it won't conflict very often:

._hidemobile,
._showtablet,
._showdesktop {
    max-height: 0 !important;
    visibility: hidden !important;
}

._showmobile {
    max-height: none !important;
    visibility: visible !important;
}

@media screen and (min-width: 768px) {
    ._showmobile,
    ._hidetablet {
        max-height: 0 !important;
        visibility: hidden !important;
    }

    ._showtablet {
        max-height: none !important;
        visibility: visible !important;
    }
}

@media screen and (min-width: 1024px) {
    ._showtablet,
    ._hidedesktop {
        max-height: 0 !important;
        visibility: hidden !important;
    }

    ._showdesktop {
        max-height: none !important;
        visibility: visible !important;
    }
}

Solution

    1. Is there any polyfill out there for this? I tried searching around, but unfortunately the terms "revert" and "polyfill" show up together a lot thanks to version control systems.

    Probably not. revert rolls back the cascade, that's a non-trivial thing.

    Moreover, I'm not sure it would be helpful in your case. You style an element with display: flex but display: none wins the cascade. If I understand correctly, you want to undo display: none and get display: flex. However, revert

    Rolls back the cascade to the user level, so that the specified value is calculated as if no author-level rules were specified for this property.

    That is, your author-level display: flex will be ignored too.

    Instead, display: revert is useful when you want to reset display to the default behavior, e.g. block for <div>, table-cell for <td>, inline for <span>.

    1. Is there any other way to do this with CSS? I was looking in to using visibility:hidden;, as I almost never use the visibility property in my projects, but this doesn't remove an element from the flow, and I couldn't think of any way to remove it that wouldn't conflict with other code.

    Yes. As you suspect, display: none is an oddity which should have never existed. CSS Display Level 3 addresses this issue by introducing a new property, called box-suppress:

    The display: none value was historically used as a "toggle" to switch between showing and hiding an element. Making this reversible requires either setting up the CSS cascade carefully, or remembering what the display value was before it was set to none. To make this common use-case easier, this module introduces the separate box-suppress property to do the same thing, so that toggling whether or not an element appears in the formatting tree can now be done without affecting its display type when it is displayed.

    The "only" problem is that no major browser supports box-suppress neither.

    So meanwhile, the best approach is applying display: none only when you need it, so that you won't have to undo it. In your example,

    .article-card {
      display: flex;
    }
    @media screen and (min-width: 1024px) { /* This rule is optional */
      ._showdesktop {
        /* Use current display */
      }
    }
    @media screen and (max-width: 1024px) {
      ._showdesktop {
        display: none;
      }
    }
    <div class="article-card _showdesktop">Hello world</div>