Elementor Custom Widget

User
make a widget in elementor where we have option to have this kind of design one big image and second which is the vector , which look like this !

and the design will be sam , most importantly make it fully responsive and best !

Assistant
To create a fully responsive Elementor widget that mimics the layout shown in your uploaded image (with a **main image overlapping a vector background and content section**), here's how to do it using a **custom Elementor widget (Elementor Extension via plugin)**.

### ✅ **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?

User
how ill it look ?
Assistant
Here’s how the final Elementor widget will look when rendered on the page (based on your reference image):

### 💡 **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?

User
.circle-grid{
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?

Assistant
The issue in your responsiveness is due to **conflicting and repeated `display` styles** on the `.circle-grid` class:

.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?

User
I have one h1 , I have given width to its parent container , which is very less , so h1 is also coming multiple lines , so I dont want to shrink it untile that page has no space !
Assistant
To prevent the “ from wrapping **until absolutely necessary**, even if the parent container has a small width, you can use the following CSS technique:

### ✅ **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?

User
min-width: max-content;

I have used this but its not coming in center now !

Assistant
Exactly — when you use `min-width: max-content;`, the element grows to fit its content **without wrapping**, but that breaks centering because its width is no longer based on the parent container.

### ✅ 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?

User
not working , can we use transform
Assistant
Yes — using `transform` **is a reliable way to center absolutely-positioned or auto-sized content** like a non-wrapping “. Here’s how to center the “ horizontally even with `min-width: max-content`:

### ✅ **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.

Leave a Comment

Your email address will not be published. Required fields are marked *