$base_control_key . '_color',
'label' => esc_html__( 'Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
"shape_divider_$side!" => '',
"{{WRAPPER}} > .elementor-shape-$side .elementor-shape-fill" => 'fill: {{UNIT}};',
$this->add_responsive_control(
$base_control_key . '_width',
'label' => esc_html__( 'Width', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ '%', 'vw', 'custom' ],
"shape_divider_$side" => array_keys( Shapes::filter_shapes( 'height_only', Shapes::FILTER_EXCLUDE ) ),
"{{WRAPPER}} > .elementor-shape-$side svg" => 'width: calc({{SIZE}}{{UNIT}} + 1.3px)',
$this->add_responsive_control(
$base_control_key . '_height',
'label' => esc_html__( 'Height', 'elementor' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
"shape_divider_$side!" => '',
"{{WRAPPER}} > .elementor-shape-$side svg" => 'height: {{SIZE}}{{UNIT}};',
$base_control_key . '_flip',
'label' => esc_html__( 'Flip', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
"shape_divider_$side" => array_keys( Shapes::filter_shapes( 'has_flip' ) ),
"{{WRAPPER}} > .elementor-shape-$side svg" => 'transform: translateX(-50%) rotateY(180deg)',
$base_control_key . '_negative',
'label' => esc_html__( 'Invert', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
'frontend_available' => true,
"shape_divider_$side" => array_keys( Shapes::filter_shapes( 'has_negative' ) ),
$base_control_key . '_above_content',
'label' => esc_html__( 'Bring to Front', 'elementor' ),
'type' => Controls_Manager::SWITCHER,
"{{WRAPPER}} > .elementor-shape-$side" => 'z-index: 2; pointer-events: none',
"shape_divider_$side!" => '',
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
$this->start_controls_section(
'label' => esc_html__( 'Typography', 'elementor' ),
'tab' => Controls_Manager::TAB_STYLE,
'label' => esc_html__( 'Heading Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'{{WRAPPER}} .elementor-heading-title' => 'color: {{VALUE}};',
'label' => esc_html__( 'Text Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'{{WRAPPER}}' => 'color: {{VALUE}};',
'label' => esc_html__( 'Link Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'{{WRAPPER}} a' => 'color: {{VALUE}};',
'label' => esc_html__( 'Link Hover Color', 'elementor' ),
'type' => Controls_Manager::COLOR,
'{{WRAPPER}} a:hover' => 'color: {{VALUE}};',
$this->add_responsive_control(
'label' => esc_html__( 'Text Align', 'elementor' ),
'type' => Controls_Manager::CHOOSE,
'title' => esc_html__( 'Start', 'elementor' ),
'icon' => 'eicon-text-align-left',
'title' => esc_html__( 'Center', 'elementor' ),
'icon' => 'eicon-text-align-center',
'title' => esc_html__( 'End', 'elementor' ),
'icon' => 'eicon-text-align-right',
'title' => esc_html__( 'Justified', 'elementor' ),
'icon' => 'eicon-text-align-justify',
'classes' => 'elementor-control-start-end',
'selectors_dictionary' => [
'left' => is_rtl() ? 'end' : 'start',
'right' => is_rtl() ? 'start' : 'end',
'{{WRAPPER}} > .elementor-container' => 'text-align: {{VALUE}};',
$this->end_controls_section();
$this->start_controls_section(
'label' => esc_html__( 'Advanced', 'elementor' ),
'tab' => Controls_Manager::TAB_ADVANCED,
$this->add_responsive_control(
'label' => esc_html__( 'Margin', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'allowed_dimensions' => 'vertical',
'{{WRAPPER}}' => 'margin-top: {{TOP}}{{UNIT}}; margin-bottom: {{BOTTOM}}{{UNIT}};',
$this->add_responsive_control(
'label' => esc_html__( 'Padding', 'elementor' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'{{WRAPPER}}' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
$this->add_responsive_control(
'label' => esc_html__( 'Z-Index', 'elementor' ),
'type' => Controls_Manager::NUMBER,
'{{WRAPPER}}' => 'z-index: {{VALUE}};',
'label' => esc_html__( 'CSS ID', 'elementor' ),
'type' => Controls_Manager::TEXT,
'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
'style_transfer' => false,
'classes' => 'elementor-control-direction-ltr',
'label' => esc_html__( 'CSS Classes', 'elementor' ),
'type' => Controls_Manager::TEXT,
'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
'classes' => 'elementor-control-direction-ltr',
Plugin::$instance->controls_manager->add_display_conditions_controls( $this );
$this->end_controls_section();
$this->start_controls_section(
'label' => esc_html__( 'Motion Effects', 'elementor' ),
'tab' => Controls_Manager::TAB_ADVANCED,
Plugin::$instance->controls_manager->add_motion_effects_promotion_control( $this );
$this->add_responsive_control(
'label' => esc_html__( 'Entrance Animation', 'elementor' ),
'type' => Controls_Manager::ANIMATION,
'frontend_available' => true,
'label' => esc_html__( 'Animation Duration', 'elementor' ),
'type' => Controls_Manager::SELECT,
'slow' => esc_html__( 'Slow', 'elementor' ),
'' => esc_html__( 'Normal', 'elementor' ),
'fast' => esc_html__( 'Fast', 'elementor' ),
'prefix_class' => 'animated-',
'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
'type' => Controls_Manager::NUMBER,
'frontend_available' => true,
$this->end_controls_section();
$this->start_controls_section(
'label' => esc_html__( 'Responsive', 'elementor' ),
'tab' => Controls_Manager::TAB_ADVANCED,
// The controls should be displayed from largest to smallest breakpoint, so we reverse the array.
$active_breakpoints = array_reverse( Plugin::$instance->breakpoints->get_active_breakpoints() );
foreach ( $active_breakpoints as $breakpoint_key => $breakpoint ) {
'reverse_order_' . $breakpoint_key,
'label' => esc_html__( 'Reverse Columns', 'elementor' ) . ' (' . $breakpoint->get_label() . ')',
'type' => Controls_Manager::SWITCHER,
'prefix_class' => 'elementor-',
'return_value' => 'reverse-' . $breakpoint_key,
'label' => esc_html__( 'Visibility', 'elementor' ),
'type' => Controls_Manager::HEADING,
'responsive_description',
/* translators: 1: Link open tag, 2: Link close tag. */
esc_html__( 'Responsive visibility will take effect only on %1$s preview mode %2$s or live page, and not while editing in Elementor.', 'elementor' ),
'<a href="javascript: $e.run( \'panel/close\' )">',
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
$this->add_hidden_device_controls();
$this->end_controls_section();
Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
Plugin::$instance->controls_manager->add_custom_css_controls( $this );
* Render section output in the editor.
* Used to generate the live preview, using a Backbone JavaScript template.
protected function content_template() {
if ( settings.background_video_link ) {
let videoAttributes = 'autoplay muted playsinline';
if ( ! settings.background_play_once ) {
videoAttributes += ' loop';
'background-video-container',
'class': 'elementor-background-video-container',
if ( ! settings.background_play_on_mobile ) {
view.addRenderAttribute( 'background-video-container', 'class', 'elementor-hidden-mobile' );
<div {{{ view.getRenderAttributeString( 'background-video-container' ) }}}>
<div class="elementor-background-video-embed" role="presentation"></div>
<video class="elementor-background-video-hosted" role="presentation" {{ videoAttributes }}></video>
<div class="elementor-background-overlay"></div>
<div class="elementor-shape elementor-shape-top" aria-hidden="true"></div>
<div class="elementor-shape elementor-shape-bottom" aria-hidden="true"></div>
<div class="elementor-container elementor-column-gap-{{ settings.gap }}"></div>
* Before section rendering.
* Used to add stuff before the section element.
public function before_render() {
$settings = $this->get_settings_for_display();
// PHPCS - the method get_html_tag is safe.
echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?> <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
if ( 'video' === $settings['background_background'] ) :
if ( $settings['background_video_link'] ) :
$video_properties = Embed::get_video_properties( $settings['background_video_link'] );
$this->add_render_attribute(
'background-video-container',
'class' => 'elementor-background-video-container',
if ( ! $settings['background_play_on_mobile'] ) {
$this->add_render_attribute( 'background-video-container', 'class', 'elementor-hidden-mobile' );
<div <?php $this->print_render_attribute_string( 'background-video-container' ); ?>>
<?php if ( $video_properties ) : ?>
<div class="elementor-background-video-embed" role="presentation"></div>