使用 CSS 的 "revert" 关键字

Using CSS's "revert" keyword

所以我一直在尝试研究一些 类 来隐藏和显示元素。当一个元素应该显示时,它应该从 display:none;display: whatever-it-was-before;。在研究实现此目的的方法时,我偶然发现了看起来是完美的解决方案:CSS 的 revert。不幸的是,Cascading and Inheritance Level 4 距离支持还有很长的路要走,并且此功能似乎并未在 Windows.

上的任何主要浏览器中实现

为了说明我正在尝试做的事情,这里有一些 CSS:

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

还有一些伴随HTML:

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

我们的想法是拥有可用于任何元素的通用 类,而不会覆盖元素的预期 CSS。这将允许我显示和隐藏 display:flex;display:block;display:inline-block;display:inline; 的元素,它们都具有同一组 类.

所以,我有两个问题:

  1. 是否有为此提供的 polyfill?我尝试四处搜索,但不幸的是,由于版本控制系统,术语 "revert" 和 "polyfill" 经常一起出现。
  2. 还有其他方法可以用 CSS 做到这一点吗?我一直在考虑使用 visibility:hidden;,因为我几乎从不在我的项目中使用 visibility 属性,但这并没有从流程中删除一个元素,我想不出以任何方式删除它,不会与其他代码冲突。

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


更新: 下面标记的答案和我现在要得到的一样好,但我想用我最终使用的代码更新这个问题。考虑到我经常使用 max-height,我不确定这会如何工作,但希望它不会经常发生冲突:

._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;
    }
}
  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.

可能不会。 revert 回滚级联,这是一件非常重要的事情。

此外,我不确定这对您的情况是否有帮助。您使用 display: flex 设置元素样式,但 display: none 赢得级联。如果我没理解错的话,你想撤消 display: none 并得到 display: flex。然而,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.

也就是说,您的作者级别 display: flex 也将被忽略。

相反,当您想将 display 重置为默认行为时,display: revert 很有用,例如block 代表 <div>table-cell 代表 <td>inline 代表 <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.

是的。正如您所怀疑的那样,display: none 是一个不应该存在的怪人。 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.

"only" 问题是没有主流浏览器 box-suppress 也不支持。

因此,最好的方法是仅在需要时应用 display: none,这样您就不必撤消它。在你的例子中,

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

这是一个非常古老的问题,我认为这个答案不会立即适用(任何 "revert" 值似乎已被删除,并且 'box-suppress' 也从未实现过),但是目前实现这一目标的方法似乎是:

display: "contents";

使用这个和包装器元素现在可以 "undo" 一个 display: "none"; 因为 "contents" 类型不会在文档流中生成块(就像 "none") 但它确实将其内容放入流中。

一些示例:

var toggle = 'contents'
btn = document.getElementById('showHide');
btn.onclick = function(ev) {
  toggle = ('none' === toggle) ? 'contents' : 'none'
  var disp = document.querySelectorAll('.toggle')
  disp.forEach( el => el.style.display = toggle )
}
.toggle { border: 1px dotted red; }
<section>
<p>
On first load, display is the browser default and outlines the elements under test. Each click toggles display:none/display:contents.<br>
<button id="showHide">TOGGLE DISPLAY</button>
</p>

<div>
Text above the first toggle element.
<span class="toggle">Text in the first toggle element.</span>
Text below the first toggle element. Note that everything flows together.
</div>

<p></p>

<div>
In a new div now, a list comes next.
<ol><li>AAA</li>
    <li class="toggle">BBB</li>
    <li>CCC</li>
</ol>
This text is after the list. The second &lt;li&gt; becomes its content.
<hr>

Here's a list that will toggle the display property on itself:
<ol class="toggle"><li>JJJ</li>
    <li>KKK</li>
    <li>LLL</li>
</ol>
When displayed again, the &lt;od&gt; is gone, but the &lt;li&gt; remain.
<hr>

This list has an embedded dev.
<ol><li>XXX</li>
    <div class="toggle"> <li>YYY</li> </div>
    <li>ZZZ</li>
</ol>
This is invalid HTML but after becoming display:contents it should appear normal.

</div>
</section>

我认为这里的大多数发帖人都不明白“还原”是什么意思?对于初学者来说,它只适用于非 IE 浏览器。所以不是很有帮助。在像“display”这样的非继承属性上,它会“恢复”到浏览器的 UA 默认样式 sheet 元素的值,而不是作者的 sheet,在这种情况下将是“块” div.

你为什么不简单地做相反的事情,只在你的媒体查询中定义你的各种 div 显示时?

._hidedesktop {
    display: none;
}

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

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