Skip to content

Manipulating multiple CSS values with the use of one SWITCHER Control's 'selectors' field. #6241

@iamzenigma

Description

@iamzenigma

Hi,

I've been looking around and I can't find anything concerning this topic. I've been working on a widget and I'm trying to create a SWITCHER-control that lets, let's say, sibling B 'inherit' values from the controls that belong to sibling A.

A More In-Depth Sketch Of The Problem
Sibling A is a container that holds its own CSS-properties and values which the user can define. For example the font size, width, height, padding etc. Now I want sibling B to be able to inherit these properties and values which are defined in A to make it more time-efficient for the user if he or she is planning to style both the same way.

Now I've almost made this work with the use of the 'selectors' key. There's just one problem. I'm able to copy over all the values from multiple controls by defining selectors in the SWITCHER-control, but if one of the values that I'm copying over is 'undefined' the whole 'selector-rule' isn't applied anymore.

An Example Might Be A More Suitable Explainer
I'll try to make it more clear by sharing code.

Here are two controls for sibling A:

$this->add_responsive_control(
    'a_alignment',
    [
        'label' => __( 'Alignment', 'your-text-domain' ),
        'type' => Controls_Manager::CHOOSE,
        'options' => [
            'left' => [
                'title' => __( 'Left', 'your-text-domain' ),
                'icon' => 'fa fa-align-left',
            ],
            'center' => [
                'title' => __( 'Center', 'your-text-domain' ),
                'icon' => 'fa fa-align-center',
            ],
            'right' => [
                'title' => __( 'Right', 'your-text-domain' ),
                'icon' => 'fa fa-align-right',
            ],
        ],
        'default' => 'center',
        'selectors' => [
            '{{WRAPPER}} .sibling-a' => 'text-align: {{VALUE}};',
        ],
    ]
);

$this->add_responsive_control(
    'a_spacing',
    [
        'label' => __( 'Spacing', 'your-text-domain' ),
        'type' => Controls_Manager::SLIDER,
        'range' => [
            'px' => [
                'min' => 0,
                'max' => 100,
            ],
        ],
        'selectors' => [
            '{{WRAPPER}} .sibling-a' => 'margin-bottom: {{SIZE}}{{UNIT}};',
        ],
    ]
);

These controls both manage a different CSS rule, but notice that they both point towards the same element. Also, they are both responsive controls, so for Sibling B to correctly inherit the values in the next step requires 6 CSS rules in total (for tablet 2x, mobile 2x and desktop 2x).

Here's the SWITCHER control for sibling B's inheritance.

$this->add_control(
    'b_inherits_a',
    [
        'label' => __( 'Inherit From Sibling A?', 'your-text-domain' ),
        'type' => Controls_Manager::SWITCHER,
        'default' => 'yes',
        'selectors' => [
            '(desktop){{WRAPPER}} .sibling-b' => 'text-align: {{a_alignment.VALUE}}; margin-bottom: {{a_spacing.SIZE}}{{a_spacing.UNIT}};',
            '(tablet){{WRAPPER}} .sibling-b' => 'text-align: {{a_alignment_tablet.VALUE}}; margin-bottom: {{a_spacing_tablet.SIZE}}{{a_spacing_tablet.UNIT}};',
            '(mobile){{WRAPPER}} .sibling-b' => 'text-align: {{a_alignment_mobile.VALUE}}; margin-bottom: {{a_spacing_mobile.SIZE}}{{a_spacing_mobile.UNIT}};',
        ]
    ]
);

So the problem arises when one of the values of sibling A's controls is undefined (corresponding to the device we're in). So if no value is given for the 'tablet alignment' of A, but a value for A's 'tablet spacing' is given, then B won't inherit the intended A's 'tablet spacing', because 'tablet alignment' causes an error in the syntax of the given CSS rule. (I assume the CSS rule looks something like this: 'text-align: UNDEFINED; margin-bottom: 199px;', but the whole CSS rule gets discarded for the error that arises.

The question
Is there a way to tackle multiple CSS rules on the same element in one selector?

Maybe it's a nice idea to allow an array as a value.

Like so:

'selectors' => [
    '(desktop){{WRAPPER}}` .sibling-b' => [
        'text-align: {{a_alignment.VALUE}};', 
        'margin-bottom: {{a_spacing.SIZE}}{{a_spacing.UNIT}};'
    ]
]

I hope this was somewhat comprehensible!

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions