A color control for the WordPress Customizer with support for alpha channel.
This is a customizer control using the react-color colorpicker.
The control will save either a HEX value (#000000
) or RGBA (rgba(0,0,0,0.9)
) depending on the opacity of the selected color. If the color is completely opaque, then it will save a HEX value. If the selected color is not completely opaque (has an alpha value smaller than 1) then the value will be saved as RGBA.
This is a control containing a JS template. As such, it should be whitelisted in the Customizer. To do that we can use the WP_Customize_Manager::register_control_type
method:
add_action( 'customize_register', function( $wp_customize ) {
$wp_customize->register_control_type( '\WPTRT\Customize\Control\ColorAlpha' );
} );
After we register the control using the above code, we can use it in the customizer using the Customizer API:
use \WPTRT\Customize\Control\ColorAlpha;
add_action( 'customize_register', function( $wp_customize ) {
$wp_customize->add_setting( 'your_setting_id' , [
'default' => 'rgba(0,0,0,0.5)', // Use any HEX or RGBA value.
'transport' => 'refresh',
'sanitize_callback' => 'my_custom_sanitization_callback'
] );
$wp_customize->add_control( new ColorAlpha( $wp_customize, 'your_setting_id', [
'label' => __( 'My Color', 'mytheme' ),
'section' => 'my_section',
'settings' => 'your_setting_id',
] ) );
} );
You can use this filter to change the URL for control assets. By default the control will work out of the box for any plugins and themes installed in wp-content/themes
and wp-content/plugins
respectively. It is possible however to change the URL by using the wptrt_color_picker_alpha_url
filter:
add_filter( 'wptrt_color_picker_alpha_url', function() {
return get_template_directory_uri() . '/vendor/wptrt/control-color-alpha';
} );
All controls in the WordPress Customizer should have a sanitize_callback defined. You can write your own function and use it as a sanitization callback, or use the example function below:
/**
* Sanitize colors.
*
* @since 1.0.0
* @param string $value The color.
* @return string
*/
function my_custom_sanitization_callback( $value ) {
// This pattern will check and match 3/6/8-character hex, rgb, rgba, hsl, & hsla colors.
$pattern = '/^(\#[\da-f]{3}|\#[\da-f]{6}|\#[\da-f]{8}|rgba\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|hsla\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|rgb\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)|hsl\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\))$/';
\preg_match( $pattern, $value, $matches );
// Return the 1st match found.
if ( isset( $matches[0] ) ) {
if ( is_string( $matches[0] ) ) {
return $matches[0];
}
if ( is_array( $matches[0] ) && isset( $matches[0][0] ) ) {
return $matches[0][0];
}
}
// If no match was found, return an empty string.
return '';
}
This control allows you to save the value as either a string
or an array
. The default behavior is to save a string
, but you can easily alter that by using the choices
argument in the control:
$wp_customize->add_control( new ColorAlpha( $wp_customize, 'your_setting_id', [
'label' => __( 'My Color', 'mytheme' ),
'section' => 'my_section',
'settings' => 'your_setting_id',
'choices' => [
'save_as' => 'array',
]
] ) );
The value will then be saved using a format like this:
[
'r' => 107, // Red.
'g' => 55, // Green.
'b' => 119, // Blue.
'h' => 289, // Hue.
's' => 37, // Saturation.
'l' => 34, // Lightness.
'a' => 0.82, // Alpha
'hex' => '#6b3777', // The HEX code of the color (alpha = 1)
'css' => 'rgba(107,55,119,0.82)', // The CSS value of the selected color.
'a11y' => [ // An array of accessibility-related properties.
'luminance' => 0.0719,
// Contrast with white (value 0 - 21).
'distanceFromWhite' => 8.613,
// Contrast with black (value 0 - 21).
'distanceFromBlack' => 2.438,
// Maximum contrasting color. Use this to get the text-color
// if the colorpicker is used to select a background-color.
'maxContrastColor' => '#ffffff',
// Readable text-colors on white background preserving the hue.
// The 1st value has a minimum contrast of 7:1 with white.
// The 2nd value has a minimum contrast of 4.5:1 with white.
'readableContrastingColorFromWhite' => [ '#6b3777', '#6b3777' ],
// Readable text-colors on black background preserving the hue.
// The 1st value has a minimum contrast of 7:1 with black.
// The 2nd value has a minimum contrast of 4.5:1 with black.
'readableContrastingColorFromBlack' => [ '#bc83c7', '#a458b5' ],
// True if the color is dark.
'isDark' => true
],
]
If you choose to save the value of this control as an array
, then you will need to change the sanitization function for this setting. You can write your own, or use the one below.
/**
* Sanitize colors.
*
* @since 1.0.0
* @param array $value The color.
* @return array
*/
function my_custom_sanitization_callback( $value ) {
return [
'r' => (int) $value['r'],
'g' => (int) $value['g'],
'b' => (int) $value['b'],
'h' => (int) $value['h'],
's' => (int) $value['s'],
'l' => (int) $value['l'],
'a' => (float) $value['a'],
'hex' => my_custom_color_string_sanitization_callback( $value['hex'] ),
'css' => my_custom_color_string_sanitization_callback( $value['css'] ),
'a11y' => [
'luminance' => (float) $value['a11y']['luminance'],
'distanceFromWhite' => (float) $value['a11y']['distanceFromWhite'],
'distanceFromBlack' => (float) $value['a11y']['distanceFromBlack'],
'maxContrastColor' => my_custom_color_string_sanitization_callback( $value['a11y']['maxContrastColor'] ),
'isDark' => (float) $value['a11y']['isDark'],
'readableContrastingColorFromWhite' => [
my_custom_color_string_sanitization_callback( $value['a11y']['readableContrastingColorFromWhite'][0] ),
my_custom_color_string_sanitization_callback( $value['a11y']['readableContrastingColorFromWhite'][1] ),
],
'readableContrastingColorFromBlack' => [
my_custom_color_string_sanitization_callback( $value['a11y']['readableContrastingColorFromBlack'][0] ),
my_custom_color_string_sanitization_callback( $value['a11y']['readableContrastingColorFromBlack'][1] ),
]
]
];
}
/**
* Sanitize colors.
*
* @since 1.0.0
* @param string $value The color.
* @return string
*/
function my_custom_color_string_sanitization_callback( $value ) {
// This pattern will check and match 3/6/8-character hex, rgb, rgba, hsl, & hsla colors.
$pattern = '/^(\#[\da-f]{3}|\#[\da-f]{6}|\#[\da-f]{8}|rgba\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|hsla\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|rgb\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)|hsl\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\))$/';
\preg_match( $pattern, $value, $matches );
// Return the 1st match found.
if ( isset( $matches[0] ) ) {
if ( is_string( $matches[0] ) ) {
return $matches[0];
}
if ( is_array( $matches[0] ) && isset( $matches[0][0] ) ) {
return $matches[0][0];
}
}
// If no match was found, return an empty string.
return '';
}
You'll need to use an autoloader with this. Ideally, this would be Composer. However, we have a basic autoloader available to include with themes if needed.
From the command line:
composer require wptrt/control-color-alpha
If using the WPTRT autoloader, use the following code:
include get_theme_file_path( 'path/to/autoload/src/Loader.php' );
$loader = new \WPTRT\Autoload\Loader();
$loader->add( 'WPTRT\\Customize\\Control', get_theme_file_path( 'path/to/control-color-alpha/src' ) );
$loader->register();