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


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).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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