I am working on a WordPress theme and need to allow theme users to set different values for some controls for each device (desktop, tablet, mobile) I am thinking to show/hide device specific variant of some controls on the basis of what device/size user is previewing in customizer (desktop, tablet, mobile).

Is there a way to show/hide controls when user switch devices from customizer responsive previewer?

Also note that I am using Kirki for all my customizer controls, all done using kirki.

Here is a use case to understand this better. I got a typography control for headlines as follows.

Kirki::add_field( 'start', array(
'type'        => 'typography',
'settings'    => 'headings_typography',
'label'       => __( 'Headings', 'start' ),
'section'     => 'base_typography',
'transport' => 'auto',
'default'     => array(
    'font-family'    => '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif',
    'variant'        => 'regular',
'output'      => array(
        'element' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ),
) );

I may create 2 more variants of the same control each for (desktop, tablet & mobile) and may output the values based on media queries.

The only thing I am not able to do is how to show/hide control for device-specific preview in the customizer?

TIA, Munir

2 Answers 2


I'm not familiar working with Kikri, but I've made a standalone example plugin that shows the approach I'd use to get controls to be contextual based on the previewed device.

The plugin adds colored outlines around each element in the site, with a different color for elements in desktop, tablet, and mobile (obviously just for demonstration purposes). There are then color controls specific to each device, and only the device for the current previewed device is shown at a given time.

The key logic in the plugin is found in wpse-286268-controls.js:

_.each( component.deviceControls, function( controlId, deviceSlug ) {
    api.control( controlId, function( control ) {
        function isActive() {
            return deviceSlug === api.state( 'previewedDevice' ).get();

        // Set initial active state.
        control.active.set( isActive );

        // Update active state whenever previewd device changes.
        api.state( 'previewedDevice' ).bind( function() {
            control.active.set( isActive );
        } );

        // Override whatever the active_callback may send from server when preview loads.
        control.active.validate = isActive;
    } );
} );

The isActive function returns whether the control should be active according to the current previewed device, and then this function is used to set each control's active state, and then each control's active state is updated when the previewedDevice state changes. Lastly, since these controls are registered with PHP, we override the validate method to prevent the active_callback for the control from overriding the active state we set in JS (whenever the preview refreshes the active_callback for the control will be called on the server and sent back when the preview refreshes to update the active state).


Here is my solution on this with Kirki.

I hope this may help some people.

"use strict";

wp.customize.bind('ready', function () {

    var previousDevice;

    // first load device
    wp.customize.previewer.bind('ready', function () {
        // Update Custom respsonsive Buttons
        var loadedDevice = wp.customize.previewedDevice.get();
        var firstDevice = $('.sb-devices .preview-' + loadedDevice);

        // Update Controls
        var getControls = $('li[id*="_resp_' + loadedDevice + '"]');

        // Update previous device
        previousDevice = loadedDevice;


    // Update device on change
    wp.customize.previewedDevice.bind(function () {

        if (previousDevice) {
            // Get updated device
            var reloadedDevice = wp.customize.previewedDevice.get();

            var updateDevice = $('.sb-devices .preview-' + previousDevice);

            var updateControls = $('li[id*="_resp_' + previousDevice + '"]');

            var setDevice = $('.sb-devices .preview-' + reloadedDevice);

            var setControls = $('li[id*="_resp_' + reloadedDevice + '"]');

            previousDevice = reloadedDevice;


    // Update preview device on custom buttons click
    $('.sb-devices > div').on('click', function () {


The js file needs to be enqueued with customize_controls_enqueue_scripts

And with the Kirki custom control you create something like this:

Kirki::add_field( 'domain_kirki_options', [
'type'        => 'custom',
'settings'    => '',
'section'     => 'domain_theme_header_section',
'default'     => '<div class="sb-device-holder">
                    <span class="customize-control-title">
                        Setting Title
                    <div class="sb-devices">
                        <div class="preview-desktop" data-device="desktop"></div>
                        <div class="preview-tablet" data-device="tablet"></div>
                        <div class="preview-mobile" data-device="mobile"></div>
'priority'    => 10,]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.