5

I want to be able to read a CSS file, and be able to extract all declarations of a given selector in to a string. For example, given the following stylesheet:

h1 {
  font-size: 15px;
  font-weight: bold;
  font-style: italic;
  font-family: Verdana, Arial, Helvetica, sans-serif;
}

div.item {
  font-size: 12px;
  border:1px solid #EEE;
}

I want to be able to call and get div.item, something like:

$css->getSelector('div.item');

Which should give me a string like:

font-size:12px;border:1px solid #EEE;

I have been looking around but can't find a parser that can do exactly that. Any ideas?

FYI: I need this to be able to convert selectors from a CSS and embed the styles dynamically in to HTML elements in email messages.

SOLUTION EDIT: I came up with my own crude solution and created a class to do what I was looking for. See my own answer below.

4
  • 1
    Googling for "php css parser" gave me this as the first hit: github.com/sabberworm/PHP-CSS-Parser Commented Dec 14, 2011 at 13:41
  • Yes, looked at that. It can't do individual selectors... that's in his todo list. Commented Dec 14, 2011 at 13:42
  • very nice solution you should put that as the answer Commented Dec 14, 2011 at 15:00
  • Thanks. Apparently I have to wait for 8 hours... so I just edited my post. Commented Dec 14, 2011 at 15:41

2 Answers 2

2

I guess this is what you are looking for:

http://classes.verkoyen.eu/css_to_inline_styles

CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very usefull when you're sending emails. I'm using it right now and works fine.

An example using some methods:

$html = file_get_contents('blue.html');

// my styles are stored inside the html

$cssConverter = new CSSToInlineStyles();
$cssConverter->setCleanup(true);
$cssConverter->setHTML($html);
$cssConverter->convert(true);
$cssConverter->setUseInlineStylesBlock(true);

$new_html = $cssConverter->convert();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. But I wrote my own class... see my question.
2

I came up with my own crude solution and created a class to do what I was looking for. My sources are referenced at the bottom.

class css2string {
    var $css;

    function parseStr($string) {
        preg_match_all( '/(?ims)([a-z0-9, \s\.\:#_\-@]+)\{([^\}]*)\}/', $string, $arr);
        $this->css = array();
        foreach ($arr[0] as $i => $x)
        {
            $selector = trim($arr[1][$i]);
            $rules = explode(';', trim($arr[2][$i]));
            $this->css[$selector] = array();
            foreach ($rules as $strRule)
            {
                if (!empty($strRule))
                {
                    $rule = explode(":", $strRule);
                    $this->css[$selector][trim($rule[0])] = trim($rule[1]);
                }
            }
        }
    }

    function arrayImplode($glue,$separator,$array) {
        if (!is_array($array)) return $array;
        $styleString = array();
        foreach ($array as $key => $val) {
            if (is_array($val))
                $val = implode(',',$val);
            $styleString[] = "{$key}{$glue}{$val}";

        }
        return implode($separator,$styleString);   
    }

    function getSelector($selectorName) {
        return $this->arrayImplode(":",";",$this->css[$selectorName]);
    }

}

You can run it as follows:

$cssString = "
h1 {
  font-size: 15px;
  font-weight: bold;
  font-style: italic;
  font-family: Verdana, Arial, Helvetica, sans-serif;
}

div.item {
  font-size: 12px;
  border:1px solid #EEE;
}";

$getStyle = new css2string();
$getStyle->parseStr(cssString);
echo $getStyle->getSelector("div.item");

The output would be as follows:

font-size:12px;border:1px solid #EEE

This solution works even with comments within your CSS file, as long as the comments are not inside selectors.

References: http://www.php.net/manual/en/function.implode.php#106085 http://stackoverflow.com/questions/1215074/break-a-css-file-into-an-array-with-php

4 Comments

What happens if you have comments in your css? $cssString = "h1 { /* a } comment*/ }";
Well, I built this for myself and I don't expect to have comments in my CSS. Feel free to modify and update it to fulfill your needs.
Fair enough, just don't be surprised if something breaks all of a sudden when you do decide to comment your code :)
Thanks... I know it's need another preg_match inside the for loop to discard the comment. But again, don't need to worry about it right now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.