Element API Reference

This is a deeply technical summary of what is offered by our Element API.

  1. Element Definitions
  2. Defining Values
  3. Individual Controls
  4. Composing Controls
  5. Control Conditions
  6. Style Templates
  7. Rendering
  8. FAQ
  9. Summary

Element Definitions

Elements are registered with this function:

function cs_register_element( $type, $options )
  • $type must be a unique element name. Please use a prefix to avoid naming collisions. e.g. my-plugin-my-element
  • $options provides all the details for our definition. It should be an array with the keys notated in Base Options below.

Base Options

titlestringLocalized title to display in the library and when inspecting the element
valuesarraySee Defining Values below.
builderfunctionFunction update the definition when the builder loads. This offers better performance with large control lists because they don't need to be populated on the front end.
stylefunctionFunction that returns a string style template.
decoratorfunctionFunction that updates the data before the render function is run. Useful to inject additional attributes.
renderfunctionFunction that accepts a single argument containing all the element data. Should return a string with the element markup
optionsarraySee Element Definition Options below.
iconstringInline SVG as a string.
activeboolSet to false if the element will not be able to render correctly. For example, if the element requires WooCommerce you can pass class_exists( 'WC_API' ).

Builder Options

These are all optional, but you'll want to provide some combination or the Inspector will be empty. Any of these keys can be added top level, but we recommend returning an array including them from the builder callback function. It is most likely that your builder callback will return the result of the cs_compose_controls function which provides an array in the shape described below. See Composing Controls

control_navarrayAssociative array where keys describe the control nav item, and the value is a localized title to display in the Inspector navigation
controlsarrayAn array of top level controls. Each of these should be associated with the control navigation using a group parameter. See Controls below.
controls_std_contentarrayTop level controls to show under the Content navigation menu item when Advanced Mode is turned off.
controls_std_design_setuparrayTop level controls to show under the Design navigation menu item when Advanced Mode is turned off.
controls_std_design_colorsarrayTop level controls to show under the Colors navigation menu item when Advanced Mode is turned off.

Sample Control Nav

array( 'main_group' => __( 'Group', 'your-text-domain' ), 'main_group:setup' => __( 'Setup', 'your-text-domain' ), 'main_group:design' => __( 'Design', 'your-text-domain' ) )

Element Definition Options

alt_breadcrumbstringProvide an alternate localized string to show in the Inspector navigation breadcrumbs. Useful for elements with longer names.
label_keystringSet to the key of one of your element's values. It will use that value as the label shown in the observer, and when double clicking to rename the element.
childboolSet to true to indicate this element will be rendered as a child of another element.
librarybool|arraySet to false to prevent this element from appearing in the Element Library. Set to array( 'content' ) and the element will only show in the Content builder and Global Blocks builder (not Pro Headers or Footers).
valid_childrenarrayAn array of strings containing the names of elements that can be placed as a direct child of this element. Set as array( '*' ) to accept any child similar to a Column. This does not enable drag/drop.
index_labelsboolSet to true to make the labels have numeric indexes when they are created. e.g. "Section 1", "Section 2"
empty_placeholderboolSet to false to disable the placeholder style when this element doesn't have any content.
default_childrenarrayProvide an array of elements that should automatically be created as children when this element is created.
add_new_elementarrayProvide the data of an element that will be created when you click "Add New" in this element's sortable control.
inlinearrayPass an associative array to enable inline editing. See Inline Editing below
fallback_contentstringIf the element does not have any children, this content will be used instead for the front end. Most notably used to prevent empty Columns from collapsing.
empty_preview_min_heightintIf an element has zero height, it will show as an empty placeholder. You can set this to a larger number to invoke the placeholder even if your element has height. This is useful for elements with base markup that is a few pixels tall, but still empty.
is_draggableboolSet to false to prevent users from lifting this element in the preview.
cacheboolSet to false to prevent the render system from caching markup. Useful for elements that integrate with 3rd party APIs
render_childrenboolSet to true to instruct the rendering system to render this element's children with the parent markup. This has lower performance but is useful for cases like the Map where Markers depend on the parent element.

Inline Editing

Here's an example of how to configure inline editing taken from the Tabs element.

'inline' => array( 'tab_label_content' => array( 'selector' => '.x-tabs-list button span' ), 'tab_content' => array( 'selector' => '.x-tabs-panel' ) )

The selector indicates the double click target. When the user starts editing, it will update the value with the associated key (tab_label_content). You can set the selector to root to make the base element the double click target.

Additional Definition Functions

function cs_unregister_element( $name )

Can be used to unregister an element originally registered under $name.

function cs_get_element( $name )

Retrieve the instance of an element's definition originally registered under $name

Defining Values

Every element needs values. These store data that will be customized later in the Element's controls.

Single values.

function cs_value( $default = null, $designation = 'all', $protected = false )

Each value has a $default which is the initial value used when an element is created.

The $designation determines how the system will render this value.

  • markup` - When this value changes it makes a HTTP request to the server with the updated attributes and fetches new markup for the builder preview. This is the most expensive in terms of performance, but most versatile as it invokes your custom PHP code.
  • attr - When this value changes it updates the value in the DOM immediately.
  • style - We'll cover this later on, but our builders allow you to provide a style template to output generated CSS. When a value with this designation changes, it causes the generated CSS to recalculate.
  • all - When this value changes it cause the element to fetch new markup from the server and renders the generated CSS again.

When $protected is set to true it flags the variable as "content". This means it will not be overridden by default when pasting element styles or applying a preset.


'values' => array( 'my_element_content' => cs_value( 'Initial Text', 'markup', true ) 'my_element_attribute' => cs_value( false, 'attr' ), 'my_element_feature_enabled' => cs_value( false ), // uses 'all' designation 'my_element_margin' => cs_value( '0em', 'style' ) )

Defining Reusable Values

function cs_define_values( $key, $values )

This function is useful if you're creating a suite of elements that will share values. Call this before you register your elements to define values that can be reused later. The $key is a name to use when you want to recall your values with cs_values or cs_compose_values. Set $values to an associative array that assigns keys to the result of cs_value calls.


cs_define_values( 'my-feature', array( 'my_feature_enabled' => cs_value( false ), // uses 'all' designation 'my_feature_margin' => cs_value( '0em', 'style' ), ) );

Composing Values

function cs_compose_values() // accepts unlimited arguments

The cs_compose_values function accepts unlimited arguments. Each can be a string or an array. If you pass a string, the function will retrieve the values stored via cs_define_values under the given key. If passed an array, it will merge those values into the list. This function will let you create elements that tap into predefined functionality.


'values' => cs_compose_values( 'my_element_content' => cs_value( 'Initial Text', 'markup', true ), 'my-feature', // Defined in the previous example 'omega' // Defined natively to power the Customize controls )

Prefixing Defined Values

function cs_values( $values, $key_prefix = '' )

By passing a string as the first argument, this function allows you to fetch values stored with cs_define_values. An array as the first argument assumes you are passing an associative array of values.

The $key_prefix argument is used to prefix every value in the list. The example below shows how you can retrieve the values of the native text element and prefix it for your element. The native card element is a good example of composing multiple values (controls as well).


cs_values( 'text-headline', 'my_element_text' )

Individual Controls

In this section we'll cover all the different control types, the available options, and the helper functions you can use to work with them.

Control Parameters

A control is an array that contains the following keys

keystringThe name of a value that will be mapped to this control. Not required if you use keys instead.
keysarraySome control types allow mapping multiple values.
typestringType of control. Use the Control Reference below.
groupstringRequired for top level controls. Set the control navigation group under which this control should appear.
labelstringLocalized string to describe this control. Allows templating. e.g. "{{prefix}} Margin" will populate prefix from what is passed into label_vars.
label_varsarrayKey value pairs to populate template strings in the Label. This technique is useful when amending controls for standard mode or when creating your own partials.
label_prefixstringShorthand to set label_prefix in label_vars
conditionarrayA single condition to determine if this control should be visible.
conditionsarrayMultiple conditions to determine if this control should be visible. Will supersede condition.
optionsarrayArray of options that correspond with the control type.

Control Reference

  • Controls without keys only output a single value
  • Keys with |value indicate which one is used when passing a singular key
  • Keys with ? are optional.
  • Angle brackets indicate you must use one of the enclosed strings. e.g. for <row|column> you must provide row or column.
  • Each line in Options is an individual option that can be mapped for this control. If an option references another control, it means that you can pass an array of the options for the named control.
Alignalignicon_direction : string <row|column>
axis : string <main|cross>
Aspect Ratioaspect-ratiowidth
placeholder : str "16:9"
always_linked : bool
width : [unit-slider options]
color : [color options]
Border Radiusborder-radius[see dimensions]
Box Shadowbox-shadowdimensions
x_offset : [slider]
y_offset : [slider]
blur : [slider]
spread : [unit-input]
color : [color]
Checkbox Listcheckbox-listVariable1list : [{ key : str, label : str, full : bool }]
Choose (Multi)choose-multichoices : [{ value : str, label : str, icon : str }]
delimiter : str
Choose (Single)choose-singlechoices : [{ value : str, label : str, icon : str }]
off_value : str
Code Editorcode-editorplaceholder : str
mode : <css|js>
button_label : str
header_label : str
disable_input_preview : bool
output_format : str
label : str
alt_label : str
dynamic : bool
Date / Timedate-time
Dimensionsdimensionslabels : { top : str, right : str, bottom : str, left : str }
top : [slider]
right : [slider]
bottom : [slider]
left : [slider]
Flex Layoutflexboxlayout
allow_reverse : bool
Font Familyfont-family
Font Stylefont-style
Font Weightfont-weightvalue
Icon Pickericonvalue
label : str
alt_label : str
alt_text_placeholder : str
Image Sourceimage-source
Marginmarginsee dimensions
Numbernumberplaceholder : str
monospace : bool
Paddingpaddingsee dimensions
Ratioratioplaceholder : str
Selectselectchoices : [{ value : str, label : str }]
SortablesortableNo keys6element: element-name
add_label: str
capacity : int
floor : int
Texttextplaceholder : str
monospace : bool
Text Aligntext-align
Text Decorationtext-decoration
Text Editortext-editor
Text Formattext-formatfont_family
Text Shadowtext-shadowdimensions|value
Text Styletext-stylefont_style?
color : [color]
Text Transformtext-transform
Textareatextareaplaceholder : str
monospace : bool
Unitunitunit_mode : str <distance|angle>
available_units : [ values... ]
valid_keywords : [ values... ]
disabled : bool
fallback_value : str
Unit Sliderunit-sliderunit_mode : str <distance|angle>
available_units : [ values... ]
valid_keywords : [ values... ]
disabled : bool
fallback_value : str
ranges : { px : { min : 0, max : 100, step : 1 }
min : number
max : number
step : number
Widget Areawidget-area
NameIdentifier2nd Level3rd LevelKeysOptions


  1. Checkbox List - These keys are variable and depend on the items you map.
  2. Font Weight - This needs a reference to font_family but it doesn't directly modify the value.
  3. Group - The group control doesn't accept keys or options. A top level controls property will let you pass a list of controls to display inside the group.
  4. Image - width and height are optional but you must declare both or neither
  5. Image - is_retina can only be used if width and height are mapped.
  6. Sortable - See sortable section below. Keys are not used

Example Groups

You can add a group as child control of a group to create a third level. These controls don't support labels and you're even more restricted at the types of controls that can be mapped.

Group Example (2nd Level)

array( 'type' => 'group', 'label' => __( 'Feature Controls', 'text-domain' ), 'controls' => array( array( 'key' => 'element_content', 'type' => 'text', 'label' => __( 'Content', 'text-domain' ) ), array( 'key' => 'element_color', 'type' => 'color', 'label' => __( 'Color', 'text-domain' ) ) ) )

Group Example (3rd Level)

array( 'type' => 'group', 'label' => __( 'Feature Controls', 'text-domain' ), 'controls' => array( array( 'type' => 'group', 'label' => __( 'Before / After', 'text-domain' ), 'controls' => array( array( 'key' => 'element_content_before', 'type' => 'text', ), array( 'key' => 'element_content_after', 'type' => 'text', ), ) ), array( 'key' => 'element_color', 'type' => 'color', 'label' => __( 'Color', 'text-domain' ) ) ) )

Example Checkbox List

Here's an example of the checkbox list control. The full option tells the checkbox to span the full width of the control area instead of being half size.

array( 'keys' => array( 'checkbox_a' => 'some_element_value', 'checkbox_b' => 'another_element_value', 'checkbox_c' => 'one_more_element_value', ), 'type' => 'checkbox-list', 'options' => array( 'list' => array( array( 'key' => 'checkbox_a', 'label' => __( 'Enable A', '__x__' ) ), array( 'key' => 'checkbox_b', 'label' => __( 'Enable B', '__x__' ) ), array( 'key' => 'checkbox_c', 'label' => __( 'Enable C', '__x__' ), 'full' => true ), ), ), )

Composing Controls

function cs_compose_controls() // unlimited arguments

Call cs_compose_controls with unlimited arguments. Each argument must be a string associated with a registered partial, or an array that adheres to the Builder Options parameters above. The function will combine multiple sets of controls into a single output used in the builder. This allows for leveraging partials and organizing the standard controls that should only appear when Advanced Mode is turned off.

Registering a Control Partial

function cs_register_control_partial( $name, $function )

To create your own control partials, call cs_register_control_partial with $name set to the key you will eventually reference in calls to cs_compose_controls or cs_partial_controls. Set $function to a function that will return valid Builder Options.


function my_plugin_control_partial( $settings = array() ) { $group = = isset( $settings['group'] ) ? $settings['group'] : "feature" $group_title = isset( $settings['group_title'] ) ? $settings['group_title'] : __( 'Feature', 'my-plugin' ); $group_setup = "$group:setup"; $group_design = "$group:setup"; return array( 'control_nav' => array( $group => $group_title, $group_setup => __( 'Setup', 'my-plugin' ), $group_design => __( 'Design', 'my-plugin' ), ), 'controls' => array( /* */), ); } cs_register_control_partial( 'my-plugin-control-partial', 'my_plugin_control_partial' );

Using Control Partials

function cs_partial_controls( $name, $settings = array() )

Call cs_partial_controls and pass the result as an argument of cs_compos_controls to add the partial registered as $name to your control list. The $settings array is passed to the partial to allow for customization of the resulting controls.


cs_compose_controls( cs_partial_controls( 'my-plugin-control-partial', array( 'group' => 'element-group', 'group_title' => __( 'Element', 'text-domain' ) ) ), cs_partial_controls( 'omega' ) )

Leveraging Common Control Types

function cs_control( $type, $key_prefix = '', $control = array() )

The cs_control function returns an array describing various common control types. It automatically maps one or more keys for you, and honors $key_prefix in front of those keys. Use the table below to see what is allowed for the $type argument. You can set Control parameters like group, condition(s), and options by passing them through $control. Settings can also be passed into $control to adjust the output.

border-radiusBorder Radius{key_prefix}_border_radiusNone
alt_color - Set to true to map the alt color key and make the control appear.
box-shadowBox Shadow{key_prefix}_box_shadow_dimensions
alt_color - Set to true to map the alt color key and make the control appear.
no_self - Set to true to exclude the Self Flex control and key.
layout_pre - An additional key prefix used on layout flex properties. If omitted the $key_prefix will be used.
text-shadowText Shadow{key_prefix}_text_shadow_dimensions
alt_color - Set to true to map the alt color key and make the control appear.
text-formatText Format{key_prefix}_font_family
alt_color - Set to true to map the alt color key and make the control appear.
no_font_family, no_font_weight, no_font_size, no_line_height, no_letter_spacing, no_font_style, no_text_align, no_text_decoration, no_text_transform, no_text_color - Set any of these to false to prevent the respective key and control from being mapped.
$typeNameMapped KeysSettings

All of these include {{prefix}} in their label, so you can pass label_prefix as a parameter of $control to further describe how the control should be used.

Amending a Control used multiple times

function cs_amend_control( $control, $update )

Use cs_amend_control to make an adjustment to a control that you've defined once, but need to use somewhere an additional time (useful for standard controls) with a slight adjustment. The $control argument is the original, and $update is the changes to merge in. This is different from array_merge because it handles the additional layer of updating the control's options parameter.


$base_control = array( /* ...other control parameters... */ 'label' => __( 'My Control', 'your-text-domain' ) ); $updated_control = cs_amend_control( $base_control, array( 'label' => __( 'Different Label', 'your-text-domain' ) ) );

Remembering Commonly Used Options

function cs_remember( $key, $value )

This can only be used inside a builder callback, but it allows you to store commonly used bits of data. For example, if you have a list of localized options that you may need to add on multiple elements you could store it like this.


cs_remember( 'my-element-choices', array( array( 'value' => 'one', 'label' => __( 'One', 'your-text-domain' ) ), array( 'value' => 'two', 'label' => __( 'Two', 'your-text-domain' ) ), array( 'value' => 'three', 'label' => __( 'Three', 'your-text-domain' ) ), array( 'value' => 'four', 'label' => __( 'Four', 'your-text-domain' ) ), ) );

Recalling Commonly Used Options

function cs_recall( $key )

Building off the previous example, we can recall the stored options as well. Remember it can only be used inside of a builder callback.


// in your list of controls array( 'key' => 'my_element_value', 'type' => 'select', 'label' => __( 'Select Something', 'your-text-domain'), 'options' => array( 'choices' => cs_recall( 'my-element-choices' ) ) )

Control Conditions

When mapping a control, you can set condition or conditions to determine when a control should be visible. This is primarily used to reveal additional controls after they are enabled. Each condition has the following properties:

  • key - String identifier of the value we are observing
  • op - The type of operator we are using for this comparison. See operator table below
  • value - The value to check our condition against.
  • or - Set to trueto enable OR logic for this condition. See Using OR Logic below.
==Checks if what is currently held under key is equal to our condition's value.any
=!Checks if what is currently held under key is not equal to our condition's value.
INChecks if what is currently held under key is present in the array of values set as our condition's value
NOT INChecks if what is currently held under key is not present in the array of values set as our condition's value
EMPTYChecks if the what is currently held under key is considered an empty property1 for the purposes of CSS output.
NOT EMPTYChecks if the what is currently held under key is not considered an empty property1 for the purposes of CSS output.
OperatorDescriptionValue TypeDescription
  1. Blank strings, CSS values that are zero with any unit, and the keyword none are considered empty.


The equality operator is the most commonly used and therefore is offered as a shorthand. The following two conditions are identical.

array( 'key' => 'my_value', 'value' => 'Should be this', 'op' => '==' ) array( 'my_value' => 'Should be this' )

Using OR Logic

By default multiple conditions are applied with AND logic. This means they must all be true for the control to be visible. You can override this on individual controls by setting the or parameter to true. When enabled, the condition will be automatically be considered true if condition immediately following it is true. The following example is considered true when feature_enabled is true AND either some_value is a value in the list (one, two) or another_value is ten.


[ 'conditions' => [ [ 'feature_enabled' => true ]. [ 'key' => 'some_value', 'op' => 'IN', 'value' => [ 'one', 'two' ] 'or' => true ], [ 'key' => 'another_value', 'op' => '!=', 'value' => 'ten' ], ] ]

Style Templates

When you set style to a function when registering your Element definition you will need to return a string style template. This uses a CSS like syntax to create dynamic styles based on the state of your element's values.


You can use variables in your selectors and property values. Variables can not be used as part of a property name. The available variables correspond to values that you have registered with designations style or all. An additional variable to reference the current element's class name is available as &. The following example shows styling a few properties. Each of the property value variables is expected to mapped as one of your element values.


& { margin: $my_element_base_margin; padding: get(my_element_base_padding); //Will also grab current breakpoint value } & .thing { margin: $my_element_thing_margin; padding: $my_element_thing_padding; }


Often you'll want to exclude styles unless a criteria is met. This is possible with @if. When using @if the contained styles will appear if the expression evaluates to true.

& { @if $feature_enabled == 'on' { margin: $my_element_feature_margin; padding: $my_element_feature_padding; @if not empty($feature_min_width) { min-width: $feature_min_width; } } }

Learn more about Themeco Stylesheets here.

PHP in a style template

If you're browsing our partial templates, you'll notice that they are PHP functions that use object buffering. Remember that this PHP does not actually have any element data. We're constructing a template that contains rules applied to elements later. Using PHP is helpful to setup things like key prefixes and make calls to cs_get_partial_style.


function cs_get_partial_style( $name, $settings = array() )

This function is used to get the string of a predefined style template partial registered under $name. The $settings parameter is used to instruct the partial on various adjustments that can be made.

Creating a Style Partial

This is accomplished via the cs_get_partial_style_$name hook.


function my_style_partial( $settings = array() ) { return ''; } add_filter( 'cs_get_partial_style_my_style_partial', 'my_style_partial' );


The function you assign to the render parameter accepts $data which includes the element values and should return a string.


function my_element_render( $data ) { extract( $data ); $atts = cs_atts( array( 'class' => cs_attr_class( $mod_id, 'my-element' ), 'data-my-attribute' => $custom_attribute ) ); ob_start(); ?> <div <?php echo $atts; ?>> <?php echo $data['content']; ?> </div> <?php return ob_get_clean(); }

Rendering View Partials

function cs_get_partial_view( $name, $data = array() )

Within your render function, call cs_get_partial_view with the $name of a partial you wish to render and a string will be returned with that partial's markup. The $data array is used to pass through your element's data (the $data argument of the render function). The example below is the native Button element.


function x_element_render_button( $data ) { return cs_get_partial_view( 'anchor', $data ); }

Preparing Partial Data

Extracting and Prefixing Data

Sometimes you'll need to modify the data passed into the partial. For example, if you want to use a partial multiple times, or need to rename some of the keys, you can do that with cs_extract.

function cs_extract( $data, $find = array() )

Pass in the $data from your render function (or manipulate it first with calls so cs_without and/or array_merge) and specific what values you want to extract in the $find array. Here's an example of using cs_extract to retrieve values prefixed with headline_one/headline_two and rename those keys to text for the purposes of rendering the partial. Notice how the cs_extract calls work in parallel with calls to cs_values .


cs_register_element( array( 'values' => cs_compose_values( array( // other values ), cs_values( 'text-headline', 'headline_one' ), cs_values( 'text-headline', 'headline_two' ), ), 'builder' => 'my_element_builder', // not includes in this example 'render' => 'my_element_render' ) ); function my_element_render( $data ) { $headline_one_markup = cs_get_partial_view( 'text', cs_extract( $data, array( 'headline_one' => 'text' ) ) ); $headline_two_markup = cs_get_partial_view( 'text', cs_extract( $data, array( 'headline_two' => 'text' ) ) ); // ...continue rendering. should return a string. }

Omitting Data

function cs_without( $data, $keys )

This function simply returns $data after omitting key/value pairs found in the $keys array.


// Remove some data specific to the top level element. $cleaned = cs_without( $data, array( 'mod_id', 'id', 'class', 'style' ) )

Deferred View Partials

function cs_defer_partial( $name, $data = array(), $priority = 100 )

Sometimes you want to output partial markup at the end of the site markup instead of inline. This is useful for modal and off-canvas elements. You can call cs_defer_partial with the $name of your registered partial and it will internally utilize a function called x_set_view which caches HTML and outputs it at a specific hook. In this case, it will be output at the x_before_site_end hook. This is a few levels above the closing </body> tag, and where X and Pro output all deferred markup. When using Cornerstone with other themes this will be equivalent to the wp_footer hook.

The $data argument is identical the cs_get_partial_view function. You can adjust the $priority used when attaching to the x_before_site_end hook. The following example is from the Content Area Modal element with some comments added.


function x_element_render_content_area_modal( $data ) { // Add some ARIA attributes (See ARIA Attributes section later in this article) $data = array_merge( $data, cs_make_aria_atts( 'toggle_anchor', array( 'controls' => 'modal', 'haspopup' => 'true', 'expanded' => 'false', 'label' => __( 'Toggle Modal Content', '__x__' ), ), $data['id'], $data['mod_id'] ) ); // Defer output of the modal to the site footer. cs_defer_partial( 'modal', cs_extract( $data, array( 'modal' => '' ) ) ); // Output the toggle inline using an anchor partial return cs_get_partial_view( 'anchor', cs_extract( $data, array( 'toggle_anchor' => 'anchor', 'toggle' => '' ) ) ); }

Creating a View Partial

This is accomplished via the cs_get_partial_view_$name hook.


function my_view_partial( $data = array() ) { return ''; } add_filter( 'cs_get_partial_view_my_view_partial', 'my_view_partial' );



function cs_atts( $atts, $echo = false )

Takes an associative array ($atts) and combines them into single escaped string that can be output in an HTML tag.


$atts = cs_atts( 'id' => 'my-id', 'style' => 'color: white;' ); $html = "<div $atts>Content</div";

Class Output

function cs_attr_class() // unlimited string arguments

Combines multiple strings into a single CSS class name. Pass as many arguments as you like. They can be strings or arrays of strings. It will automatically remove any values that are empty.


$feature_a = ''; $feature_b = array( '', 'feature-b' ); $classes = cs_attr_class( $mod_id, 'my-element', $feature_a, $feature_b ); // $classes === "e123-1 my-element feature-b"

ARIA Attributes

Some of the native view partials look for additional data to populate the aria attributes. We can attach this data with the cs_make_aria_atts function.


function my_element_with_toggle_render( $data ) { $data = array_merge( $data, cs_make_aria_atts( 'toggle_anchor', array( 'controls' => 'dropdown', 'haspopup' => 'true', 'expanded' => 'false', 'label' => __( 'Toggle Dropdown Content', '__x__' ), ), $data['id'], $data['mod_id'] ) ); // continue rendering element }

The best way to understand how this function is used would be to look at the code for the Content Area Dropdown, Content Area Modal, and Content Area Off Canvas elements.


How can I make an element like [native element]?

Feel free to copy and paste from our native elements liberally! The native partials are not a documented part of the public API, but you're welcome to re-use anything you find in our elements.

What is the _region value?

This is used internally to track which "region" the element resides in. Here are the regions and what they mean

  • top, left, right, bottom - Element is a bar or descendant of one in the respective region of a Pro Header.
  • footer - Element is a bar or descendant of one in a Pro Footer
  • content - Element is in the main area of content created in the Content Builder of Global Blocks

Referencing this value can be useful if you want to slightly alter the element behavior based on the output location.

How can I make my render function behave differently in the preview area?

$is_preview = did_action( 'cs_element_rendering' );

This is useful in render functions if you want to slightly adjust the behavior for the preview versus the front end.

How can I turn my element into a drag/drop container?

Because this requires additional client side (React Components) code, we do not currently offer a way to define an element as a drag and drop container.


We've taken an in-depth look at all the Element API has to offer, and covered specific options and covered the majority of functionality used in the native elements. When building your own elements, feel free to copy and paste sections of code from the native elements. For more of a step-by-step walkthrough of the Element API, see the API Primer.

See something inaccurate? Let us know