使用PHP从HTML文档中的CSS文件中提取所有使用的样式

时间:2015-05-23 19:27:30

标签: php css

我想从HTML文档中的CSS文件中提取所有使用的样式。

如果有像:

这样的HTML
<div class="blue"></div>

和CSS文件一样:

.blue {
  background-color: #2196F3 !important; }
.red {
  background-color: #F44336 !important; }

PHP代码应该产生一个输出:

.blue {
  background-color: #2196F3 !important; }

目的是为HTML文档带来CSS样式以防止render-blocking CSS

我认为它需要一个HTML和CSS解析器。

2 个答案:

答案 0 :(得分:2)

只是一个粗略的想法,

假设我的html文件是:

<body class="container">
 <div class="row bg-red">
  <div class="col-md-12">
  </div>
 </div>
</body>
  1. 使用正则表达式在.html文件中的类中获取字符串,如:

    <.... class="....." >|/>
    
  2. 子字符串并按空格分割

  3. 以多维数组存储它(准备存储类嵌套,如:[0] = container, [0][0] = row, [0][0][0] = col-md-12, [0][1] = bg-red

  4. 阅读.css个文件和所有<style>

  5. 开始读取多维数组,如

    • 检查array [0] = container,然后搜索css,<style>查找.container
    • 检查array [0][0] = row,然后搜索.row
    • 检查array [0] [0][0] = .container .row
    • 检查array [0][0][0] = col-md-12,然后搜索.col-md-12
    • 检查array [0] [0][0] [0][0][0] = .container .row .col-md-12
    • 如果找到,请检查css中所有“”是否匹配。

      • ex。 '.container' = match
      • ex。 '.container .row' = match
      • ex。 '#main .container' = match
      • ex。 '.container .row .detail' = not match
      • ex。 '.container > .row' = match
  6. 注意:这只是一个非常粗略的想法,您需要更多地考虑处理需要继续的CSS,例如.container > .row

答案 1 :(得分:0)

我取得了我的确切结果,我认为这将有助于许多想要根据Google Pagespeed Insights建议优化其网站的人。

use PHPHtmlParser\Dom;
ob_start();
?><!doctype html>
<html>
<head>
.....

</body>
</html><?PHP
$html = ob_get_contents();
ob_end_clean();
$md5 = md5($html);
if($memcached->append($md5, NULL)==TRUE){
    echo $memcached->get($md5);
}else{
    //add to HTML in style labels the CSS Used and minimized the result
    $dom = new Dom;
    $dom->load($html);
    $style = '';
    foreach($css_files as $css_file){
        $md5CSS = md5_file($css_file);
        if($memcached->append($md5CSS, NULL)==TRUE){
            $cssParsed = $memcached ->get($md5CSS);
        }else{
            $cssContent = file_get_contents($css_file);
            $oSettings = Sabberworm\CSS\Settings::create()->withMultibyteSupport(false)/*->beStrict()*/;
            $oCssParser = new Sabberworm\CSS\Parser($cssContent, $oSettings);
            $cssParsed = $oCssParser->parse();
            $memcached->set($md5CSS, $cssParsed);
        }
        foreach ($cssParsed->getContents() as $oItem) {
            if ($oItem instanceof Sabberworm\CSS\CSSList\KeyFrame)
                continue;
             if ($oItem instanceof Sabberworm\CSS\RuleSet\AtRuleSet)
                continue;
            if($oItem instanceof Sabberworm\CSS\RuleSet\DeclarationBlock){
                $oBlock = $oItem;
                $selectors = array();
                foreach($oBlock->getSelectors() as $oSelector)
                    $selectors[] = $oSelector->getSelector();
                if(count($dom->find(implode(",",$selectors))) > 0)
                    $style .= $oBlock->render(Sabberworm\CSS\OutputFormat::createCompact());
            }
            if ($oItem instanceof Sabberworm\CSS\CSSList\AtRuleBlockList) {
                foreach($oItem->getContents() as $oBlock) {
                    $selectors = array();
                    foreach($oBlock->getSelectors() as $oSelector)
                        $selectors[] = $oSelector->getSelector();
                    if(count($dom->find(implode(",",$selectors))) > 0){
                        $style .= $oItem->render(Sabberworm\CSS\OutputFormat::createCompact());
                        break;
                    }
                }
            }            
        }
    }
    $styleLabel = '<style type="text/css">'.$style.'</style>';
    $html = str_replace("</head>", $styleLabel."\n</head>",$html);