Elementor Custom Widget
May 7, 2025 · AI Conversations
and the design will be sam , most importantly make it fully responsive and best !
—
### ✅ **Design Overview**:
– Left: Large image (team meeting style)
– Background: Subtle vector/shape behind image (CSS/vector layer)
– Right: Heading + text content (like “OM OSS” and description)
—
### 🔧 **1. Create Elementor Widget in Custom Plugin**
**Plugin Base:**
Create a plugin folder and PHP file `custom-image-content-widget.php`:
<?php
/**
* Plugin Name: Custom Image Content Widget
* Description: Adds a custom Elementor widget for image + vector + content layout.
* Version: 1.0
* Author: Your Name
*/
function register_image_content_widget( $widgets_manager ) {
require_once( __DIR__ . '/widgets/image-content-widget.php' );
$widgets_manager->register( new Elementor_Image_Content_Widget() );
}
add_action( 'elementor/widgets/register', 'register_image_content_widget' );
function custom_widget_styles() {
wp_enqueue_style( 'custom-widget-css', plugin_dir_url( __FILE__ ) . 'widgets/style.css' );
}
add_action( 'wp_enqueue_scripts', 'custom_widget_styles' );
—
### 📁 **widgets/image-content-widget.php**
<?php
class Elementor_Image_Content_Widget extends ElementorWidget_Base {
public function get_name() {
return 'image_content_widget';
}
public function get_title() {
return __('Image Content Widget', 'custom-plugin');
}
public function get_icon() {
return 'eicon-post';
}
public function get_categories() {
return ['general'];
}
protected function _register_controls() {
$this->start_controls_section('content_section', [
'label' => __('Content', 'custom-plugin'),
]);
$this->add_control('main_image', [
'label' => __('Main Image'),
'type' => ElementorControls_Manager::MEDIA,
'default' => ['url' => ElementorUtils::get_placeholder_image_src()],
]);
$this->add_control('background_vector', [
'label' => __('Background Vector (optional)'),
'type' => ElementorControls_Manager::MEDIA,
]);
$this->add_control('heading', [
'label' => __('Heading'),
'type' => ElementorControls_Manager::TEXT,
'default' => __('OM OSS', 'custom-plugin'),
]);
$this->add_control('content', [
'label' => __('Content'),
'type' => ElementorControls_Manager::WYSIWYG,
'default' => __('Your description goes here...', 'custom-plugin'),
]);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
?>
<div class="custom-image-content-widget">
<div class="image-container">
<?php if ($settings['background_vector']['url']) : ?>
<img class="vector-bg" src="<?php echo esc_url($settings['background_vector']['url']); ?>" alt="Vector Background" />
<?php endif; ?>
<img class="main-img" src="<?php echo esc_url($settings['main_image']['url']); ?>" alt="Main Image" />
</div>
<div class="content">
<h2><?php echo esc_html($settings['heading']); ?></h2>
<div class="text"><?php echo $settings['content']; ?></div>
</div>
</div>
<?php
}
}
—
### 📁 **widgets/style.css**
.custom-image-content-widget {
display: flex;
flex-wrap: wrap;
align-items: center;
background: #fff;
padding: 40px 20px;
position: relative;
overflow: hidden;
border-radius: 10px;
box-shadow: 0 5px 30px rgba(0,0,0,0.05);
}
.custom-image-content-widget .image-container {
position: relative;
flex: 1 1 50%;
max-width: 50%;
padding: 20px;
}
.custom-image-content-widget .image-container .vector-bg {
position: absolute;
left: 0;
top: 0;
width: 120%;
height: 120%;
object-fit: contain;
opacity: 0.1;
z-index: 0;
pointer-events: none;
}
.custom-image-content-widget .image-container .main-img {
position: relative;
width: 100%;
border-radius: 10px;
z-index: 1;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.custom-image-content-widget .content {
flex: 1 1 50%;
max-width: 50%;
padding: 20px;
}
.custom-image-content-widget .content h2 {
font-size: 32px;
font-weight: 700;
margin-bottom: 20px;
}
.custom-image-content-widget .content .text {
font-size: 16px;
line-height: 1.8;
color: #444;
}
/* Mobile Responsiveness */
@media (max-width: 767px) {
.custom-image-content-widget {
flex-direction: column;
}
.custom-image-content-widget .image-container,
.custom-image-content-widget .content {
max-width: 100%;
}
}
—
### 🧪 How to Use:
1. Upload this custom plugin.
2. Activate it.
3. In Elementor editor, search for **“Image Content Widget”** under **General**.
4. Insert it and upload:
– Main image
– Vector background (optional)
– Heading
– Text
—
Would you like me to convert this into a downloadable ZIP file for you?
—
### 💡 **Layout Preview (Visual Description)**
#### 📐 **Desktop View:**
--------------------------------------------------------------
| [Vector BG Image] | OM OSS |
| [Main Image on Top] | Vi är ett Sverige-baserat... |
| | På Svea Development... |
| | Från mjukvaruutveckling... |
| | Vi nöjer oss inte... |
--------------------------------------------------------------
– **Left Side**:
A **large, rounded-corner image** of a team meeting, layered **on top of a semi-transparent background vector pattern**.
The image has a soft **box-shadow and rounded edges**.
– **Right Side**:
The heading **“OM OSS”** in bold, followed by a **clean, modern paragraph text block** with excellent line spacing.
– The **layout is 50-50 split** on desktop, with plenty of padding and spacing.
—
### 📱 **Mobile View:**
-------------------------------
| [Main Image] |
| (full width, top section) |
| |
| OM OSS |
| Vi är ett Sverige-baserat... |
| ... |
-------------------------------
– The image and content stack **vertically**.
– The vector remains faint in the background (if provided).
– **Full responsiveness** with padding adjustments and fluid text.
—
### 🎨 **Style Notes:**
– Modern, minimal Swedish aesthetic
– Light shadows and clean white background
– Typography: Bold headings, smooth body text
– Perfect for **agency/consultancy About Us** sections
—
Would you like me to generate a mockup screenshot or provide a zip so you can install and preview it immediately in Elementor?
display: flex
;
flex-direction: column;
align-items: center;
}
.circle-grid img{
transform: rotate(90deg); /* or -90deg if it rotates the wrong way */
transform-origin: center center;
}
.circle-grid{
display: grid
;
grid-template-columns: repeat(3, 1fr);
gap:20px;
}
.circle-icon-main-container {
height: 190px;
}
why its creating issue in responsiveness?
.circle-grid {
display: flex;
flex-direction: column;
align-items: center;
}
...
.circle-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
You're defining `.circle-grid` **twice**, and the **second declaration (`display: grid`) overrides the first one (`display: flex`)**, but you’ve kept properties like `align-items: center` from the `flex` layout, which do **nothing in a CSS grid**.
—
### ✅ **Fix: Consolidate into One Display Type**
If you're going with `grid`, clean it up like this:
.circle-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 20px;
justify-items: center; /* centers content inside grid cells */
}
.circle-grid img {
transform: rotate(90deg);
transform-origin: center center;
}
.circle-icon-main-container {
height: 190px;
}
—
### 📱 Responsive Tip:
Use `auto-fit` + `minmax()` in the grid for responsiveness:
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
This automatically reduces the number of columns based on available width, **making it responsive** on smaller screens.
—
Would you like me to give you a full working example with media queries too?
—
### ✅ **CSS Solution: Prevent H1 from Wrapping Too Early**
.parent-container {
width: 200px; /* your narrow container */
overflow-x: auto; /* allow horizontal scroll if needed */
}
.parent-container h1 {
white-space: nowrap; /* prevent wrapping */
overflow: hidden; /* hide overflow if no scroll */
text-overflow: ellipsis; /* optional: shows '...' if overflowed */
}
—
### 🔁 Optional (to allow full scrollable heading):
If you want the full heading to be visible with horizontal scrolling instead of hiding:
.parent-container {
width: 200px;
overflow-x: auto;
}
.parent-container h1 {
white-space: nowrap;
}
—
### 🧪 Bonus (Fluid layout):
To make sure the H1 behaves fluidly but only wraps **after the entire page width is exhausted**, try:
h1 {
min-width: max-content;
}
—
Would you like this solution adapted for a specific framework like Elementor or Tailwind?
I have used this but its not coming in center now !
—
### ✅ To **center it horizontally**, you can fix it with:
#### 🔹 **Flexbox Parent:**
.parent-container {
display: flex;
justify-content: center;
}
h1 {
min-width: max-content;
}
#### 🔹 Or use **text-align + margin auto** combo:
.parent-container {
text-align: center;
}
h1 {
display: inline-block;
min-width: max-content;
}
> Both will center the long, non-wrapping “ within a smaller-width parent.
—
Would you like it vertically centered too, or just horizontal is fine?
—
### ✅ **Use `transform: translateX(-50%)` with `left: 50%`**
.parent-container {
position: relative;
}
.parent-container h1 {
position: absolute;
left: 50%;
transform: translateX(-50%);
min-width: max-content;
}
### 📌 Explanation:
– `position: absolute` takes the h1 out of flow
– `left: 50%` moves the left edge of the h1 to the center
– `transform: translateX(-50%)` shifts the h1 left by half its width — perfectly centering it
– `min-width: max-content` ensures it won’t wrap
—
### 👀 Bonus (also center vertically):
.parent-container h1 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Let me know if the parent has constraints like padding or height, and I can adapt this further.