Is there a CSS optimizer that will detect identical single properties in selectors and group them together?

Here is an example of what I expect:

Entrance:

a { background: red; } p { background: red; } strong { background: red; color: green; } 

Conclusion:

 strong{color:green;} a,p,strong{background:red;} 

Most optimizers will output something like this:

 strong{background:red;color:green;} a,p{background:red;} 

Note that he did not understand the fact that strong , although it contains color: green; , also contains background: red; , so can it be grouped with others?

Any help you could provide would be greatly appreciated.

All the best

Yane

+4
source share
2 answers

Okay, so it seems that I was after either not existing or very hard to find, so I wrote a script that solves my specific problem. I insert it here in the hope that someone will someday find it useful.

 <?php $css = file_get_contents('test.css'); //Strip comments and whitespace. Tabs to spaces $css = preg_replace("/\s{2,}/e", ' ', $css); $css = preg_replace("/\/\*.*?\*\//", '', $css); $css = str_replace("\t", " ", $css); $css = str_replace(": ", ":", $css); $css = str_replace(" }", "}", $css); $css = str_replace("{", "{", $css); $css = str_replace(";}", "}", $css); //Break each rule out onto a new line $css = preg_replace("/}\s*/", "}\r\n", $css); //Break @ rules out onto new lines $css = preg_replace('/(@.*?;\s*)/', '\0'."\r\n", $css); //Parse CSS Rules $parsed = array(); $css = explode("\r\n", $css); foreach($css as $line => $rule){ if (preg_match('/(.*?)\{(.*?)\}/i', $rule, $regs)) { $clean_selectors = preg_replace('/\s*,\s*/', ',', $regs[1]); $clean_selectors = preg_replace('/,\s*$|\s$/', '', $clean_selectors); $parsed[$line]['selectors'] = explode(',', $clean_selectors); $parsed[$line]['properties'] = explode(';', $regs[2]); } elseif(trim($rule) != '') { $parsed[$line] = $rule; } } //Group CSS by property $groups = array(); foreach($parsed as $line => $css){ if(is_array($css)){ foreach($css['properties'] as $pline => $property){ if(isset($groups[$property])){ $groups[$property] = array_merge($groups[$property], $css['selectors']); } else { $groups[$property] = $css['selectors']; } } } else { $groups[$line] = $css; } } //Output CSS sorted by property foreach($groups as $property => $selectors){ if(is_array($selectors)){ asort($selectors); echo implode(",\r\n", $selectors)." {\r\n\t".trim($property).";\r\n}\r\n\r\n"; } else { echo $selectors."\r\n\r\n"; } } ?> 

Now a few folders.

  • No, this is not the most beautiful code in the world, it was done quickly to solve one specific problem that I once encountered, and it adapted very much to the CSS that I had to work with. However, it should be general enough to work with most of the CSS that you throw at it.

  • This is the nature of CSS, which is sometimes the order in which a rule appears, which is important for rendering the final document. It is likely that if you just run all of your CSS through this script, your page will not display as you expect. I just use this script to group page-specific CSS in a web application, I don't have layout control. Since each rule applies to a specific element on a specific page, I do not expect a huge amount of tricks when I group in this way - it just makes CSS more convenient.

0
source

Maybe CSSTidy can help here.

If you look at this CSS before , you will see this piece of code:

 a:hover{ color: #DD6900; } a.admin:hover,a.mod:hover{ color: #DD6900; } 

In CSS after you get:

 a:hover,a.admin:hover,a.mod:hover,a.topictitle:hover { color:#DD6900 } 

Not sure if this will deal with all possible cases - but in some situations it seems like he is doing what you ask; -)

+2
source

Source: https://habr.com/ru/post/1302340/


All Articles