-1

I want to start using css --variables. For legacy browsers, the css fallback is to declare a legacy rule first, and that's fine. But then I will manipulate them via javascript. So, is it going to break the script and throw some errors in legacy browsers? I ask because I currently can't test on legacy, so I can't see by myself.

I mean, if I do something like this:

elem.style.setProperty('--tx', `10px`);

What will happen in legacy browsers? Just nothing (--tx will silently not update and the program will go on) or, throw an error and break the script?

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118
  • try it: `elem.style.setProperty('notarealproperty', '10px')` To a legacy browser that doesn't support --tx, it will be as if you passed gibberish to it. so pass gibberish to it and see what happens. – Kevin B Nov 21 '18 at 16:39
  • That should be fine. According to https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty `HTMLElement.style.setProperty()` takes a `DOMString` as first argument (which seemingly simply is directly translated to a simple `String`). Btw, `--tx` does not seem an intuitive name for a variable. – connexo Nov 21 '18 at 16:39
  • 1
    When a legacy browser sees a var it can't compute, it simply skips the property. Your fallback should work nicely. – jmargolisvt Nov 21 '18 at 16:40

2 Answers2

1

According to the specification, setProperty() can throw a DOMException under these conditions:

SYNTAX_ERR: Raised if the specified value has a syntax error and is unparsable.

NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is readonly or the property is readonly.

If you want to be safe, wrap the call in a try...catch or a condition based on Modernizr.customproperties to ensure that the call is either caught if it throws an exception in legacy browsers, or is only called if the browser supports it.

I also suggest you not use template literals or transpile it to ES5 using Babel.

Community
  • 1
  • 1
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • Please see my answer below. In fact, javascript won't throw any error. – Luca Reghellin Nov 22 '18 at 08:54
  • I never claimed it would necessarily throw an error in your specific case. I provided an answer for the general case. – Patrick Roberts Nov 22 '18 at 09:29
  • I don't think it applies to the general case, in relation to my question. Since the errors detailed by the spec are related to readonly properties (css props are not readonly) and values (not properties) that are unparsable or have a syntax error. I think none of those cases apply when trying to change a --css-property on a legacy browser. – Luca Reghellin Nov 22 '18 at 10:12
  • Please re-read my comment more carefully. Setting a CSS variable is an extremely specific use of `setProperty()` method. The general case means "any input". The point of this answer is that the relevant parts of the specification are here in order for you to make your own logical inferences about your specific use-case. – Patrick Roberts Nov 22 '18 at 20:13
  • Then your answer doesn't really answer to the main question, and thus you should either move your answer to comments, or update it with these new explanations. – Luca Reghellin Nov 23 '18 at 08:45
0

For me, the answer to my question is no, it won't break the javascript. Still, you will need to address css code for browsers that don't support --variables. Specifically, and sadly obviously, Microsoft Edge does support them but it's unable to correctly handle them in some circumstances. This makes it somewhat more buggy than IE11, which simply ignores them.

Consider this code:

  @for $i from 1 through 20{
    // first for legacy browsers
    &[data-current="#{$i}"]{ transform: translateX(-100% * ($i - 1)); }
    // then for modern ones
    &[data-current="#{$i}"]{ transform: translate(calc(-100% * (#{$i} - 1) + var(--distance))); }
  }

and this:

hm.on('pan', function(e){ // (hammer.js)
  slide_strip.style.setProperty('--distance', e.deltaX + 'px');
});

Tested on Android browser 4.4.2, IE11, Edge. Android 4.4.2 and IE11 do not support --variables. Edge does support them, but not inside a calc() passed to transforms.

Behaviours:

  • Android 4.4.2 and IE11: js will just do not set --distance without throwing any error, and they will use the first css rule (due to data-current updates upon a swipe event > not showed here for simplicity). So it will all work as fallback.

  • Edge: js will not throw any error. The browser will read the second css rule, but won't be able to handle it, and the result will bee a motion freeze. So here there should be some kind of addressing. Personally I would use a tool like Bowser to detect the browser type, add a related class to body, and map different css rules based on that.

About the w3c spec, I would like to point out that:

SYNTAX_ERR: Raised if the specified value has a syntax error and is unparsable.

In this case, we are speaking of the value, not the property. Also, the value doesn't have any syntax error.

NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is readonly or the property is readonly.

The property is not readonly, or, it cannot be told (if the browser doesn't support i, it doesn't now about it). I guess..

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118