Custom Stylesheet in WordPress with Advanced Custom Fields and the ACF Options Add-On

I absolutely love Advanced Custom Fields and us it for every WordPress based project I develope. This, in hand with the Custom Post Types UI plugin really help to flesh out WordPress as a much more complete content management system.

With the help of many other WordPress users and Google searches I have been using ACF and the Options add-on to generate custom stylesheets. That way, administrators can easily go into the WordPress Dashboard and modify the look of the site without having to dig into the CSS directly.

To make sure I didn’t forget how I accomplished this in the futre, and to have a guide for doing so in upcoming projects, I decided to write out this small guide.

A couple things of note:

  • This guide is based off of the most current version of ACF (4.1.1) as of May 6th, 2013 and is best used with the premium Options add-on for ACF.
  • I use a sub-directory called “layouts” for all of my css file (excluding the WordPress required style.css). I would recommend the same approach as it helps to keep your files structured and easy to find later. Especially if you tend to use a lot of different stylecheets (Bootstrap, Font-Awesome, ie-hacks, etc.).

Lets start off by adding a new folder called “inc” to our theme directory. Create a new file in here called custom-styles.php.

The contents of your new file will look a lot like standard CSS but you will have the ability to add all sorts of custom php and ACF field data. For example…

/* Typography
body {
 color:<?php the_field('default_text_color','option');?>;
 font-size:<?php the_field('default_font_size','option');?>px;
 font-family:<?php the_field('default_text_font_family','option');?>;
 line-height:<?php the_field('default_text_line_height','option');?>;

h1,h2,h3,h4,h5,h6 {
 color:<?php the_field('default_headline_color','option');?>;
 font-family:<?php the_field('defaut_header_font_family','option');?>;

a {color:<?php the_field('default_link_color','option');?>;}
a:hover{color:<?php the_field('default_linkhover_color','option');?>;}
a:active{color:<?php the_field('default_linkactive_color','option');?>;}
a:focus{color:<?php the_field('default_linkfocus_color','option');?>;}
a:visited{color:<?php the_field('default_linkvisited_color','option');?>;}

This is just a small example of the code possible and is based off of fields I have created for my Options page with ACF. The fields created, and how you choose to use them are all up to you!

Next, we’ll be adding the following code to our functions.php file. this code will parse out our custom-style.php file and write a brand new custom-style.css file in our layouts directory.

function generate_options_css() {
    $ss_dir = get_stylesheet_directory();
    ob_start(); // Capture all output into buffer
    require($ss_dir . '/inc/custom-styles.php'); // Grab the custom-style.php file
    $css = ob_get_clean(); // Store output in a variable, then flush the buffer
    file_put_contents($ss_dir . '/layouts/custom-styles.css', $css, LOCK_EX); // Save it as a css file
add_action( 'acf/save_post', 'generate_options_css', 20 ); //Parse the output and write the CSS file on post save (thanks Esmail Ebrahimi)

The code above can be modified to read from and store the files in various directories and with different filetypes.

Finally, we’ll enqueue the style so it appears in our page header and links to the brand new CSS file. Add this to your enqueue function in the functions.php file. This should probably be added as the last enqueued style in the function. This way, our new CSS file will be read last and have the ability to override any existing styles. (I should note that this portion is really dependent on your theme. How you add stylesheets to your theme is ultimately up to you, but it is highly recommended that you use the enqueue_style function in your functions.php.)

wp_enqueue_style( 'custom-styles', get_template_directory_uri() . '/layouts/custom-styles.css' );

To sum up, we are reading a custom-style.php file that can contain dynamic php elements. When a page is requested, the functions.php file fires off and parses this file outputing a brand new custom-style.css.

Obviously, we’re not limited to only generating css files. This could be used to generate any filetype your require. I’m also not a master level PHP coder and if anyone has any recommendations on how to better implement this strategy, please let me know.

23 Responses to “Custom Stylesheet in WordPress with Advanced Custom Fields and the ACF Options Add-On”

  1. Luke Clifton says:

    Hi, found your code snippet useful. And also have an improvement for you. The only issue with your function is that it will be called every time a user loads a page within the site. This means that you will be generating your css file every page load. This is not clever. Call the function using this action instead: This means that the css file is only generated when a ACF post is saved i.e your options page.

  2. Colin Tait says:

    Great post, thanks for the info.

    How do I get this working with an image field?

    Been looking everywhere and can’t find an answer.

    Thanks again

    • wglassbrook says:

      Lets say I have a div with a class of “image” and I want to apply a background image to it via a image field in my custom stylesheet. If we use the default “Image Object” to return data from the image field, we would use something like this in the template file…

      < ?php $image = get_field('image'); if( !empty($image) ): ?>
      background: transparent url('< ?php echo $image['url']; ?>') no-repeat center center;
      < ?php endif; ?>

      If you use another value to return data such as “Image ID”, you’d have to refer to the ACF documentation, but those are the basics.

  3. Colin Tait says:

    I have been working on this in a child theme but when I paste the lines into the functions.php I get the following error

    Parse error: syntax error, unexpected ‘$ss_dir’ (T_VARIABLE) in C:\xampp\htdocs\testsite\wp-content\themes\LochcarronCorporate\functions.php on line 3

    line 3:    $ss_dir = get_stylesheet_directory();

    line 6:    $css = ob_get_clean(); // Store output in a variable, then flush the buffer

    Does anyone know how to fix this error, is it something really simple, as I know others have got it working no problem.

  4. Tommy says:

    This is great! Exactly what I’ve been looking forward.

    However, I’m using Multisite, with a network that allows each user to update their colours. This works perfectly for the main blog, but means all the child themes update each other. Do you know of any way to restrict it the child theme? I tried this, but to no avail:

    function generate_options_css() {
    $site = str_replace('/','',$GLOBALS['path']);
    $ss_dir = get_stylesheet_directory();
    require($ss_dir . '/inc/styles.php');
    $css = ob_get_clean();
    file_put_contents($ss_dir . '/assets/css/'.$site.'-child.css', $css, LOCK_EX);
    add_action( 'acf/save_post', 'generate_options_css' );

  5. Bob says:

    Hi, got the code working in chrome and safari, but the code does not work in firefox.
    It does not load the php functions inside the stylesheet.

    Is there a fix for this?
    I hope so!!

    • wglassbrook says:

      I haven’t had any issues with this code in Firefox and am using it in several production sites. Perhaps it’s a caching issue? Take a look at your page source and see if the custom-styles.css file is being called in the html.

  6. Keith Shaw says:

    This is incredible, you can also use conditional logic to apply certain styles via checkboxes. Really nice post!

  7. Laura says:

    Hi there. I’m having trouble getting this work. The function doesn’t appear to actually be writing to the custom-styles.css file. Not sure why. I’m using ACF version 4.4.5. Could that be the problem? Any help would be appreciated.

  8. esmail ebrahimi says:

    hi again
    i using this great code and that worked perfectly
    just a little problem exists

    when i save acf options in my theme settings ; in first time, css file not change, but i second saving, the css file create nice
    so my customers and i have to save acf options 2 times

    can you help me ?

  9. esmail ebrahimi says:

    i found the problem section
    when we using below action , reading fields data fired before saving their data in database
    add_action( ‘acf/save_post’, ‘generate_options_css’ );

    just change this line to below
    add_action( ‘acf/save_post’, ‘generate_options_css’ , 20);


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>