CSSOM icon indicating copy to clipboard operation
CSSOM copied to clipboard

Preserve multiple definitions of the same property in the same rule?

Open papandreou opened this issue 13 years ago • 21 comments

It's not uncommon for CSS authors to take advantage of the fact that a browser must ignore a CSS property in its entirety if a parse error or unsupported token is encountered in the value. For example:

body {
    background-image: -moz-radial-gradient(center, #a8e936, #76a326);
    background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 800, from(#a8e936), to(#76a326));
    background-image: -webkit-radial-gradient(center, #a8e936, #76a326);
}

If parsed and reserialized using CSSOM only the last of the three background-image properties will survive. In the project I'm working on it would be very desirable to be able to reconstruct the whole thing. I'm not sure if this falls within the scope of CSSOM -- but would it be possible to achieve that behavior somehow?

Best regards, Papandreou

papandreou avatar Feb 28 '11 23:02 papandreou

I fully understand your problem. I'm rewriting the parser in SAC-style. It will allow me to parse CSS into different object models, not just CSSOM. Like so:

body {
    background-image: -moz-radial-gradient(center, #a8e936, #76a326);
    background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 800, from(#a8e936), to(#76a326));
    background-image: -webkit-radial-gradient(center, #a8e936, #76a326);
}

into

{
  "cssRules": [
    {
      "selectorText": "body",
      "style": {
        "0": {
          name: "background-image",
          value: "-moz-radial-gradient(center, #a8e936, #76a326)"
        },
        "1": {
          name: "background-image",
          value: "-webkit-gradient(radial, 50% 50%, 0, 50% 50%, 800, from(#a8e936), to(#76a326))"
        },
        "2": {
          name: "background-image",
          value: "-webkit-radial-gradient(center, #a8e936, #76a326);"
        },
        "length": 3,
        "background-image": [0, 1, 2]
      }
    }
  ]
}

Stay tuned!

NV avatar Mar 01 '11 13:03 NV

Awesome :). That'd be exactly what I need!

papandreou avatar Mar 01 '11 19:03 papandreou

yes, i have the same problem. would be awesome to have this.

stef avatar Mar 20 '11 16:03 stef

I don't think I'll fix it soon. If you want it ASAP you could override CSSStyleDeclaration.prototype.setProperty.

NV avatar Mar 20 '11 20:03 NV

I ended up hacking the CSS parser to continue with a new rule (with an identical selector) if it sees a property redefinition. Seems like that preserves the semantics: https://github.com/One-com/assetgraph/compare/9609d665b8c8e645d8f3...ee00c998754b15c75952#diff-0 (only the changes to lib/3rdparty/CSSOM/lib/parse.js are relevant, don't mind the other diffs).

Haven't looked into doing the opposite during serialization yet.

papandreou avatar Aug 15 '11 07:08 papandreou

@papandreou

img {
  border: none;
  border: 1px solid red;
}

serializes to

img {
  border: none;
}
img {
  border: 1px solid red;
}

The downside is it changes amount of selectors.

NV avatar Sep 12 '11 13:09 NV

@NV: Since I wrote the previous message I've patched the serialization code to do the inverse: https://github.com/One-com/assetgraph/blob/master/lib/3rdparty/CSSOM/lib/CSSStyleSheet.js#L77-L91

So your example now serializes to one rule with a single selector :)

Yes, it's still a hack, and in some corner cases it will collapse neighboring rules with the same selector that were separate originally, but the semantics are preserved and it seems to be adequate for my use case.

papandreou avatar Sep 12 '11 13:09 papandreou

+1 for fixing this, using papandreou fork for now.

sveisvei avatar Dec 08 '11 05:12 sveisvei

+1 vote

quaelin avatar Mar 17 '12 20:03 quaelin

@quaelin: In the mean time you can npm install cssom-papandreou to use my hack.

papandreou avatar Mar 17 '12 20:03 papandreou

Thanks @papandreou, your fork is doing the trick. :)

quaelin avatar Mar 17 '12 22:03 quaelin

Ive been using papandreou fork for some time as well, works great - love OS this way :)

sveisvei avatar Mar 18 '12 08:03 sveisvei

i definitely need this too. do you have the SAC thing open-sourced anywhere?

tj avatar Jul 18 '12 16:07 tj

No, I still haven’t released it.

NV avatar Jul 20 '12 08:07 NV

i ended up just whipping up https://github.com/visionmedia/node-css since I don't (currently at least) need completely parsed selectors / values

tj avatar Jul 20 '12 10:07 tj

+1 for merging in the pull request

nc avatar Oct 23 '12 12:10 nc

This does not seem to have been merged yet. I tried using cssom-papandreou but that doesn't preserve multiple rules for same attribute.

ralyodio avatar Feb 12 '13 19:02 ralyodio

I also need this. https://github.com/papandreou/CSSOM/tree/cssom-papandreou has fixed it, but it does not have the latest version of cssom. So I created another fork: https://github.com/intesso/CSSOM and created a pull request: https://github.com/NV/CSSOM/pull/53.

andineck avatar Mar 19 '13 12:03 andineck

Is there any fix or suggested work around to this yet? Thx!

ryno1234 avatar Aug 27 '13 12:08 ryno1234

vote +1 , this is very important when i use flex. such as

display:-webkit-box; display:-webkit-flex; display:flex;

superlc avatar Jun 29 '16 04:06 superlc

@superlc I recommend using postcss instead, unless it's important to work with the CSSOM api. Postcss doesn't have this limitation.

papandreou avatar Jun 29 '16 09:06 papandreou