Skip to content

[cssom] CSSStyleRule.style assignability (?) differs across browsers #1506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jyc opened this issue Jun 7, 2017 · 6 comments
Closed

[cssom] CSSStyleRule.style assignability (?) differs across browsers #1506

jyc opened this issue Jun 7, 2017 · 6 comments
Labels
cssom-1 Current Work

Comments

@jyc
Copy link

jyc commented Jun 7, 2017

EDIT: It seems like the difference arises due to Safari and Edge not implementing PutForwards, which is an attribute on the style field of CSSStyleRule (https://drafts.csswg.org/cssom/#the-cssstylerule-interface).


Is CSSStyleRule.style supposed to be live (if that's the right term)? In Firefox and Chrome, the following example will output "", while in Safari it will output "3px":

<style id="styles">
div { margin: 10px; }
</style>

<script>
var style = document.getElementById("styles").sheet;
var ruleList = style.cssRules;
var rule = ruleList[0];

rule.style.margin = "3px";

//console.log("before " + rule.style.margin);
// in all browsers, this is '3px'

// this is what assert_readonly in testharness.js does
var initial = rule["style"];
rule["style"] = initial + "a";
rule["style"] = initial;

console.log(rule.style.margin);
// in Chrome and Firefox, this is '', while in Safari, this is '3px'

rule.style.margin = "10px";

//console.log("end " + rule.style.margin);
// in all browsers, this is '10px'
</script>

This is sort of a related issue for Typed OM, where the eventual decision was for the corresponding object to be live: w3c/css-houdini-drafts#149

@dholbert
Copy link
Member

dholbert commented Jun 7, 2017

[EDIT: updating this comment to simplify testcase further & correct myself; I previously misunderstood what was going on under the hood in Safari/Edge]

More direct testcase:

<style id="styles">
div { font-family: AAA }
</style>

<script>
var rule = document.getElementById("styles").sheet.cssRules[0];
console.log("Initial: " + rule.style.fontFamily);

// Tweak rule.style.* and see if it took effect
rule.style.fontFamily = "BBB";
console.log("After tweaking rule.style.fontFamily: " + rule.style.fontFamily);

// Tweak rule.style itself, and see if it took effect:
rule.style = "font-family: CCC";
console.log("After tweaking rule.style: " + rule.style.fontFamily);

// Clear rule.style and see if it took effect
rule.style = "";
console.log("After clearing rule.style: " + rule.style.fontFamily);
</script>

In Firefox 55 Nightly & Chrome Dev 60, this outputs:

Initial: AAA
After tweaking rule.style.fontFamily: BBB
After tweaking rule.style: CCC
After clearing rule.style:

In Safari 10.1 & Edge 15, this instead outputs:

Initial: AAA
After tweaking rule.style.fontFamily: BBB
After tweaking rule.style: BBB
After clearing rule.style: BBB

The last two lines are where we differ -- specifically, browsers disagree about what happens when you directly set CSSStyleRule.style to some value (though they agree on what happens when CSSStyleRule.style.whatever is tweaked.)

  • In Firefox & Chrome, we allow rule.style to be assigned directly (which simply updates the contents of the object)
  • In Safari & Edge, rule.style does not accept direct assignments (though its properties can be assigned).

@dbaron dbaron added the cssom-1 Current Work label Jun 7, 2017
@dholbert
Copy link
Member

dholbert commented Jun 7, 2017

So for me, this boils down to a question of what "readonly" means here in CSSOM 6.4.3:

[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;

...vs. in this later text in the same section:

The style attribute must return a CSSStyleDeclaration object for the style rule, with the following properties:

  • readonly flag
    Unset.

I'm not 100% sure which of those are authoritative about whether or not CSSStyleRule.style can be assigned to... CC @bzbarsky who I suspect will know.

@dbaron
Copy link
Member

dbaron commented Jun 7, 2017

The first "readonly" there is the IDL attribute, saying that the style property doesn't have a setter. (On the other hand, it does have a PutForwards=cssText that is setter-like, and requires the presence of readonly.) See readonly and PutForwards. This means that assignment to style forwards to assignment to style.cssText.

The second "readonly" you quote there is whether the CSSStyleDeclaration object's mutation methods work; see readonly flag.

@dholbert dholbert changed the title [cssom] CSSStyleRule.style liveness (?) differs across browsers [cssom] CSSStyleRule.style assignability (?) differs across browsers Jun 7, 2017
@bzbarsky
Copy link

bzbarsky commented Jun 7, 2017

Right. All that's happening here is that Safari and Edge don't implement that PutForwards bit from the spec, so assigning to .style is a no-op there (or an exception in strict mode code), while assigning to .style is the same as assigning to .style.cssText in Firefox and Chrome.

@dholbert
Copy link
Member

dholbert commented Jun 7, 2017

Thanks! I think all is well here spec-wise, then.

For WebKit, this is tracked in https://bugs.webkit.org/show_bug.cgi?id=164537 (technically that bug is about Element.style, but it has the same issue).

Unlike WebKit, Edge gets this correct for Element.style -- e.g. it correctly honors the height tweak in document.documentElement.style="height:5px";alert(document.documentElement.style.height); But it gets it wrong for CSSStyleRule. I'll file an Edge issue for that.

@dholbert dholbert closed this as completed Jun 7, 2017
@dholbert
Copy link
Member

dholbert commented Jun 7, 2017

I filed https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12271447/ on this incompatibility in Edge (CC @gregwhitworth )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cssom-1 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants