diff --git a/ctools.info b/ctools.info
index b2c54ad..045b083 100644
--- a/ctools.info
+++ b/ctools.info
@@ -3,5 +3,7 @@ description = A library of helpful tools by Merlin of Chaos.
 core = 7.x
 package = Chaos tool suite
 files[] = includes/context.inc
+files[] = includes/css-cache.inc
 files[] = includes/math-expr.inc
 files[] = includes/stylizer.inc
+files[] = tests/css_cache.test
diff --git a/ctools.install b/ctools.install
index 63677fc..b4bd50f 100644
--- a/ctools.install
+++ b/ctools.install
@@ -142,6 +142,21 @@ function ctools_schema_1() {
 }
 
 /**
+ * Implements hook_install().
+ */
+function ctools_install() {
+  // Activate our custom cache handler for the CSS cache.
+  variable_set('cache_class_cache_ctools_css', 'CToolsCssCache');
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function ctools_uninstall() {
+  variable_del('cache_class_cache_ctools_css');
+}
+
+/**
  * Enlarge the ctools_object_cache.name column to prevent truncation and weird
  * errors.
  */
@@ -217,3 +232,10 @@ function ctools_update_6008() {
     )
   );
 }
+
+/**
+ * Enable the custom CSS cache handler.
+ */
+function ctools_update_7000() {
+  variable_set('cache_class_cache_ctools_css', 'CToolsCssCache');
+}
diff --git a/ctools.module b/ctools.module
index b5ab626..62aade9 100644
--- a/ctools.module
+++ b/ctools.module
@@ -546,19 +546,10 @@ function ctools_cron() {
 }
 
 /**
- * Ensure the CTools CSS cache is flushed whenever hook_flush_caches is invoked.
+ * Implements hook_flush_caches().
  */
 function ctools_flush_caches() {
-  // Do not actually flush caches if running on cron. Drupal uses this hook
-  // in an inconsistent fashion and it does not necessarily mean to *flush*
-  // caches when running from cron. Instead it's just getting a list of cache
-  // tables and may not do any flushing.
-  if (!empty($GLOBALS['locks']['cron'])) {
-    return;
-  }
-
-  ctools_include('css');
-  ctools_css_flush_caches();
+  return array('cache_ctools_css');
 }
 
 /**
diff --git a/includes/css-cache.inc b/includes/css-cache.inc
new file mode 100644
index 0000000..2a2300f
--- /dev/null
+++ b/includes/css-cache.inc
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Custom cache implementation for the CTools CSS cache.
+ */
+
+class CToolsCssCache implements DrupalCacheInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clear($cid = NULL, $wildcard = FALSE) {
+    // Only clear the caches if the wildcard is set, this ensures that the cache
+    // is only cleared when the full caches are cleared manually (eg by invoking
+    // drupal_flush_all_caches()), and not on a cron run.
+    // @see drupal_flush_all_caches()
+    // @see system_cron()
+    if ($wildcard) {
+      ctools_include('css');
+      ctools_css_flush_caches();
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get($cid) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMultiple(&$cids) {
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function set($cid, $data, $expire = CACHE_PERMANENT) {
+  }
+
+}
\ No newline at end of file
diff --git a/tests/css_cache.test b/tests/css_cache.test
new file mode 100644
index 0000000..e289b42
--- /dev/null
+++ b/tests/css_cache.test
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @file
+ * Tests the custom CSS cache handler.
+ */
+
+/**
+ * Tests the custom CSS cache handler.
+ */
+class CtoolsObjectCache extends DrupalWebTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Ctools CSS cache',
+      'description' => 'Tests the custom CSS cache handler.',
+      'group' => 'Chaos Tools Suite',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp('ctools');
+  }
+
+  /**
+   * Tests the custom CSS cache handler.
+   *
+   * @see https://drupal.org/node/1313368
+   */
+  public function testCssCache() {
+    // Create a CSS cache entry.
+    $filename = ctools_css_cache('body { color: red; }');
+
+    // Perform a cron run. The CSS cache entry should not be removed.
+    $this->cronRun();
+    $this->assertTrue(file_exists($filename), 'The CSS cache is not cleared after performing a cron run.');
+
+    // Manually clear the caches. The CSS cache entry should be removed.
+    drupal_flush_all_caches();
+    $this->assertFalse(file_exists($filename), 'The CSS cache is cleared after clearing all caches.');
+  }
+
+}
