Generating dynamic CSS file for ACF options page


I’m trying to dynamically generate a CSS file that will pull values from an ACF options page. I’ve configured options pages in ACF where the user can define various theme styles like text colors, etc.

I’ve spent several hours digging around online and found several people doing this by simply creating a 'styles.php' file and adding that to the head. Others have said that’s a bad approach and recommended using wp_enqueue_styles instead.

I came across the following tutorial that calls a function upon saving the ACF options page to generate a CSS file from the PHP file:

I’ve tried adding the following function to extras.php and even functions.php but when I save the ACF options page, it does not generate the theme-styles.css file.

function generate_options_css() {
    $ss_dir = get_stylesheet_directory();
    require($ss_dir . 'dist/styles/theme-styles.php');
    $css = ob_get_clean();
    file_put_contents($ss_dir . 'dist/styles/theme-styles.css', $css, LOCK_EX);
add_action('acf/save_post', 'generate_options_css', 20);

Can someone help me figure out why this isn’t working or propose a better solution?

A second related question:
I’m using SASS with Roots Sage. Is there a way to use SASS in this situation? That is, can I write SCSS inside the theme-styles.php file and have Gulp convert it to CSS while still maintaining the PHP hooks?

Thanks in advance to anyone who can help. I’ve built a few themes on Roots in the past, but I’m definitely a more novice developer. Thanks!

Not sure if this helps, but you should be name spacing your functions -

add_action('acf/save_post', __NAMESPACE__ . '\\generate_options_css', 20);

As for the SASS, I’d take a look at some other plugins and such to get an idea for how other people do it. JetPack’s Custom CSS module allows for vanilla CSS, Less, or SASS. You might take a look at that.

It injects the styles into the head, as opposed to a stylesheet though. I’m okay with this personally, and that’s probably how I’d handle the options page thing (internal style block in the head).

Thanks for the reminder about namespacing. I fixed that but the function still does not work.

How would you inject the styles into the head? I know I could link the theme-styles.php file in the head.php but I’ve read that has a negative impact on performance because the PHP is being read every time the page loads.

Is there another way to preemptively generate plain CSS from the PHP file?

I’m not sure what issues you are having with file_put_contents but you could implement the WordPress Filesystem API in its place.

If you were happy to print the CSS inline you could use a transient to cache or site option to save the CSS generated.

To transpile SCSS to CSS you’ll need to implement something like sass.js.

Thanks. I ended up just injecting the CSS in the head for simplicity.