How to Combine CSS Files Into One File In WordPress

To speed up access to our websites, we need to minimize the number of HTTP requests, one way to achieve it is to combine CSS files, so, in this article, we’ll discuss how to combine CSS files in WordPress into one file.

As a WordPress user, using a lot of CSS files is an unavoidable thing, this happens because our theme uses various CSS file, in addition, some of our plugins also use separate CSS files, so that combining CSS file become a very important task.

I. How to Merge/Combine CSS files in WordPress manually

To combine CSS files manually, do the following steps:

  1. Identify CSS files that are used, the easiest way is open your web page and right-click on it and choose view source, in the source page, find (Ctrl + F) a word “stylesheet”

    Find Stylesheet Loaded on a Page

    Notice the id of each style (as in the red box), the word before -css is the name of the CSS file handle, the handle is used by WordPress to identify each CSS files.

  2. Next, open each CSS file by opening the link in the href attribute, then, copy-paste all CSS code into a single file, for example: merged-style.css and place it in our theme directory that is being used, for example in wp-content\themes\wdc\merged-style.css
  3. Open the functions.php file in the theme directory and load the merged-style.css file using the function: wp_enqueue_style('merged-style', get_stylesheet_uri (). '/merged-style.css')
  4. Deregister all CSS file handle that we have combined by using the function: wp_deregister_style('handle-name'). Done.

Although it looks simple, this method has a lot of drawbacks

Combining CSS files in WordPress manually has several drawbacks such as:

  1. If there are CSS files are added/removed, either when changing the theme or installing/uninstalling plugins, then we have to re-combine all of CSS files manually.
  2. Dependency between CSS file could not be guaranteed work well.
  3. The use of relative URLs such as in background image will potentially result an error (file not found) – explained later.

II. How to Combine CSS Files in WordPress Automatically

The better solution to overcome those disadvantages is to use an automated way, we can do this easily by using the WP_Styles class that stored in the $wp_styles variable

WP_Styles and $wp_styles

WP_Styles and $wp_styles are WordPress class(object) and built-in variable that are used to handle the entire styles that are loaded on a page, this class can be called on many WordPress hooks, like wp_enqueue_style, wp_print_styles, wp_head, init, etc.

To view the content of this object, open the functions.php file located in the theme directory, and then copy-paste the following code:

add_action('admin_enqueue_scripts', 'show_all_styles');
function show_all_styles()
{
    // use global to call variable outside function
    global $wp_styles;
     
    // show all data
    echo '<pre>'; print_r($wp_styles); echo '</pre>';
}

Next, open a web page, you’ll see the properties of this object either in an object or array form.

Note that there is a queue property ($wp_styles->queue), this property contains list of style handles that will be loaded on the page.

BUT these handles has not been sorted by its dependency, hence to be able to work properly, we need to re-arrange them using all_deps() method, which we’ll discuss shortly.

Get all of the style handles based on its dependency

WP_Styles object has a lot of method, one of them is all_deps method. To see a complete list is of the methods, visit this page: Class Reference/WP Styles »WordPress Codex

This method will automatically sort the css files according its dependency and the results will be stored on the to_do property ($wp_styles->to_do)

The following code will print all styles sorted by its dependency:

add_action('wp_enqueue_scripts', 'show_all_styles');
function show_all_styles()
{
    // use global to call variable outside function
    global $wp_styles;
     
    // arrange the queue based on its dependency
    $wp_styles->all_deps($wp_styles->queue);  
     
    // The result
    $handles = $wp_styles->to_do;
     
    echo '<pre>'; print_r($handles); echo '</pre>';
}

Well, now the $handles variable already contains all of the styles that have been sorted by its dependency, so it ready to use for processing the handles.

Combine all of the styles

Once we get all of the handle, then we ready to combine all of the CSS file.

Step we need:

  1. Combine all the css code on each css file and then save it in a file (e.g. merged-styles.css). To find the location of the css file: (1) find the registered property  ($wp_styles->registered), (2) Find the name of the handle in the array key ($wp_styles->registered['handle']) and then find the URL path.
  2. Load the merged file using wp_enqueue_style() function.
  3. Deregister all CSS File handles that have already been merged using wp_deregister_scripr() function.
  4. Copy-paste the following code into functions.php file in the theme directory
    add_action('wp_print_styles', 'show_all_styles');
    function show_all_styles()
    {
    	// use global to call variable outside function
    	global $wp_styles;
    	
    	// arrange the queue based on its dependency
    	$wp_styles->all_deps($wp_styles->queue);	
    	
    	// The result
    	$handles = $wp_styles->to_do;
    	
    	$css_code = '';
    
    	// New file location: E:xampp\htdocs\wordpress\wp-content\theme\wdc\merged-style.css
    	$merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-style.css';
    	
    	// loop all styles
    	foreach ($handles as $handle)
    	{
    		/*
    			Clean up the url, for example: wp-content/themes/wdc/style.min.css?v=4.6
    			become wp-content/themes/wdc/style.min.css
    		*/
    		$src = strtok($wp_styles->registered[$handle]->src, '?');
    		
    		// #1. Combine CSS File.
    		// If the src is url		
    		if (strpos($src, 'http') !== false)
    		{
    			// Get thr site url, e.g. http://webdevzoom.com/wordpress
    			$site_url = site_url();
    		
    			/*
    				If the css file come from local server, change the full url into relative path
    				For example: http://webdevzoom.com/wordpress/wp-content/plugins/wpnewsman/css/menuicon.css
    				Become: /wp-content/plugins/wpnewsman/css/menuicon.css
    				
    				Otherwise, leave it as is, e.g: https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
    			*/
    			if (strpos($src, $site_url) !== false)
    				$css_file_path = str_replace($site_url, '', $src);
    			else
    				$css_file_path = $src;
    			
    			/*
    				In order to be able to use file_get_contents function, we need to remove preceding slash,
    				For example: /wp-content/plugins/wpnewsman/css/menuicon.css
    				Become: wp-content/plugins/wpnewsman/css/menuicon.css
    			*/
    			$css_file_path = ltrim($css_file_path, '/');
    		} 
    		else 
    		{			
    			$css_file_path = ltrim($src, '/');
    		}
    		
    		// Check wether file exists then merge
    		if  (file_exists($css_file_path)) {
    			$css_code .=  file_get_contents($css_file_path);
    		}
    	}
    
    	// write the merged styles into current theme directory
    	file_put_contents ( $merged_file_location , $css_code);
    	
    	// #2. Load the URL of merged file
    	wp_enqueue_style('merged-style',  get_stylesheet_directory_uri() . '/merged-style.css');
    	
    	// #3. Deregister all handles
    	foreach ($handles as $handle)
    	{
    		wp_deregister_style($handle);
    	}
    }
  5. Make sure everything goes well, open a web page and check the CSS file, there should only be one file, namely merged-styles.css

    How to Combine CSS Files in WordPress Into One File - Merged FIles

Again, this way contain a serious drawbacks. The use of relative paths in the url, such as background-image will cause a serious error “file not found”, this will potentially break our site layout

For example, css in a particular plugin uses an image from the img directory inside the plugin directory, e.g. background: url('img/plg_logo.png'), when we combine this css code and we place in the new location, for example in a theme directory, then for sure the plg_logo.png file will not be found.

III. How to Combine CSS files in WordPress automatically – Fixing Relative Path

Next, we need to correct the relative path, so all CSS files will work properly.

We don’t need to write our own script to accomplish this task because it requires a fairly complex analysis (if you have times yo may do this task).

Instead, there are several libraries that are ready to use, but the problem is, not much of them up to date following the development of the CSS itself.

One that is quite up to date is “Path Converter” and Minify developed by Matthias Mullie, but in fact, we can not directly use it.

If we want to use path converter, first, we need to parse the CSS code to find the relative path, then use this tool to convert the URL.

Otherwise, if we wan’t to use the Minify, we need to write each css file to a file, this is the only way this tool convert the relative path automatically, this not efficient (especially with lots of css file), we want to combine all css files at once then write it to a file, instead.

So, we need a little modification:

  • In Minify.php file, add/modufy the following script:
    abstract class Minify
    {
        private $toPath = '';
         
        public function setToPath($path)
        {
            $this->toPath = $path;
        }
         
        public function minify($path = null)
        {
            $toPath  = $this->toPath ?: $path;
            $content = $this->execute($toPath);
     
            // save to path
            if ($path !== null) {
                $this->save($content, $path);
            }
     
            return $content;
        }
    }

    Or, you can download the final code here.

  • But, you’ll want to check the latest version on github and then read the manual, if it still not support custom from-to converter, change the Minify.php file according to the above code
  • While using Minify, don’t forget to include the “Path Converter” library which needed by the Minify to change the relative path automatically, just download the Converter.php file and placed it in the src directory

    Path-Converter

  • Further, copies all of the “Minify” file to our theme directory, e.g. wp-content/themes/yourtheme/Minify, the structure as shown below:

    Include the Minifier Library Into Theme

Combine and Minify

After modifying the file Minify.php file, change our code that we have created earlier into the following:

add_action('wp_enqueue_scripts', 'show_all_styles');
function show_all_styles()
{
    // use global to call variable outside function
    global $wp_styles;
     
    // arrange the queue based on its dependency
    $wp_styles->all_deps($wp_styles->queue);  
     
    // The result
    $handles = $wp_styles->to_do;
     
    $css_code = '';
     
    // New file location: E:xampp\htdocs\wordpress\wp-content\theme\wdc\merged-style.css
    $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-style.css';
     
    //Including Minifylibrary
    require_once('minify\src\Minify.php');
    require_once('minify\src\CSS.php');
    require_once('minify\Converter.php');
     
    // loop all styles
    foreach ($handles as $handle)
    {
        /*
            Clean up the url, for example: wp-content/themes/wdc/style.min.css?v=4.6
            become wp-content/themes/wdc/style.min.css
        */
        $src = strtok($wp_styles->registered[$handle]->src, '?');
         
        // #1. Combine CSS Files.
        // If src is url        
        if (strpos($src, 'http') !== false)
        {
            // dapatkan site url, misal: http://jagowebdev.com/wordpress
            $site_url = site_url();
         
            /*
                If the css file come from local server, change the full url into relative path
                For example: http://webdevzoom.com/wordpress/wp-content/plugins/wpnewsman/css/menuicon.css
                Become: /wp-content/plugins/wpnewsman/css/menuicon.css
                 
                Otherwise, leave it as is, e.g: https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
            */
            if (strpos($src, $site_url) !== false)
                $css_file_path = str_replace($site_url, '', $src);
            else
                $css_file_path = $src;
             
            /*
                In order to be able to use file_get_contents function, we need to remove preceding slash,
                For example: /wp-content/plugins/wpnewsman/css/menuicon.css
                Become: wp-content/plugins/wpnewsman/css/menuicon.css
            */
            $css_file_path = ltrim($css_file_path, '/');
        } 
        else 
        {           
            $css_file_path = ltrim($src, '/');
             
        }
         
        // Cek wether file exists, then merge
        if  (file_exists($css_file_path)) {
            $minifier = new MatthiasMullie\Minify\CSS($css_file_path);
            $minifier->setToPath( $merged_file_location );
            $css_code .=  $minifier->minify($css_file_path);
        }
    }
 
    // write the merged styles into current theme directory
    file_put_contents ( $merged_file_location , $css_code);
     
    // #2. Load the URL of merged file
    wp_enqueue_style('merged-style',  get_stylesheet_directory_uri() . '/merged-style.css');
     
    // #3. Deregister all handles
    foreach ($handles as $handle)
    {
        wp_deregister_style($handle);
    }
}

Explanation:

  • On line 19-21, we add the library files
  • On line 66-68, we use the Minify class to minify the CSS files and simultaneously adjust the url path (if any) in accordance with the new location of the merged file ( merged-style.css ).

Done. Check whether the process works well. Open your web page and view it source, then open the merged-style.css by clicking the href attribute of <link> tag.

Furthermore…

Despite we have successfully combined all css files, we need to consider other important matters, such as:

  • The use of cache. Combining CSS file each time the page is loaded is not efficient at all, so we need to cache (server side cache) the merged file.
  • Use dynamic file name. If we only use single file name and the file is cached by the browser, then if we generate new merged file, the browser will still use the old one because the file name is same, hence we need to change our merged file name each time we merging the CSS file.
  • The use of other compressor tools such as YUI Compressor.

With the addition of those features, not relevant anymore if we still made it in the theme, so we need to separate it into a plugin.

To achieve that, you’ll want to develop your own plugins by learning the existing plugin, or use the existing one.

There are lot of plugins that do the such task, on of them is MinQueue, this plugin is nice but can not automatically combine all javascript and css files into one file, so I developed a plugin: APH Merge Script, you my want to give it a try.

Closing…

So far, we can combine CSS files in WordPress into one file using either manual way or automatic way.

The manual way is not recommended because it contains many-many drawbacks, while using the automatic way, we need to make some adjustments especially to the url path which is certainly not easy task.

Well, as an alternative, we can use a plugin such as MinQueue or APH Merge Scripts.

Subscibe Now

Loves articles on webdevzoom.com? join our newsletter to get quality article right to your inbox. Nothing else, just quality stuff!!!

Related Post

Leave a comment

Like Us

Newsletter

Great information from webdevzoom.com right to your inbox

We value your privacy
  1. 7 Best Free Online Image Compressor & Optimizer Tools – Compared & Tested

  2. 40+ Modern Free WordPress Themes For Blog in 2017 – Beautiful & Responsive

  3. Understanding Constant in PHP – Updated to PHP 7

  4. Understanding Variable in PHP – All PHP Version

  5. Retrieve Data From Multiple Tables in MySQL – JOIN in MySQL

  6. How to Calculate Date and Time Difference in PHP – The Easiest Way

  7. Understanding Time, Mktime, and Strtotime Function in PHP

  8. Understanding Timezone and Time Difference in PHP

  9. Understanding Return in PHP

  10. How to Install MySQL Zip File on Windows – A Step by Step Guide