【问题标题】:How can I feature-detect CSS filters?如何对 CSS 过滤器进行功能检测?
【发布时间】:2012-06-15 08:34:53
【问题描述】:

在某些浏览器中,包括 Chrome stable,您可以这样做:

h3 {
  -webkit-filter: grayscale(1);
  filter: grayscale(1);
}

你不知道吗,h1 将完全以灰度渲染。 Everything old is new again.

无论如何 — 有没有人知道任何对此进行特征检测的方法?

如果filter 不起作用,我需要能够应用其他样式。

【问题讨论】:

  • 你的意思是filter内部的不同风格,还是filter本身?
  • @3p3r 哦,太好了,某些浏览器是否只支持其中一些?……当然。好吧,我猜需要测试什么。
  • 我认为是这样,因为我的浏览器(Chrome 19)支持filter,但不支持grayscale

标签: css browser-feature-detection


【解决方案1】:

所谓的更新回答:

正如 OP 提到的一个好点,我正在更新答案,但这与我之前的答案没有任何相关或矛盾,这只是浏览器检测。

Alan H. 提到 IE,在它的第 10 个之前。版本,支持filter css 属性,但不是我们都知道的方式(CSS3 filter 我的意思)。

所以如果我们只想对CSS3 filters 进行特征检测,我们应该继续使用一点browser-detection。正如我在my comments 中提到的。

使用documentMode 属性,并将其与我们简单的特征检测相结合,我们可以排除 IE 中所谓的误报。

function css3FilterFeatureDetect(enableWebkit) {
    //As I mentioned in my comments, the only render engine which truly supports
    //CSS3 filter is webkit. so here we fill webkit detection arg with its default
    if(enableWebkit === undefined) {
        enableWebkit = false;
    }
    //creating an element dynamically
    el = document.createElement('div');
    //adding filter-blur property to it
    el.style.cssText = (enableWebkit?'-webkit-':'') + 'filter: blur(2px)';
    //checking whether the style is computed or ignored
    //And this is not because I don't understand the !! operator
    //This is because !! is so obscure for learning purposes! :D
    test1 = (el.style.length != 0);
    //checking for false positives of IE
    //I prefer Modernizr's smart method of browser detection
    test2 = (
        document.documentMode === undefined //non-IE browsers, including ancient IEs
        || document.documentMode > 9 //IE compatibility moe
    );
    //combining test results
    return test1 && test2;
}

Original Modernizr source


if(document.body.style.webkitFilter !== undefined)

if(document.body.style.filter !== undefined)

额外信息:

对于简单的特征检测,请使用我上面的代码。有关支持的功能列表,请查看此处:

如需在 Chrome 中实时演示 filters,请查看此处:

还有 2 个资源可供您使用:

在我撰写此答案时,您必须使用 webkit 供应商前缀才能使其正常工作。

【讨论】:

  • 太棒了。但我注意到,在 Chrome 中,.filter 已定义,但什么也没做(与 .webkitFilter 不同,它已定义并有效)。你认为这是为什么?
  • 我对此没有任何解释,因为我知道浏览器供应商前缀适用于处于原型(非标准)阶段或真正特定于浏览器的样式。
  • @AlanH。 Here 表示它只适用于 webkit 供应商前缀。
  • 我想我担心的是,.filter 已定义但无法使用,这似乎真的很奇怪和不可靠——如果它是错误的,这会破坏功能测试的意义。
  • @AlanH。 - IE 实现了一个非标准的filter CSS 属性,用于新标准取代的不同目的。也许 Chrome 一直支持 filter 以与 IE 兼容,这解释了它的定义原因,但请放心,一旦标准化,它将被替换为与 webkitFilter 相同的东西。不幸的是,这确实使特征检测变得复杂——你如何以一种不会在 IE 上误报的面向未来的方式检测 filter 的存在?
【解决方案2】:

您现在可以使用 CSS 的内置 @support 有条件地应用样式。请注意browser support for @support is good but not perfect。这是一篇很好的文章,通过几个示例解释了它是如何工作的:https://iamsteve.me/blog/entry/feature-detection-with-css

例如,您可以执行以下操作 (see it live):

@supports (filter: grayscale(1)) or (-webkit-filter: grayscale(1)) {
  h3 {
    -webkit-filter: grayscale(1);
    filter: grayscale(1);
  }
}

@supports not (filter: grayscale(1)) and not not (-webkit-filter: grayscale(1)) {
  h3 {
    color: #808080;
  }
}

【讨论】:

  • 更重要的是,旁边还有一个 JS 选项:Mozilla documentation
  • 时代变了,这可能是现在最好的答案,所以我正在改变我接受的答案。也就是说,我想支持 @support 但不支持 CSS filter 的浏览器数量一定很小......可能只有 Opera Mini 和一些嵌入式浏览器。
  • 关于浏览器支持,目前的每个浏览器(不是 MSIE 之类的死浏览器)都支持@support?
【解决方案3】:

以@Sepehr 的答案为基础,但对其进行一些现代化改造并删除多余的行:

var supportsFilters = (function() {
  var filterEl = document.createElement('div');
  filterEl.style.cssText = 'filter:blur(2px)';
  return filterEl.style.length != 0 && (document.documentMode === undefined || document.documentMode > 9);
})();

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多