CSS @supports 与通过 JS 检查支持

CSS @supports vs Checking Support via JS

在寻找检查浏览器 CSS 支持的方法时,我遇到了两种不同的方法:CSS 和 JavaScript。我以前使用 JS 检查浏览器中的功能支持,但不使用 CSS 属性。据我所知,较新的浏览器已经添加了对 CSS @supports 的支持,但是那些不支持的浏览器呢?

CSS@supports的例子:

@supports (display: flex) {
    div { display: flex; }
}

那么,如果旧版浏览器不支持 CSS @supports,同时使用 JS 和 CSS 方法是否可行?关于我上面的例子,是否可以用它做几乎一个 if/else 语句,例如:

@supports (display: flex) { 
    div { display: flex; }
} else { 
    div { display: none; }
}

我知道它可能不是关键词 else,但能够按照这些思路执行某些操作将是有益的。所以,总结整理一下我的问题:

  1. 在不支持此 CSS 语法的旧版浏览器中检查 CSS 属性 对 @supports 支持的最佳方法是什么?
  2. 同时使用 CSS 和 JS 是否有意义或实用?
  3. CSS @supports 是否有某种 if/else 语法?
  1. What is the best approach to checking CSS property support with @supports in older browsers not supporting this CSS syntax?

    这完全取决于您要做什么。如果您正在检查对 属性 的特定值的支持(例如 flexdisplay 属性),提供回退值并让在大多数情况下,cascade 会为您处理。

    使用你的例子,它很简单:

    div {
        display: none;
        display: flex;
    }
    

    如果您要处理旧版浏览器可能不支持的整个 属性,那么这完全取决于您尝试使用或不使用 属性 来完成的工作。例如,border-radius 通常不会对布局产生任何不利影响,因此不支持它的旧版浏览器会正常降级,您无需执行任何其他操作。但其他属性可能会对布局产生不利影响,您需要考虑不同的属性和不同的布局配置。

  2. Would it make sense or be practical to utilize both CSS and JS for this?

    如果您使用 JS 来覆盖尽可能多的基础,使用 CSS 可能是多余的,或者作为一种现代的非 JS 替代方案,可以解决禁用 JS 的用户。这也可能会有所不同,具体取决于您检测到的特征类型。

    因为这是关于 @supports,值得注意的是有一个 JavaScript API 称为 CSS.supports 除了你从 [=58 中调用它之外,它的功能相同=].如果您不担心禁用脚本的用户,您可以检查它是否已实现并使用它,否则使用您现有的功能检测代码:

    var supported = false;
    
    if (window.CSS) {
        supported = window.CSS.supports('display', 'flex');
    } else {
        // Your existing feature detection code here
    }
    
  3. Is there some sort of if/else syntax for CSS @supports?

    CSS 条件 at 规则(例如 @supports@media)没有 if/else 语法,即使有,浏览器也不支持@supports 可能会忽略 else 部分。如果您需要考虑较旧的浏览器,您唯一的选择是使用如上所示的级联(即使浏览器支持不是问题,它也更简单并且涵盖大多数用例)。

    另一种方法是复制条件并在前面添加 not 以否定它,并且每个 @supports 规则中的 CSS 规则将互斥(如果您想要包含仅当 属性 不受 支持且无法使用旧版浏览器的旧语法模拟时才应应用的其他属性):

    @supports (display: flex) {
        div { display: flex; }
    }
    
    @supports not (display: flex) {
        div { display: none; }
    }