Skip to content
Block Controls

Conditional Logic

Conditional Logic hides a control in the block editor until its rules pass. A block with a Layout select and eight layout-specific options shows two controls instead of nine, and the seven that do not apply are out of the way rather than greyed out.

Rules are set per control. Open the control in the block builder, find Conditional Logic in its settings, and add a rule.

Conditional logic settings

What a rule can test

A rule has three parts: what to look at, an operator, and a value to compare against.

The first dropdown lists every control on the block under a Controls heading, and two more sources under Other:

SourceWhat it reads
any controlthat control's stored value
CSS Class Namethe block's className attribute, which holds whatever a user typed in the Advanced panel
Block Stylesthe applied style variation, matched through className

Block Styles is greyed out until the block has at least one style variation.

A control inside a Repeater appears in the list under its parent, and stores its target as parent-name.child-name.

Operators

Nine operators exist. Which ones the second dropdown offers depends on the control type, because most of them only make sense for some kinds of value.

LabelStored valueOffered for
Has any value!=emptyevery control except Checkbox, Toggle, Inner Blocks and Message, plus both Other sources
Has no value==emptythe same list
Is equal to==Text, Textarea, Number, Range, URL, Email, Password, Rich Text, Classic Editor, Code Editor, Select, Radio, Color Picker, Date Time Picker, Units, Checkbox, Toggle
Is not equal to!=the same list
Contains==containsthe Is equal to list minus Checkbox and Toggle, plus CSS Class Name
Is greater than>Number, Range, Gallery, Posts, Taxonomy, Users, Repeater
Is less than<the same list
Has class==classCSS Class Name
Has no class!=classCSS Class Name

On Block Styles the last two are labelled Has style and Has no style.

Two control types behave differently from the rest. Checkbox and Toggle are not offered the empty operators at all, and their value field is locked to a single option, Checked. Inner Blocks has a name so it appears in the list, but no operator applies to it, so its operator dropdown comes up empty.

The value field changes with the source. Select and Radio give you a dropdown of their own choices, Block Styles gives you a dropdown of the block's style variations, and everything else is a text field.

A count, not a value

For Gallery, Repeater, Posts, Taxonomy and Users, Is greater than and Is less than compare the number of items, not the value. "Is greater than 2" on a Gallery control means the block has three images or more. On a Repeater it means three rows or more.

The same conversion makes the empty operators work on these controls: an empty gallery counts as no value, so Has no value passes.

Posts, Taxonomy and Users only hold a list when their Multiple setting is on. With Multiple off they hold a single value, and the range operators compare that value as a number instead of counting it.

Rules, and groups of rules

Inside a group, and joins the rules. Every rule in the group has to pass.

Between groups, or joins them. The control is shown when any one group passes in full.

So this pair of groups:

Group 1   layout        Is equal to        grid
          images        Is greater than    2

or

Group 2   Block Styles  Has style          outline

shows the control on a grid layout with more than two images, or on any block using the outline style.

Add a rule to the current group with the and button. Add a whole new group with Add Rule Group.

Matching a style or a class

Has class matches a whole class name, not a fragment. A rule of Has class and card passes for card wide and fails for card-wide. Use Contains when you want a fragment.

Block Styles stores the style's name and matches the class Gutenberg generates from it. A variation named outline is stored as outline and matched against is-style-outline, so you pick the name from the dropdown and never type the class yourself.

A block that has never had a class or a style applied has no className attribute at all, and a rule against it is skipped rather than passed or failed.

What it does not do

Conditional Logic is an editor feature and nothing more. It decides whether a control is drawn in the inspector or in the block body. It does not touch the stored value and it does not touch the rendered block.

Three consequences follow, and all three surprise people:

  • A hidden control keeps its value. Hide a control after someone filled it in and the value is still on the block, still passed to your block code, and still printed on the front end.
  • Your template has to repeat the condition. If the output should disappear along with the control, guard it in Handlebars with {{#if}} or in PHP with an if of your own.
  • A required control that is hidden still blocks saving. The save lock checks every control on the block without consulting its rules, so a required control hidden by conditional logic locks the post with no visible field to fix. Do not mark a conditional control as required.

Where the rules are stored

The rules live on the control itself, under conditional_logic, as an array of groups where each group is an array of rules. Exporting a block carries them along.

Block JSON
"control_a1b2c3": {
  "type": "number",
  "name": "columns",
  "label": "Columns",
  "placement": "inspector",
  "conditional_logic": [
    [
      { "control": "layout", "operator": "==", "value": "grid" },
      { "control": "images", "operator": ">", "value": "2" }
    ],
    [
      { "control": "__BLOCK_STYLE__", "operator": "==class", "value": "outline" }
    ]
  ]
}

value is always a string, even for the numeric comparisons, and it is absent on a rule using one of the empty operators. __BLOCK_STYLE__ is how Block Styles is stored; CSS Class Name is stored as className.

A rule that targets a Repeater child from outside the Repeater reads the first row only. Rules on controls inside the Repeater are evaluated per row, so each row shows and hides its own controls independently.

Was this article helpful?

Copyright © 2026 Lazy Blocks.