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:
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;
}
}
- 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>
.
- Is there any other way to do this with CSS? I was looking in to using
visibility:hidden;
, as I almost never use thevisibility
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 thedisplay
value was before it was set tonone
. To make this common use-case easier, this module introduces the separatebox-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>