Existe um otimizador CSS que descobrirá propriedades únicas idênticas nos seletores e os agrupará?
-
22-09-2019 - |
Pergunta
Aqui está um exemplo do que eu esperaria:
Entrada:
a {
background: red;
}
p {
background: red;
}
strong {
background: red;
color: green;
}
Resultado:
strong{color:green;}
a,p,strong{background:red;}
A maioria dos otimistas produzirá algo assim:
strong{background:red;color:green;}
a,p{background:red;}
Observe como não pegou o fato de que strong
, embora contenha color: green;
, também contém background: red;
Assim, pode ser agrupado com os outros?
Qualquer ajuda que você possa fornecer seria muito apreciada
Tudo de bom
Iain
Solução 2
Ok, então parece que eu era o que eu era depois, não existe ou é muito difícil de encontrar, então escrevi um script que resolve meu problema em particular. Estou colando aqui, na esperança de que alguém possa achar útil.
<?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";
}
}
?>
Agora, alguns Cavaets.
Não, este não é o código mais bonito do mundo, foi feito rapidamente para resolver um problema em particular que eu estava tendo uma vez e é fortemente adaptado ao CSS com o qual fui dado para trabalhar. Dito isto, deve ser genérico o suficiente para trabalhar com a maioria dos CSs que você joga nele.
É a natureza do CSS que, às vezes, a ordem em que uma regra aparece é importante para a renderização do documento final. É provável que, se você apenas executar todos os seus CSs através deste script, sua página não renderize mais como você espera. Estou apenas usando esse script para agrupar o CSS específico da página em um aplicativo da Web sobre o qual não tenho controle de layout. Como cada regra se aplica a um elemento específico em uma página específica, não estou esperando enormes quantidades de difusão quando agrupo dessa maneira - isso apenas tornará o CSS mais sustentável.
Outras dicas
Pode ser Csstidy poderia ajudar aqui.
Se você der uma olhada em Este CSS "antes", você verá esta parte do código:
a:hover{
color: #DD6900;
}
a.admin:hover,a.mod:hover{
color: #DD6900;
}
No CSS "depois", você terá :
a:hover,a.admin:hover,a.mod:hover,a.topictitle:hover {
color:#DD6900
}
Não tenho certeza se vai lidar com todos os casos possíveis-mas em algumas situações, parece que está fazendo o que você está pedindo ;-)