How to check if a CSS property or value is supported by a browser?
Asked Answered
I

8

35

My div that uses vh is not working in some browsers, so I want to check if it is supported. I found this article by Lea Verou on the subject, but I'm really not sure how to use it with a CSS value:

Here is the code given as a shortcut for you:

if('opacity' in document.body.style) {  
   // do stuff
}

function isPropertySupported(property{
   return property in document.body.style;
 }

In the comments of the article above someone asks how to check if a CSS value is supported and the answer is, "You set it, then read the value back and check if the browser retained it." which sounds like requires JavaScript (which I don't know).

How can I check in CSS or in JavaScript whether a property or a value is supported by a browser?

Incite answered 24/3, 2016 at 1:36 Comment(1)
You can use stylelint-no-unsupported-browser-features (Technically answering your question, since this approach uses Javascript (Node.js), but at build time rather than runtime)Batten
W
34

I assume you meant to check whether the vh value is supported, not whether specifically DIV#id bears it?

function cssPropertyValueSupported(prop, value) {
  var d = document.createElement('div');
  d.style[prop] = value;
  return d.style[prop] === value;
}
cssPropertyValueSupported('width', '1px');
// => true
cssPropertyValueSupported('width', '1vh');
// => maybe true, maybe false (true for me)
cssPropertyValueSupported('width', '1foobar');
// => false

EDIT: This is obsolete; CSS.supports is now well supported, and should be used instead. Please support this answer instead.

Whirly answered 24/3, 2016 at 1:42 Comment(6)
Thanks for your help. This code is pretty advanced compared to my curremt knowledge. Im just guessing but should i test the cssPropertyValueSupported('width', '100vh') with an if statement?Incite
Yes, usually the if statement would make the most sense here.Whirly
That did the trick! Wish i could understand the code more but i will in due time! thanks alot Amadan.Incite
Beware that this will incorrectly return true if the CSS property is completely unsupported. For example, cssPropertyValueSupported('dominant-baseline', 'hanging') will return true on MS Edge, which does not support any values for dominant-baseline. If you can, use CSS.supports(property, value) instead, which works on everything except IE (any version) and stock Android from 2013Recha
it's a good answer, just to add that you should beware that setting a style will normalise it like "polygon(50% 0px,100% 100%,0% 100%)" becomes standard "polygon(50% 0px, 100% 100%, 0% 100%)" ( with a space after ,). Also to mitigate for the previous comment, maybe you should check for the presence of the property first like style[camelCaseProp] it should be an empty string and not undefined. Although I can't vouch that's how all browsers work.Andrews
By no means this answer is obsolete. Why would I try using CSS.supports if it itself may not be supported? The whole idea is obsolescence check, which should be achieved by the most vanilla code.Retrusion
R
48

There is the new API CSS.supports. Supported in most browsers except IE.

console.log(
  // CSS.supports(property, value)
  1, CSS.supports("text-decoration-style", "blink"),
  2, CSS.supports("display", "flex"),
  3, CSS.supports('--foo', 'red'),
  4, CSS.supports('(--foo: red)'),

  // CSS.supports(DOMstring)
  5, CSS.supports("( transform-origin: 5% 5% )"),
  6, CSS.supports("( transform-style: preserve ) or ( -moz-transform-style: preserve ) or " 
  + "( -o-transform-style: preserve ) or ( -webkit-transform-style: preserve )")
)

And there is a similar feature in CSS, the @supports feature query selector, also supported in most browsers except IE:

@supports (display: grid) {
  div {
    display: grid;
  }
}
@supports not (display: grid) {
  div {
    float: right;
  }
}
Rickard answered 9/8, 2017 at 3:43 Comment(0)
W
34

I assume you meant to check whether the vh value is supported, not whether specifically DIV#id bears it?

function cssPropertyValueSupported(prop, value) {
  var d = document.createElement('div');
  d.style[prop] = value;
  return d.style[prop] === value;
}
cssPropertyValueSupported('width', '1px');
// => true
cssPropertyValueSupported('width', '1vh');
// => maybe true, maybe false (true for me)
cssPropertyValueSupported('width', '1foobar');
// => false

EDIT: This is obsolete; CSS.supports is now well supported, and should be used instead. Please support this answer instead.

Whirly answered 24/3, 2016 at 1:42 Comment(6)
Thanks for your help. This code is pretty advanced compared to my curremt knowledge. Im just guessing but should i test the cssPropertyValueSupported('width', '100vh') with an if statement?Incite
Yes, usually the if statement would make the most sense here.Whirly
That did the trick! Wish i could understand the code more but i will in due time! thanks alot Amadan.Incite
Beware that this will incorrectly return true if the CSS property is completely unsupported. For example, cssPropertyValueSupported('dominant-baseline', 'hanging') will return true on MS Edge, which does not support any values for dominant-baseline. If you can, use CSS.supports(property, value) instead, which works on everything except IE (any version) and stock Android from 2013Recha
it's a good answer, just to add that you should beware that setting a style will normalise it like "polygon(50% 0px,100% 100%,0% 100%)" becomes standard "polygon(50% 0px, 100% 100%, 0% 100%)" ( with a space after ,). Also to mitigate for the previous comment, maybe you should check for the presence of the property first like style[camelCaseProp] it should be an empty string and not undefined. Although I can't vouch that's how all browsers work.Andrews
By no means this answer is obsolete. Why would I try using CSS.supports if it itself may not be supported? The whole idea is obsolescence check, which should be achieved by the most vanilla code.Retrusion
V
10

We can since a while test from javascript if a css rule if available in the context with CSS.supports.

(Since Firefox 22/ Chrome 28)

console.log(
CSS.supports("( transform-origin: 5% 5% )"),
"\n",
CSS.supports("( display: flex )"),
"\n ",
CSS.supports("( background-color: #12233212 )")
)

The CSS.supports() static methods returns a Boolean value indicating if the browser supports a given CSS feature, or not.

https://developer.mozilla.org/en-US/docs/Web/API/CSS/supports


To go further, we can possibly use this property for browser detection.

Verily answered 1/6, 2018 at 16:38 Comment(0)
C
5

I see the code you have there.

var styletotest = "PutStyleHere";

if (styletotest in document.body.style)
{
    alert("The " + styletotest + " property is supported");

} else {

    alert("The " + styletotest + " property is NOT supported"); 

}

Simply place the css property you want to test in the quotes where it says

PutStyleHere

And when you load the file it will show a popup telling you if it works or not.

However this seems unnecessary.

Simply Googling:

[property] css W3

where [property] is the property you want to know browser support information.

When I searched

Opacity Css W3

and then clicked on the W3 link... you can scroll down and you will see a section of the page with the info you want like this:

Browser SUpport

Source

Calamity answered 24/3, 2016 at 1:51 Comment(2)
Sadly the alert says its not supported even in firefox and chrome. i have a feeling something isnt right with 'in document.body.style'. anyways i gave Amadan's suggestion a try and it worked. Again, thanks alot for your help!Incite
Not entirely unnecessary in situations where you may want to polyfill certain styles where your property isn't supported. object-fit is a good example, right nowReach
S
4

Use the new CSS @supports feature. You can do this from CSS and also from JavaScript.

CSS:

@supports(width: 1vh) {
  div#id {
    width: 1vh;
  }
}
/* Use at `@supports not` if you want to give an `else` condition */
@supports not (width: 1vh) {
  div#id {
    width: 3%;
  }
}

JavaScript way: The supports() method is provided in the CSS API to do this.

if(CSS.supports('width', '1vh')) {
  document.querySelector('div#id').style.width = '1vh';
} else {
  documen.querySelector('div#id').style.width = '1%';
}

Read more at CSS Conditional Rules

Sartin answered 28/6, 2021 at 5:4 Comment(0)
U
2

I'd suggest to use Modernizr.

Modernizr is a JavaScript library that detects which HTML5 and CSS3 features your visitor's browser supports. In detecting feature support, it allows developers to test for some of the new technologies and then provide fallbacks for browsers that do not support them.

Some useful links:

Unpaidfor answered 24/3, 2016 at 3:37 Comment(3)
Install a library to check for the existence of one CSS property?Exhortation
@Exhortation Thanks for the comment. It's true that OP just said one property there, but it's very likely that it needs to check more in the real project. Probably you don't want to end up writing a whole new library. Modernizr is highly customizable anyway. Easy to use for both beginners and experts.Unpaidfor
This does look like a good option but it's true i only need one css value to be checked. i'll for sure look into modernizr for future projects. thanks!Incite
A
0

This is my code that accounts for totally unsupported properties by checking for presence of camel-Case props in the style, and uses CSS.supports if available.

const prefixes = ['', '-webkit-']

function supports(prop, value) {
  if ('CSS' in window && 'supports' in window.CSS) {
    for (let i = 0; i < prefixes.length; i++) {
      const property = prefixes[i] + prop

      if (window.CSS.supports(property, value) ) { return true }
    }
    return false
  }

  const el = document.createElement('div')

  let found = false
  prefixes.forEach((pr) => {
    if (found) return
    const p = `${pr}${prop}`
    const Prop = p.replace(/-(.)/g, (m, s) => s.toUpperCase())
    if (!(Prop in el.style)) return
    el.style[p] = value
    found = el.style[p] == value // can just check if it's not empty actually
  })
  return found
}
Andrews answered 12/10, 2019 at 22:49 Comment(0)
H
0

In Chromium browsers starting in version 100 you can now inspect using DevTools to see if a particular declaration (property + value) is supported.

Here is a screenshot of my website using Chrome 101 (Beta), which is the first Chromium version to support the font-palette property:

enter image description here

You can see in the green boxes that the @supports rule with the following conditions:

@supports (font-palette: dark) or (font-palette: light)

that in Chrome 101, both of the following declarations

font-palette: light;
font-palette: dark;

are supported.

Unlike the answers above, this is a pure DevTools -> Styles solution to determining support in a browser.

Haroldson answered 6/4, 2022 at 18:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.