In the last video, we created a basic Elementor custom widget. In this video, we will apply some features to this Elementor custom widget. For example, we will add options for changing the color, and typography.

I am going to keep this video short by only applying some features to this custom Elementor widget. But I do believe, this video is a starting point to proceed further. So, you can build custom Elementor widget from scratch with limitless features.
Before I start, I want you to know, in this Youtube Channel Channel, you will find basic to advanced tutorials on WordPress, Website & Social Media strategies, Web Development, and UI/UX.
Please, consider subscribing to this Youtube Channel if this is something you are into.
Okay, enough talk, let’s start.
Initial plan for this Elementor custom widget
If you did not watch the last video, then please watch it first to understand better.
So, I am starting from the end of the last video. In the last video, we applied a “Content section
” using the control “TAB_CONTENT
”. It became part of the “Content
” tab.

And, in this part, I will apply a “Style section
” using the control “TAB_STYLE
”. It becomes the part of the “Style
” tab. Our all options for Styles will stay under this Style section.

Building the Style section for custom Elementor widget
So, first, we will start with a new control section for style, and end that new control section.
$this->start_controls_section(
'section_style',
[
'label' => esc_html__( 'Style', 'essential-elementor-widget' ),
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]
);
// OUR CODE FOR STYLE OPTIONS WILL BE HERE
$this->end_controls_section();
Options for Title
We will add the three controls.
- Heading option for title
- Title color option
- Title typography option
Heading option for title
Now, within this style section, we will add control for a Heading.
$this->add_control(
'title_options',
[
'label' => esc_html__( 'Title Options', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
]
);
We named it “Title Options
”. It is just to understand that all the Title Styling option is here. The separator “before
” adding a border above this title.
Color option for custom Elementor widget Title
Now, add control for Title color, which we can use to change the color of the title. I am pasting this.
$this->add_control(
'title_color',
[
'label' => esc_html__( 'Color', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#f00',
'selectors' => [
'{{WRAPPER}} h3' => 'color: {{VALUE}}',
],
]
);
For the ID of this field, we name it “title_color
”, and for the human-readable Title, we name it “Color
”.
We put the default color for the title “#F00
” which is red. But of course, you can change the color from the admin side.
The “selectors” key can contain
the values with Array. We can target more than one CSS selector here. Here we have targeted our title tag H3 to bind the CSS. We can target our CSS class instead of H3, that is “card_title
”. And, we will have the same output.
Our widget will add custom CSS rules to the CSS file generated for this page. For example, if we inspect and see, then here is this.

So, our defined rules here only apply to this widget. Because here the “{{WRAPPER}}” prefix ensures only this instance of the widget using this color. And the “{{VALUE}}
” here returns the Value of the color.
So, this line '{{WRAPPER}} h3' => 'color: {{VALUE}}'
, means the CSS output “PARENT_ELEMENTS_CSS_CLASS h3 {color: #f00;}
”. The {{WRAPPER}}
returns the parent element CSS class, and we are targeting the inner element H3.
If we now check this in the dashboard, you see, we can change the color of the title, cool, right?

Typography option for Title
Now, we will add Typography options to the title. Let’s paste this.
$this->add_group_control(
\Elementor\Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} h3',
]
);
So, here we are adding a group control with “add_group_control
” and in the first parameter, we are using the “Group_Control_Typography
”.
With the selector key, we are targeting our H3 with the {{WRAPPER}}
, it means with the parent elements.
So, what this line ‘selector’ => ‘{{WRAPPER}} h3’, returns? Let’s inspect the browser and see the output. We see H3 with parent elements has these CSS rules.

So, now, let’s check this in the dashboard. Let me click on Typography. You see, we can change the “font-size
”, “line-height
”, “letter-spacing
” etc., cool, right?

Options for Elemenor custom widget Description
Let’s move to the Description option. We will add a similar Color and Typography option for this. I am pasting these.
$this->add_control(
'description_options',
[
'label' => esc_html__( 'Description Options', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'description_color',
[
'label' => esc_html__( 'Color', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#f00',
'selectors' => [
'{{WRAPPER}} .card__description' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
\Elementor\Group_Control_Typography::get_type(),
[
'name' => 'description_typography',
'selector' => '{{WRAPPER}} .card__description',
]
);
So, the options we added for the Description field are like the Title field.
Here is the Heading, then the color, and typography. As these are the same, I hope, you don’t need the explanation again. But, of course, if you have some confusion, please comment on the video on YouTube, I will be happy to reply.
If you now check on the dashboard. We see the Description Typography can be changed. Very cool, right?
The whole Elementor custom widget file
So now, all together, our final version of the card-widget.php is as follows.
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Essential_Elementor_Card_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'card';
}
public function get_title() {
return esc_html__( 'Essenial Card', 'essential-elementor-widget' );
}
public function get_icon() {
return 'eicon-header';
}
public function get_custom_help_url() {
return 'https://essentialwebapps.com/category/elementor-tutorial/';
}
public function get_categories() {
return [ 'general' ];
}
public function get_keywords() {
return [ 'card', 'service', 'highlight', 'essential' ];
}
protected function register_controls() {
// our control function code goes here.
$this->start_controls_section(
'content_section',
[
'label' => esc_html__( 'Content', 'essential-elementor-widget' ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'card_title',
[
'label' => esc_html__( 'Card title', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::TEXT,
'label_block' => true,
'placeholder' => esc_html__( 'Your card title here', 'essential-elementor-widget' ),
]
);
$this->add_control(
'card_description',
[
'label' => esc_html__( 'Card Description', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::TEXTAREA,
'label_block' => true,
'placeholder' => esc_html__( 'Your card description here', 'essential-elementor-widget' ),
]
);
$this->end_controls_section();
// style controls
$this->start_controls_section(
'section_style',
[
'label' => esc_html__( 'Style', 'essential-elementor-widget' ),
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'title_options',
[
'label' => esc_html__( 'Title Options', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'title_color',
[
'label' => esc_html__( 'Color', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#f00',
'selectors' => [
'{{WRAPPER}} h3' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
\Elementor\Group_Control_Typography::get_type(),
[
'name' => 'title_typography',
'selector' => '{{WRAPPER}} h3',
]
);
$this->add_control(
'description_options',
[
'label' => esc_html__( 'Description Options', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'description_color',
[
'label' => esc_html__( 'Color', 'essential-elementor-widget' ),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#f00',
'selectors' => [
'{{WRAPPER}} .card__description' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
\Elementor\Group_Control_Typography::get_type(),
[
'name' => 'description_typography',
'selector' => '{{WRAPPER}} .card__description',
]
);
$this->end_controls_section();
}
protected function render() {
// get our input from the widget settings.
$settings = $this->get_settings_for_display();
// get the individual values of the input
$card_title = $settings['card_title'];
$card_description = $settings['card_description'];
?>
<!-- Start rendering the output -->
<div class="card">
<h3 class="card_title"><?php echo $card_title; ?></h3>
<p class= "card__description"><?php echo $card_description; ?></p>
</div>
<!-- End rendering the output -->
<?php
}
}
Along with this, let’s grab the Plugin file code from the first part of the tutorial and you are done.
Now you know, how things work when it comes to applying features to an Elementor custom widget.
Now, it is your time to apply more features to your custom Elementor widget. And, you can do so by checking the available Elementor controls here in this link. I believe you can do it, isn’t it?
I will see you in the next video. Till then take care.

About the Author
Jamal is a WordPress Developer having more than 10 years of experience and is based in Helsinki, Finland. He is doing his 9-5 Developer job but, in his free time, he loves to create tutorials and connect with people.