【问题标题】:Is there a CSS optimizer that will discover identical single properties in selectors and group them together?是否有一个 CSS 优化器可以在选择器中发现相同的单个属性并将它们组合在一起?
【发布时间】:2010-02-26 09:38:10
【问题描述】:

这是我所期望的一个例子:

输入:

a {
    background: red;    
}

p {
    background: red;    
}

strong {
    background: red;
    color: green;
}

输出:

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

大多数优化器会输出如下内容:

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

注意它没有注意到strong 虽然包含color: green;,但也包含background: red;,因此它可以与其他组合在一起吗?

如果您能提供任何帮助,我们将不胜感激

一切顺利

伊恩

【问题讨论】:

  • 这不是您要求的,但 Google Page Speed 可以识别未使用的 CSS,因此您可以将其完全删除:code.google.com/speed/page-speed/docs/…
  • 你说得对,这不是我要找的东西,但还是很好找 :)

标签: css optimization css-selectors utilities


【解决方案1】:

也许CSSTidy 可以帮忙,在这里。

如果您查看this CSS "before",您会看到这部分代码:

a:hover{
    color: #DD6900;
}

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

CSS "after"中,你会得到:

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

不确定它是否会处理所有可能的情况——但在某些情况下,它似乎正在按照您的要求做 ;-)

【讨论】:

  • 感谢帕斯卡的回复。我见过一些优化器可以做到这一点——而且它非常方便。但是,我所追求的是一个优化器,它可以处理(例如)五个选择器都具有相同的背景颜色,但它们都有不同的边距值的情况。该优化器会识别出五个选择器共享一种背景颜色,因此它会创建一个新组来仅容纳共享的背景颜色,并将每个选择器中的其余属性单独保留。
【解决方案2】:

好的,看来我所追求的东西要么不存在,要么很难获得,所以我编写了一个脚本来解决我的特定问题。我把它贴在这里,希望有人会发现它有用。

<?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"; 
    }
}

?>

现在,有几个注意事项。

  1. 不,这不是世界上最漂亮的代码,它很快就解决了我曾经遇到的一个特定问题,而且它非常适合我使用的 CSS。也就是说,它应该足够通用,可以与你扔给它的大多数 CSS 一起使用。

  2. 有时规则出现的顺序对最终文档的呈现很重要,这是 CSS 的本质。如果您只是通过此脚本运行所有 CSS,您的页面可能不会再按预期呈现。我只是使用此脚本在我无法控制布局的 Web 应用程序上对特定于页面的 css 进行分组。由于每条规则都适用于特定页面上的特定元素,因此我不会期望以这种方式进行分组时会有大量的狡猾 - 它只会使 CSS 更易于维护。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-28
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    相关资源
    最近更新 更多