Index: src/wp-includes/class-wp-customize-manager.php
===================================================================
--- src/wp-includes/class-wp-customize-manager.php	(revision 29006)
+++ src/wp-includes/class-wp-customize-manager.php	(working copy)
@@ -1182,28 +1182,6 @@
 }
 
 /**
- * Sanitizes a hex color.
- *
- * Returns either '', a 3 or 6 digit hex color (with #), or null.
- * For sanitizing values without a #, see sanitize_hex_color_no_hash().
- *
- * @since 3.4.0
- *
- * @param string $color
- * @return string|null
- */
-function sanitize_hex_color( $color ) {
-	if ( '' === $color )
-		return '';
-
-	// 3 or 6 hex digits, or the empty string.
-	if ( preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) )
-		return $color;
-
-	return null;
-}
-
-/**
  * Sanitizes a hex color without a hash. Use sanitize_hex_color() when possible.
  *
  * Saving hex colors without a hash puts the burden of adding the hash on the
@@ -1215,16 +1193,21 @@
  * @since 3.4.0
  * @uses sanitize_hex_color()
  *
- * @param string $color
- * @return string|null
+ * @param string $color The hex color to remove the hash from.
+ * @return string|null The color with the removed hash.
  */
 function sanitize_hex_color_no_hash( $color ) {
 	$color = ltrim( $color, '#' );
 
-	if ( '' === $color )
+	if ( '' === $color ) {
 		return '';
+	}
 
-	return sanitize_hex_color( '#' . $color ) ? $color : null;
+	if ( is_hex_color( '#' . $color ) ) {
+		return $color;
+	} else {
+		return null;
+	}
 }
 
 /**
@@ -1235,12 +1218,13 @@
  *
  * @since 3.4.0
  *
- * @param string $color
- * @return string
+ * @param string $color The color to "sanitize" to prepend a hash to.
+ * @return string The color with the prepended hash.
  */
 function maybe_hash_hex_color( $color ) {
-	if ( $unhashed = sanitize_hex_color_no_hash( $color ) )
+	if ( $unhashed = sanitize_hex_color_no_hash( $color ) ) {
 		return '#' . $unhashed;
+	}
 
 	return $color;
 }
Index: src/wp-includes/formatting.php
===================================================================
--- src/wp-includes/formatting.php	(revision 29006)
+++ src/wp-includes/formatting.php	(working copy)
@@ -3972,3 +3972,39 @@
 
 	return $spaces;
 }
+
+/**
+ * Validates a hex color.
+ *
+ * @since 4.0.0
+ *
+ * @param string $color The color to validate.
+ * @return bool True if the value is a valid hex color; false if it is not.
+ */
+function is_hex_color( $color ) {
+	$clean_color = sanitize_hex_color( $color );
+	return ! empty( $clean_color );
+}
+
+/**
+ * Sanitizes a hex color.
+ *
+ * Returns either '', a 3 or 6 digit hex color (with #), or null.
+ *
+ * @since 4.0.0
+ *
+ * @param string $color The color to "sanitize".
+ * @return string|null The color value if value; empty string if empty; null if not valid.
+ */
+function sanitize_hex_color( $color ) {
+	if ( '' === $color ) {
+		return '';
+	}
+
+	// 3 or 6 hex digits, or the empty string.
+	if ( preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
+		return $color;
+	}
+
+	return null;
+}
\ No newline at end of file
Index: tests/phpunit/tests/formatting/color.php
===================================================================
--- tests/phpunit/tests/formatting/color.php	(revision 0)
+++ tests/phpunit/tests/formatting/color.php	(working copy)
@@ -0,0 +1,132 @@
+<?php
+/**
+ * @group formatting
+ * @group color
+ */
+class Tests_Formatting_Color extends WP_UnitTestCase {
+	/**
+	 * @ticket 27583
+	 */
+	function test_valid_colors_pass_validation() {
+		// Numeric 3 digit
+		$color = '#333';
+		$this->assertTrue( is_hex_color( $color ) );
+
+		// Alphanumeric 3 character
+		$color = '#f4A';
+		$this->assertTrue( is_hex_color( $color ) );
+
+		// Alpha 3 character
+		$color = '#fff';
+		$this->assertTrue( is_hex_color( $color ) );
+
+		// Numeric 6 digit
+		$color = '#333333';
+		$this->assertTrue( is_hex_color( $color ) );
+
+		// Alphanumeric 6 character
+		$color = '#ff44AA';
+		$this->assertTrue( is_hex_color( $color ) );
+
+		// Alpha 6 character
+		$color = '#ffffff';
+		$this->assertTrue( is_hex_color( $color ) );
+	}
+
+	/**
+	 * @ticket 27583
+	 */
+	function test_invalid_colors_do_not_pass() {
+		// Too many characters
+		$color = '#1234567';
+		$this->assertFalse( is_hex_color( $color ) );
+
+		// Too few characters
+		$color = '#12';
+		$this->assertFalse( is_hex_color( $color ) );
+
+		// Missing #
+		$color = 'ffffff';
+		$this->assertFalse( is_hex_color( $color ) );
+
+		// Invalid character
+		$color = '#f9a%ad';
+		$this->assertFalse( is_hex_color( $color ) );
+
+		// Empty string
+		$color = '';
+		$this->assertFalse( is_hex_color( $color ) );
+
+		// Whitespace
+		$color = '#ff fff';
+		$this->assertFalse( is_hex_color( $color ) );
+	}
+
+	function test_removal_of_hash_from_colors() {
+		require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+
+		// Numeric 3 digit
+		$color = '#333';
+		$color_no_hash = '333';
+		$this->assertEquals( $color_no_hash, sanitize_hex_color_no_hash( $color ) );
+
+		// Alphanumeric 3 character
+		$color = '#f4A';
+		$color_no_hash = 'f4A';
+		$this->assertEquals( $color_no_hash, sanitize_hex_color_no_hash( $color ) );
+
+		// Alpha 3 character
+		$color = '#fff';
+		$color_no_hash = 'fff';
+		$this->assertEquals( $color_no_hash, sanitize_hex_color_no_hash( $color ) );
+
+		// Numeric 6 digit
+		$color = '#333333';
+		$color_no_hash = '333333';
+		$this->assertEquals( $color_no_hash, sanitize_hex_color_no_hash( $color ) );
+
+		// Alphanumeric 6 character
+		$color = '#ff44AA';
+		$color_no_hash = 'ff44AA';
+		$this->assertEquals( $color_no_hash, sanitize_hex_color_no_hash( $color ) );
+
+		// Alpha 6 character
+		$color = '#ffffff';
+		$color_no_hash = 'ffffff';
+		$this->assertEquals( $color_no_hash, sanitize_hex_color_no_hash( $color ) );
+	}
+
+	function test_prepend_hash_on_color_without_hash() {
+		require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+
+		// Numeric 3 digit
+		$color = '#333';
+		$color_no_hash = '333';
+		$this->assertEquals( $color, maybe_hash_hex_color( $color_no_hash ) );
+
+		// Alphanumeric 3 character
+		$color = '#f4A';
+		$color_no_hash = 'f4A';
+		$this->assertEquals( $color, maybe_hash_hex_color( $color_no_hash ) );
+
+		// Alpha 3 character
+		$color = '#fff';
+		$color_no_hash = 'fff';
+		$this->assertEquals( $color, maybe_hash_hex_color( $color_no_hash ) );
+
+		// Numeric 6 digit
+		$color = '#333333';
+		$color_no_hash = '333333';
+		$this->assertEquals( $color, maybe_hash_hex_color( $color_no_hash ) );
+
+		// Alphanumeric 6 character
+		$color = '#ff44AA';
+		$color_no_hash = 'ff44AA';
+		$this->assertEquals( $color, maybe_hash_hex_color( $color_no_hash ) );
+
+		// Alpha 6 character
+		$color = '#ffffff';
+		$color_no_hash = 'ffffff';
+		$this->assertEquals( $color, maybe_hash_hex_color( $color_no_hash ) );
+	}
+}
\ No newline at end of file
