0

複数の CSS を 1 つに生成するスクリプトに取り組んでいます。そして、これがスクリプトです。

    $full_string = "";

    foreach($allfiles as $curfile => $file) {           
        $file = $PATH[$curfile] . $file;
        $file_open = fopen($file , 'r');
        $concat = "\n" . fread($file_open , filesize($file)) . "\n";
        $full_string .= $concat;
        fclose($file_open);
    }

    return $full_string;

ここでは、すべての CSS ファイルを 1 つに結合しています。しかし、現在の問題は、現在の CSS($file) を別の CSS(と考えてみましょう) と比較する必要があることoverrider.cssです。そして $file が次のようなスタイルを持っている場合、

h1 {
    color: white; 
    background: teal; 
    FONT-FAMILY: arial, helvetica, lucida-sans, sans-serif; 
    FONT-SIZE: 18pt; 
    FONT-STYLE: normal; 
    FONT-VARIANT: normal;
}

body 
{
    font-family: arial;
    FONT-SIZE: 14px; 
}

そして、overrider.css が次のようなスタイルを持っている場合、

body 
{
    font-family: Calibri;
    color: #3E83F1; 
}

次に、生成される最終的な CSS(output.css) は、次のようになります。

h1 {
    color: white; 
    background: teal; 
    FONT-FAMILY: arial, helvetica, lucida-sans, sans-serif; 
    FONT-SIZE: 18pt; 
    FONT-STYLE: normal; 
    FONT-VARIANT: normal;
}

body 
{
    font-family: Calibri;
    FONT-SIZE: 14px;
    color: #3E83F1;
}

ここでは、 body の style がoverride.csshavefont-familyにあるため、元の CSS の font-family プロパティを置き換えます。色は、元の CSS ファイルである ($file) には存在しない新しいプロパティであるため、元の CSS ファイルにプロパティを追加する必要があります。 CSS ファイル。CSSの解析について何も考えていないので、PHPでこれを達成する方法。これに関するアイデアは大歓迎です。

file1($file) および file2(override.css) として入力を指定して新しい CSS ファイルを生成する必要があることに注意してください。スタイルをオーバーライドして output.css を生成する必要があります。

前もって感謝します。

4

3 に答える 3

1

利用可能な CSS パーサーがいくつかあります (google "php css parser")。このようなものは試していませんが、興味深いものです。しかし、個人的には自分で解析を行います-その種の疑似PHPアルゴリズムに従います

  • すべてのファイルを 1 つの文字列に読み取り、Strすべての "\n"、"\r"、および "\t" をスペースに置き換えます (解析を (少し) 簡単にするため)

次に、処理する関数 (セレクター => ルール)

func deal with selectors and rules:

rules = array()
do {
  S = string from current pos to next `{` excluded (selectors)
  R = string from '{' to next '}' (rules)
  r = explode(';', R) 
  lr = make array of rules from r trimmed elements
  s = explode (',', S)
  ls = make array of [selector => lr]

  // same sel: latest rule overwrite existing, added if not exist
  merge ls into rules 
} while (not '}' and not '@' and not EOF); // the '}' would be the closing media

return rules

メディアを処理するためのメイン関数、および上記の関数を呼び出す

medias = array();

func deal with Str
do {
  if (first non blank char is @) {
     media = array of listed medias
     eat fist '{'
  }
  else {
     media = array ('GLOBAL')
  }
  selectorsrules = deal with selectors and rules(rest of Str)

  foreach (media as m) {
    merge in medias(m) selectorsrules, same procedure as above
  }
} while (not EOF);

興味深いプロジェクトですが、完全に実装する時間がありません。結果はmedias配列です。

于 2013-02-28T06:49:43.670 に答える
0

次の 2 つの選択肢があります。

  1. 簡単な方法は、css ファイルを変更し、重要な場所に !important を追加することです。たとえば、css に「body」を複数回含めるのは正しいことです。そして、オーバーライドするスタイルをいつでも残してください。もちろん、この種のアプローチはほとんど手動です。どこが上書きされ、どこが上書きされないかを知る必要があります。

  2. 2 番目のアプローチでは、文字列の解析と正規表現が必要です。つまり、文字列広告を解析する方法を知っておく必要があります。各ファイルのコンテンツを取得して文字列に保存し、両方にタグが存在するかどうかを正規表現を使用して比較し、タグのコンテンツをマージする必要があります。この方法は言うのは簡単ですが、実行するのは難しいです。

于 2013-02-28T06:13:55.563 に答える
0

適用したい場合は、font-family: arial;次のように追加しますfont-family: arial !important;

ブラウザーは、最初の CSS で見つかった色の 2 番目の CSS から自動的に body タグに色を追加し、2 番目の CSS で上書きするため、マージについて心配する必要はありません。

于 2013-02-28T06:05:03.637 に答える