2011-10-20 88 views
2

好吧,讓我們說我有一個變量$css,其中包含一些CSS代碼。我想要做的是在每個選擇器前添加一個特定的文本。因此,例如,下面的代碼:在使用PHP的CSS摘錄中爲所有選擇器添加前綴?

#hello, .class{width:1px;height:1px;background-color:#AAA;} 
div{font-size:1px} 
input, a, span{padding:4px} 

將被轉換成:

#someId #hello, #someId .class{ ... } 
#someId div{ ... } 
#someId input, #someId a, #someId span{ ... } 

我一直在嘗試使用幾個explode()秒。但是,我無法有效地完成任務。有什麼想法嗎?

謝謝! JCOC611

+0

每個CSS規則都會在一行上嗎? –

回答

4

基於喬恩的建議,我寫了下面的代碼:

<?php 

$prefix = '#someId'; 
$css = '#hello, .class{width:1px;height:1px;background-color:#AAA;} 
div{font-size:1px} 
input, a, span{padding:4px}'; 

$parts = explode('}', $css); 
foreach ($parts as &$part) { 
    if (empty($part)) { 
     continue; 
    } 

    $subParts = explode(',', $part); 
    foreach ($subParts as &$subPart) { 
     $subPart = $prefix . ' ' . trim($subPart); 
    } 

    $part = implode(', ', $subParts); 
} 

$prefixedCss = implode("}\n", $parts); 

echo $prefixedCss; 

地看到,它的工作原理看http://codepad.org/bqRd83gu

+0

+1哇,非常感謝!它完美的工作! – JCOC611

+1

如果使用@ @ media或'@ font-face'查詢怎麼辦? –

+0

@Kolink好的一點,在這些情況下,這段代碼將不起作用。但正如喬恩指出的那樣,這種類型的代碼是解決這個問題的一個快速和骯髒的解決方案。幸運的是它符合JCOC611的需求。 –

0

它看起來像你需要一個適當的CSS解析器,以便能夠告訴哪裏是每個選擇器的開始。

但是,您可以通過考慮}表示每個選擇器的結束並在每個出現大括號之後插入必要的文本(除最後一個之外)來解決快速而骯髒的解決方案。

+0

你的解決方案的缺陷是有幾個選擇器用逗號分隔的規則。我要去尋找一些解析器;無論如何,你知道如果* QueryPath *可以解析它嗎? – JCOC611

+0

@ JCOC611:確實。我無法回答QueryPath,對不起。 – Jon

0

此方法將前綴添加到所有選擇。

/** 
* Prefix CSS code. 
* 
* @param $prefix prefix to add to all selectors. 
* @param $css CSS code to prefix. 
* @return CSS  the prefixed CSS 
*/ 
function prefixCSS($prefix, $css) { 
    $parts = explode('}', $css); 
    foreach ($parts as &$part) { 
     if (empty($part)) { 
      continue; 
     } 

     $firstPart = substr($part, 0, strpos($part, '{') + 1); 
     $lastPart = substr($part, strpos($part, '{') + 2); 
     $subParts = explode(',', $firstPart); 
     foreach ($subParts as &$subPart) { 
      $subPart = str_replace("\n", '', $subPart); 
      $subPart = $prefix . ' ' . trim($subPart); 
     } 

     $part = implode(', ', $subParts) . $lastPart; 
    } 

    $prefixedCSS = implode("}\n", $parts); 

    return $prefixedCSS; 
} 
3

我寫了改進版本,因爲我還需要媒體查詢。這是我基於Jan的回答:

function getPrefixedCss($css,$prefix){ 
    $parts = explode('}', $css); 
    $mediaQueryStarted = false; 
    foreach ($parts as &$part) { 
     if (empty($part)) { 
      continue; 
     } 

     $partDetails = explode('{',$part); 
     if(substr_count($part,"{")==2){ 
     $mediaQuery = $partDetails[0]."{"; 
     $partDetails[0] = $partDetails[1]; 
     $mediaQueryStarted = true; 
     } 

     $subParts = explode(',', $partDetails[0]); 
     foreach ($subParts as &$subPart) { 
      if(trim($subPart)=="@font-face") continue;  
      $subPart = $prefix . ' ' . trim($subPart); 
     }  

     if(substr_count($part,"{")==2){ 
     $part = $mediaQuery."\n".implode(', ', $subParts)."{".$partDetails[2]; 
     }elseif(empty($part[0]) && $mediaQueryStarted){ 
     $mediaQueryStarted = false; 
     $part = implode(', ', $subParts)."{".$partDetails[2]."}\n"; //finish media query 
     }else{ 
     $part = implode(', ', $subParts)."{".$partDetails[1]; 
     }   
    } 

    $prefixedCss = implode("}\n", $parts); 

    return $prefixedCss; 
} 

它適用於媒體查詢和@ font-face。

1

這是更先進的JohnyFree的變體,很少有dirty修改。

這種變異禮包整個CSS成單行線, 刪除所有CSS註釋,以及,如果$partDetails[1]在年底實際isset檢查,而且比去內爆*(最後else

給JohnyFree更多聲望人,他應得的。

ps:我已經在我進行修改的地方添加了0​​。

function getPrefixedCss($css,$prefix) 
{ 
    # Wipe all block comments 
    $css = preg_replace('!/\*.*?\*/!s', '', $css); 

    $parts = explode('}', $css); 
    $mediaQueryStarted = false; 

    foreach($parts as &$part) 
    { 
     $part = trim($part); # Wht not trim immediately .. ? 
     if(empty($part)) continue; 
     else # This else is also required 
     { 
      $partDetails = explode('{', $part); 
      if(substr_count($part, "{")==2) 
      { 
       $mediaQuery = $partDetails[0]."{"; 
       $partDetails[0] = $partDetails[1]; 
       $mediaQueryStarted = true; 
      } 

      $subParts = explode(',', $partDetails[0]); 
      foreach($subParts as &$subPart) 
      { 
       if(trim($subPart)==="@font-face") continue; 
       else $subPart = $prefix . ' ' . trim($subPart); 
      } 

      if(substr_count($part,"{")==2) 
      { 
       $part = $mediaQuery."\n".implode(', ', $subParts)."{".$partDetails[2]; 
      } 
      elseif(empty($part[0]) && $mediaQueryStarted) 
      { 
       $mediaQueryStarted = false; 
       $part = implode(', ', $subParts)."{".$partDetails[2]."}\n"; //finish media query 
      } 
      else 
      { 
       if(isset($partDetails[1])) 
       { # Sometimes, without this check, 
        # there is an error-notice, we don't need that.. 
        $part = implode(', ', $subParts)."{".$partDetails[1]; 
       } 
      } 

      unset($partDetails, $mediaQuery, $subParts); # Kill those three .. 
     } unset($part); # Kill this one as well 
    } 

    # Finish with the whole new prefixed string/file in one line 
    return(preg_replace('/\s+/',' ',implode("} ", $parts))); 
} 
相關問題