问题
I have parsed a given CSS file/string into a JSON object like so:
{
"#header": {
"color": "#000000"
},
"#header h1": {
"color": "#000"
},
"h1": {
"color": "#4fb6e5"
}
}
What I want to do now is re-order them based on Specificty. In this case, the #header h1
should come after the h1
in the JSON object as this is how they'll be applied in the browser.
How can I do this? Are there any existing libraries for this? Or any useful libraries to help with this?
I can use both Javascript/jQuery or PHP to do this. I'm looking for implementation advice and hopefully this has already been done!
回答1:
Short answers:
Are there any existing libraries for this?
No, not one I'm aware of that does this "out-of-the-box" for you.
Or any useful libraries to help with this?
Yes, there is json_decode and uksort:
$specificity = function($selector) {
/*
* @link http://www.w3.org/TR/selectors/#specificity
*
* 9. Calculating a selector's specificity
*
* A selector's specificity is calculated as follows:
*
* * count the number of ID selectors in the selector (= a)
* * count the number of class selectors, attributes selectors, and
* pseudo-classes in the selector (= b)
* * count the number of type selectors and pseudo-elements in the
* selector (= c)
* * ignore the universal selector
*
* Selectors inside the negation pseudo-class are counted like any other,
* but the negation itself does not count as a pseudo-class.
*
* Concatenating the three numbers a-b-c (in a number system with a large
* base) gives the specificity.
*/
...
return (int) $result;
}
$compare = function($a, $b) use ($specificity) {
return $specificity($a) - $specificity($b)
};
$array = json_decode('{"yours" : "json"}', true);
uksort($array, $compare);
echo json_encode((object) $array);
As this code example shows, it only explains how to calculate the specificity in a comment and it does not contain the code. That's just because I don't have that code at hand, but I have put in there the specification how this is done (at least for CSS 3).
If you're looking for a CSS selector parser, I know about XDOM (because I wrote it). It's available on github: https://github.com/hakre/XDOM - It's a 100% CSS 3 compatible CSS selector parser.
To my best knowledge that is most of what you get as of today in terms of ready-made solutions. All other CSS selector parsers I know of are not compatible with the CSS 3 standard in full because they don't follow the W3C specification. Which might be good for you: If you don't need strict CSS3 compatbility, you might find some other code-chunks that suit your needs already.
回答2:
Actually there is a standard algorithm for ordering by specificity, I think you might want to look at that.
CSS Specificity
Also can be useful some sort of heuristic formula, for example check if there is a leading # or count the amount of spaces and dots.
来源:https://stackoverflow.com/questions/10636340/order-css-based-on-selector-specificity