1

Short question : I've a $css variable containing CSS, I would like to find a given style (in my case the "body" one) in that variable and replace it with custom style.

Basic input output :

/* blablabla */
body {
    background-color:#d0e4fe;
    font-family: 'Afamily', sanas-serif;
}
span {
    padding: 5px
}
h1 {
    color:orange;
    text-align:center;
}
body {
    margin: 10px;
    padding: 5px;
}
p {
    font-family:"Times New Roman";
    font-size:20px;
}

We call magicFunction():

echo magicFunction($css, 'font-color: pink; font-weight: bold;');

And we get :

/* blablabla */
body {
    font-color: pink; font-weight: bold;
}
span {
    padding: 5px
}
h1 {
    color:orange;
    text-align:center;
}
p {
    font-family:"Times New Roman";
    font-size:20px;
}

What's wrong ? Basically I'm stucked here

$bodyPattern = '/body\s\{[.|\s]*/m';
$found = preg_match_all($bodyPattern, $css, $matches);

It found only output stuff like :

"body {
   '"

After the line return ... nothing.

Of course once I'll have the right regexp pattern I'll use preg_replace.

Why I want to do that : I want to apply CssToInlineStyle using my website CSS to build a newsletter, I'd like to change only the body style to avoid some style to be applied (like a background color). EDIT : This point is mentioned to let you know the "why", feel free to comment and give your view point on that, but please consider only the above question as what you're supposed to answer.

4
  • Did you first wonder if email clients accept css like that? Commented Sep 20, 2012 at 11:02
  • Yes they do, at least GMail accepts it, if the rendering is not that good on others that's not a big deal Commented Sep 20, 2012 at 11:05
  • 2
    @Robinv.G. : maybe the cause is "font-color: pink", I admit that's really bad taste ! Commented Sep 20, 2012 at 11:16
  • @MihaiIorga : for your information Facebook is sending email this way Commented Sep 21, 2012 at 14:52

4 Answers 4

1

I believe the regex your after is this: body {(([a-zA-Z0-9:;#%\(\)\'\-])*\s*)*} - you'll need to format it properly for multiline in php.

You need to match every character except { and } to ensure you only capture the body style and not all styles.

I also reccomend using this site to test regex before trying to use it. I do agree with the other comments, I think what your doing is a little mad.. but in the words of Norman Bates 'We all go a little mad sometimes', I know I have. Hope this helps.

EDIT:

<?php
    $css = "body { \n
        color:#899890;\n
        }";
    $pattern = '/body(\s){0,1}{(([a-zA-Z0-9:;#%\(\)\'\-])*\s*)*}/m';
    $found = preg_match_all($pattern, $css, $matches);

    print_r($matches);
?>

produces:

Array
(
    [0] => Array
        (
            [0] => body { 

        color:#899890;

        }
        )

    [1] => Array
        (
            [0] =>  
        )

    [2] => Array
        (
            [0] => 
        )

    [3] => Array
        (
            [0] => ;
        )

)

It seems to work for me.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it works on your sample code, but not on my whole CSS, I reproduce the problem : 1/ quotes aren't correctly handled 2/ multi body entries aren't returned
0

Either you serve your CSS-file with PHP. Or you use something like SASS for using variables in your CSS.

Parsing the CSS with PHP and replace variables using regex will result in very bad performance and put a big load on your server.

1 Comment

My question was not to serve a CSS from my server since external file loading are blocked by many clients. I'm already using LESS but in my case I don't think I can write anything to erase previous declarations. I'm not concerned by performances issue since I run this part of the code only once.
0

I would use css like this.

<style>
<? include style.php;?>
</style>

Now on style.php

body { <? magicFunction('font-color: pink; font-weight: bold;');
?> 
}

h1 {
    color:orange;
    text-align:center;
}
p {
    font-family:"Times New Roman";
    font-size:20px;
}

And magicFunction would be like this

function magicFunction($style) {
    echo $style;
}

3 Comments

This is an ugly trick, but since I use LESS I do not think embedded PHP code would do anything good. This also put dependencies in the style for a small feature of my app.
@AsTeR: it's an ugly trick alright, but instead of embedding PHP in LESS (which would most likely result in compile error), it would be much easier to generate a LESS file from PHP.
Which would require to run PHP, then to run less and this while a client is waiting ... bad idea
0

one way to avoid needing to do this is by exploiting the cascading feature of CSS:

body {
    background-color:#d0e4fe;
    font-family: 'Afamily', sanas-serif;
}

<? if (...): ?>
    body {
        // overrides the definitions applied above
        background-color: inherit;
        font-family: inherit;

        // and define your own rules
        font-color: pink; 
        font-weight: bold;
    }
<? endif; ?>

9 Comments

see @vusan answer and my comment
@AsTeR: I was not suggesting embedded PHP, instead you put this code on the HTML file; the if statement can alternatively be replaced with a /* */ if you don't even use PHP for generating the HTML.
Well TMHO that's the same approach
@AsTeR: why? AFAICT, there is no trickery needed. Unless you have another requirement that you're not telling.
@AsTeR: in fact, since you already have the $css in a variable, you can just concatenate your new rules to that variable if you wish.
|

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.