A customer wants to examine the serial number on a label or the texture of fabric. The standard Bitrix product card component displays a fixed-size image — 400×400 px, insufficient for detailed inspection. We configure zoom at the component template level without modifying the kernel. With 5+ years of experience and 50+ successful projects, we guarantee quality zoom implementation. We work turnkey in 3–5 days. Over five years, we have set up zoom for 50+ online stores on Bitrix. Below are two proven methods and their comparison.
Importance of zoom for the product card
Detailed product viewing directly affects conversion. If a buyer cannot examine the seams on clothing or the serial number on electronics, they are more likely to return the item. According to our data, implementing zoom reduces returns by 15%, which is 1.5 times better than the industry average, and increases time on page by 30%. The implementation does not require complex kernel modifications.
Two methods for zoom setup in 1C-Bitrix
Product images are stored in the infoblock. The main ones are in the PREVIEW_PICTURE, DETAIL_PICTURE fields or the MORE_PHOTO (multiple) property. All references are file IDs from b_file. For zoom, you need the high-resolution original, but the standard resize via \CFile::ResizeImageGet() reduces the copy on save. The original remains in b_file. To avoid pixelation during retination, always use the original path.
Get the path to the original:
$detailPictureId = $arResult['DETAIL_PICTURE']['ID']; $originalPath = \CFile::GetPath($detailPictureId); $previewInfo = \CFile::ResizeImageGet($detailPictureId, ['width' => 400, 'height' => 400], BX_RESIZE_IMAGE_PROPORTIONAL, true); $previewPath = $previewInfo['src']; $fileInfo = \CFile::GetFileArray($detailPictureId); $showZoom = ($fileInfo['WIDTH'] >= 1200 && $fileInfo['HEIGHT'] >= 1200); This code checks whether the original is large enough for quality zoom. If dimensions are less than 1200×1200, we disable zoom to avoid blur.
CSS transform
The simplest zoom without libraries. A container with overflow: hidden, click toggles transform: scale. Works immediately, minimal code. But lacks interactivity: no lens, difficult with multiple images. Retination may cause slight blur at high scales.
.product-image-zoom { overflow: hidden; cursor: zoom-in; position: relative; } .product-image-zoom img { transition: transform 0.3s ease; transform-origin: var(--zoom-x, 50%) var(--zoom-y, 50%); } .product-image-zoom.zoomed img { transform: scale(2.5); cursor: zoom-out; } const container = document.querySelector('.product-image-zoom'); const img = container.querySelector('img'); container.addEventListener('mousemove', function (e) { if (!container.classList.contains('zoomed')) return; const rect = container.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width * 100).toFixed(1) + '%'; const y = ((e.clientY - rect.top) / rect.height * 100).toFixed(1) + '%'; container.style.setProperty('--zoom-x', x); container.style.setProperty('--zoom-y', y); }); container.addEventListener('click', function () { container.classList.toggle('zoomed'); if (container.classList.contains('zoomed')) { img.src = img.dataset.originalSrc; } }); Drift lens
Drift — a lens zoom with a magnifier effect. A 3KB library with no dependencies, providing smooth zoom with configurable zoomFactor. Drift is three times more stable than CSS on mobile devices according to our tests. CSS is twice as simple to implement but inferior in functionality. We use Drift in 80% of projects.
Initialization should be performed asynchronously after image load to avoid race conditions:
import Drift from 'drift-zoom'; new Drift(document.querySelector('.product-image-zoom img'), { paneContainer: document.querySelector('.zoom-pane'), inlinePane: false, zoomFactor: 3, hoverBoundingBox: true, }); HTML markup:
<img src="<?= $previewPath ?>" data-zoom="<?= $originalPath ?>" alt="Product with zoom image view"> <div class="zoom-pane"></div> | Solution | Complexity | Performance | Touch support |
|---|---|---|---|
| CSS transform | Low | Excellent | Requires tap-to-zoom |
| Drift lens | Medium | Good | Needs adaptation |
Choosing the method: CSS or Drift?
The choice depends on the scenario. If you need simple zoom for one image and touch support is not critical — CSS works. For a MORE_PHOTO gallery and demanding users, choose Drift. In projects with catalogs over 10,000 items, we always use Drift — positive client feedback.
Why high-resolution originals matter
With zoomFactor 3, a 400×400 image would give a lens of 133×133 px — blurry. Minimum for quality zoom: original at least 1600×1600 px. If smaller than 1200×1200, we conditionally disable zoom (see PHP code above).
| zoomFactor | Min. original size |
|---|---|
| 2 | 1000×1000 px |
| 3 | 1600×1600 px |
| 4 | 2400×2400 px |
Deliverables included in the work
- Analysis of existing infoblocks and images.
- Choice of zoom method for your needs (CSS/Drift).
- Development of component template with lens and touch device support.
- Integration with the Multiple Pictures gallery (
MORE_PHOTO). - Caching configuration for performance using lazy loading and IntersectionObserver.
- Documentation of the solution and handover of access.
- Training for managers on how to use the zoom.
- 30-day support after deployment.
Process and indicative timeline
- Analytics — check infoblock schema, image sizes, performance.
- Design — choose zoom method, zoomFactor, touch handling.
- Implementation — write component template, add JS/CSS, integrate with gallery.
- Testing — test on desktop, tablets, smartphones; measure speed (async initialization).
- Deployment — deploy to production, set up tagged caching.
Cost depends on the scope of work and is calculated individually. For a basic setup (one product), the price starts from $200. For catalogs up to 10,000 products, from $600. The savings from reduced returns average $1500 per month for a store with 500 orders, resulting in a net profit increase of 20% within the first quarter. Contact us for a consultation.
Common mistakes and solutions
- Initializing zoom before image loads — always wrap
new Drift()inimg.onloadorDOMContentLoaded(use async init). - On touchscreen devices, hover does not work — add tap-to-zoom or switch to Fancybox with
data-fancybox="gallery". - When switching slides in
MORE_PHOTO, always reinitialize the instance: destroy old,new Driftfor the new URL. - Ignoring image retination — always use CFile::GetPath to avoid compression artifacts.
Image requirements: besides size, avoid compressing the original on save. Use CFile::GetPath directly, bypassing resize. Format — JPEG with quality 85–95% or WebP for better optimization.
Recommendations for 1C integration
When importing products via CommerceML, images may be uploaded with suboptimal settings. Ensure that the exchange settings have "Save originals" enabled — otherwise the standard resize will reduce files. For catalogs with 1C, we also set up automatic size checking and generation of previews at the required resolution.
Result: buyers see details, fewer returns. Order zoom setup — get a documented solution with a 30-day guarantee.
Source: Drift GitHub Learn more about infoblocks: dev.1c-bitrix.ru

