Code help with Hotspots and Tooltips

Topic summary

A user is building a custom Shopify section with an image (2/3 width) and table (1/3 width), featuring interactive hotspots/tooltips that allow product selection and cart addition. The core issue: hotspots positioned in the theme editor don’t maintain their correct positions on the frontend.

Technical Details:

  • Image dimensions: 1000px × 1000px
  • Hotspots use X/Y position ranges (0-100) in the schema
  • Product selector and quantity input functionality works correctly
  • Only the positioning stability is problematic

Solution Provided:
A community member offered fixes addressing:

  • Proper container structure for aspect ratio maintenance
  • Improved tooltip positioning using CSS custom properties
  • Corrected 2/3 to 1/3 layout ratio
  • Enhanced responsive behavior for mobile

The solution includes updated code with the same schema and JavaScript, focusing on CSS positioning improvements. The original poster confirmed the fix works successfully.

Status: Resolved - hotspots now remain locked in position across different screen sizes and browser window resizing.

Summarized with AI on November 4. AI used: claude-sonnet-4-5-20250929.

Hi All,

Im hoping someone can help with this issue, Im no developer and have some understanding of code.

Im setting an image 2/3 of the page with and have a table to the right of it in the other 1/3.

The image is set at 1000px X 1000px, Im then adding a tooltip/hotspot over the image, Ive then setup a selector on that so you can select a product add your qty and add it to cart. This all works, my issue is adding the tooltips/hotspot onto the image, once its been added and I view the page on the frontend its not keeping the tooltip/hotspot in the correct position. I need to lock the position in the theme editor so it does not move.

Any help would be appreciated. Thanks in Advance

Here is the code Ive put together.

{% schema %}
{
“name”: “Hotspot v6.1”,
“settings”: [
{
“type”: “image_picker”,
“id”: “image”,
“label”: “Image”
}
],
“blocks”: [
{
“type”: “product_block”,
“name”: “Product Block”,
“settings”: [
{
“type”: “product”,
“id”: “product”,
“label”: “Select Product”
},
{
“type”: “range”,
“id”: “x_position”,
“label”: “X Position”,
“min”: 0,
“max”: 100,
“default”: 50
},
{
“type”: “range”,
“id”: “y_position”,
“label”: “Y Position”,
“min”: 0,
“max”: 100,
“default”: 50
}
]
}
],
“presets”: [
{
“name”: “Hotspot v6.1”,
“category”: “Custom”
}
]
}
{% endschema %}

{% if section.settings.image %}
Custom Image

{% assign displayed_products = ‘’ %}

{% for block in section.blocks %}
{% if block.settings.product %}
{% if block.settings.product.variants.size > 0 %}
{% assign product_sku = block.settings.product.variants.first.sku %}
{% assign product_price = block.settings.product.variants.first.price | money %}
{% else %}
{% assign product_sku = ‘No SKU’ %}
{% assign product_price = ‘Price unavailable’ %}
{% endif %}
{% unless displayed_products contains product_sku %}
{% assign displayed_products = displayed_products | append: product_sku | append: ‘,’ %}

{{ block.settings.product.title }}
{{ product_price }}
{% endunless %} {% endif %} {% endfor %}
{% endif %}

Parts Information

{% assign displayed_products = '' %}

{% for block in section.blocks %}
{% if block.settings.product %}
{% if block.settings.product.variants.size > 0 %}
{% assign product_sku = block.settings.product.variants.first.sku %}
{% assign product_price = block.settings.product.variants.first.price | money %}
{% else %}
{% assign product_sku = ‘No SKU’ %}
{% assign product_price = ‘Price unavailable’ %}
{% endif %}
{% unless displayed_products contains product_sku %}
{% assign displayed_products = displayed_products | append: product_sku | append: ‘,’ %}

{% endunless %} {% endif %} {% endfor %}
# Title
0 :shopping_cart:
Ref: {{ forloop.index }} Sku: {{ product_sku }}
{{ block.settings.product.title }}
Price: {{ product_price }}
{% if block.settings.product %} Add to Cart {% else %}

Product not found.

{% endif %}
Item added to cart!
.custom-image-table-section { display: flex; flex-direction: row; justify-content: space-between; gap: 20px; } .image-block { position: relative; flex: 1; max-width: 50%; } .table-block { flex: 1; margin-bottom: 20px; max-width: 50%; } .tooltip { position: absolute; display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; border: 3px solid #555; border-radius: 50%; cursor: pointer; background-color: transparent; color: transparent; transform: translate(-50%, -50%); top: 0; left: 0; } .tooltip:hover { border: 4px solid #D93939; } .tooltip .tooltiptext { visibility: hidden; width: 10vw; max-width: 140px; background-color: #333; color: #fff; font-size: 12px; text-align: center; border-radius: 6px; padding: 5px; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -60px; opacity: 0; transition: opacity 0.3s; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; } .highlight { background-color: #e88888; } @media (max-width: 768px) { .custom-image-table-section { flex-direction: column; } .image-block, .table-block { max-width: 100%; } }

Hi @dalemitchley ,

Thanks for reaching out about the hotspot positioning issue. I’ve reviewed your code and I understand the problem with the tooltips not staying in their correct positions. I have a solution that should fix this for you.

The main issue is with how the image container and tooltips are being positioned. I’ve made some improvements to the code that will keep the hotspots locked in place, while maintaining your 2/3 and 1/3 layout for the image and table.

Here are the key changes I’ve made:

  1. Added a proper container structure for the image to maintain aspect ratio
  2. Improved the tooltip positioning system using CSS custom properties
  3. Fixed the section layout to ensure the correct 2/3 to 1/3 ratio
  4. Enhanced the responsive behavior for mobile devices

I’ve attached the complete updated code below. To implement this fix:

  1. Replace your current section code with this new version
  2. Keep your existing schema and JavaScript code as they are
  3. Test the positioning in the theme editor
{%- comment -%}
The schema remains the same as your original code
{%- endcomment -%}
{% schema %}
{
  "name": "Hotspot v6.1",
  "settings": [
    {
      "type": "image_picker",
      "id": "image",
      "label": "Image"
    }
  ],
  "blocks": [
    {
      "type": "product_block",
      "name": "Product Block",
      "settings": [
        {
          "type": "product",
          "id": "product",
          "label": "Select Product"
        },
        {
          "type": "range",
          "id": "x_position",
          "label": "X Position",
          "min": 0,
          "max": 100,
          "default": 50
        },
        {
          "type": "range",
          "id": "y_position",
          "label": "Y Position",
          "min": 0,
          "max": 100,
          "default": 50
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Hotspot v6.1",
      "category": "Custom"
    }
  ]
}
{% endschema %}

  {% if section.settings.image %}
    

      

        

        {% assign displayed_products = '' %}
        {% for block in section.blocks %}
          {% if block.settings.product %}
            {% if block.settings.product.variants.size > 0 %}
              {% assign product_sku = block.settings.product.variants.first.sku %}
              {% assign product_price = block.settings.product.variants.first.price | money %}
            {% else %}
              {% assign product_sku = 'No SKU' %}
              {% assign product_price = 'Price unavailable' %}
            {% endif %}
            
            {% unless displayed_products contains product_sku %}
              {% assign displayed_products = displayed_products | append: product_sku | append: ',' %}
              

                
                  {{ block.settings.product.title }}
                  

                  {{ product_price }}
                
              

            {% endunless %}
          {% endif %}
        {% endfor %}
      

    

  {% endif %}

  {%- comment -%}Rest of your table block code remains the same{%- endcomment -%}
  
    
  

{%- comment -%}Your existing JavaScript remains the same{%- endcomment -%}

The tooltips should now stay perfectly positioned on your image, even when:

  • The browser window is resized
  • Viewing on different screen sizes
  • Making adjustments in the theme editor

Let me know if you need any help implementing these changes or if you have any questions. I’m happy to clarify anything that’s not clear.

Best regards,
Shubham | Untechnickle

@TheUntechnickle , this is great thanks so much for your help works great.