I absolutely love Advanced Custom Fields and use 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 ACF Options Page Admin add-on to generate custom stylesheets. That way, site 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.
This is just so great.
Thankis. Wade
This is a pretty neat way to use ACF. I appreciate you taking the time to writeup such concise directions.
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: http://www.advancedcustomfields.com/resources/actions/acfsave_post. This means that the css file is only generated when a ACF post is saved i.e your options page.
Good call Luke! Thanks for the input. Will edit the post accordingly.
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
Colin
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…
.image{
background: transparent url('') no-repeat center center;
}
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.
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.
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();
ob_start();
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' );
Tommy I have the same issue, have you got a way around it yet
just want to say “thank you” for this cool trick 🙂
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!!
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.
This is incredible, you can also use conditional logic to apply certain styles via checkboxes. Really nice post!
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.
I actually just found a solution over on another site (http://aquagraphite.com/2011/11/dynamically-generate-static-css-files-using-php/) I’m not sure why it works better for me, but in case anyone else has any issues making it work, they can check things out over there.
This is pretty neat, and works beautifully.
A thousand Thank you i’ve been looking for something similar !!
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 ?
thanks
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);
enjoy
Good catch! Never had the issue myself but I’ve edited the post to reflect your change. Thanks Esmail!