From 99e7134a84fc4e1c80cb8007b0c17cefae85d130 Mon Sep 17 00:00:00 2001 From: niranjan-uma-shankar Date: Sat, 2 Aug 2025 18:05:54 +0900 Subject: [PATCH 1/5] Prevents zoom on touch devices Zooming on Unsplash images in mobile and tablet devices leads to an awkward UI, not compatible with small screens. This removes the zoom capability on mobile and tablet devices. --- ghost/admin/app/components/gh-unsplash-photo.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ghost/admin/app/components/gh-unsplash-photo.js b/ghost/admin/app/components/gh-unsplash-photo.js index 122ccf4cdcb..dc20ee4fd96 100644 --- a/ghost/admin/app/components/gh-unsplash-photo.js +++ b/ghost/admin/app/components/gh-unsplash-photo.js @@ -41,6 +41,10 @@ export default class GhUnsplashPhoto extends Component { this.height = this.width * this.args.photo.ratio; } + get isTouchDevice() { + return window.matchMedia('(pointer: coarse)').matches; + } + @action select(event) { event.preventDefault(); @@ -52,6 +56,13 @@ export default class GhUnsplashPhoto extends Component { zoom(event) { const {target} = event; + // Prevent zooming on touch devices + if (this.isTouchDevice) { + event.stopPropagation(); + event.preventDefault(); + return; + } + // only zoom when it wasn't one of the child links clicked if (!target.matches('a') && target.closest('a').classList.contains('gh-unsplash-photo')) { event.preventDefault(); From dc9c3867364838587c258b625d20614e05993059 Mon Sep 17 00:00:00 2001 From: niranjan-uma-shankar Date: Sat, 2 Aug 2025 19:27:41 +0900 Subject: [PATCH 2/5] Allows clicks on overlay buttons Overlay button clicks are allowd to pass through on mobile devices --- ghost/admin/app/components/gh-unsplash-photo.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ghost/admin/app/components/gh-unsplash-photo.js b/ghost/admin/app/components/gh-unsplash-photo.js index dc20ee4fd96..e243199fa4d 100644 --- a/ghost/admin/app/components/gh-unsplash-photo.js +++ b/ghost/admin/app/components/gh-unsplash-photo.js @@ -55,8 +55,14 @@ export default class GhUnsplashPhoto extends Component { @action zoom(event) { const {target} = event; + const isOverlayButtonClick = target.closest('.gh-unsplash-button-likes') || + target.closest('.gh-unsplash-button-download') || + target.closest('.gh-unsplash-photo-author'); + + if (this.isTouchDevice && isOverlayButtonClick) { + return; + } - // Prevent zooming on touch devices if (this.isTouchDevice) { event.stopPropagation(); event.preventDefault(); From 11f1b15b5a7043bfa3437032f84e3abcb659f4b4 Mon Sep 17 00:00:00 2001 From: niranjan-uma-shankar Date: Sat, 2 Aug 2025 20:37:45 +0900 Subject: [PATCH 3/5] Refactors for improved maintainability --- ghost/admin/app/components/gh-unsplash-photo.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ghost/admin/app/components/gh-unsplash-photo.js b/ghost/admin/app/components/gh-unsplash-photo.js index e243199fa4d..3c710a96d36 100644 --- a/ghost/admin/app/components/gh-unsplash-photo.js +++ b/ghost/admin/app/components/gh-unsplash-photo.js @@ -7,6 +7,13 @@ export default class GhUnsplashPhoto extends Component { @tracked height = 0; @tracked width = 1200; + // Overlay button selectors for touch device handling + static OVERLAY_BUTTON_SELECTORS = [ + '.gh-unsplash-button-likes', + '.gh-unsplash-button-download', + '.gh-unsplash-photo-author' + ]; + get style() { return htmlSafe(this.args.zoomed ? 'width: auto; margin: 0;' : ''); } @@ -55,9 +62,7 @@ export default class GhUnsplashPhoto extends Component { @action zoom(event) { const {target} = event; - const isOverlayButtonClick = target.closest('.gh-unsplash-button-likes') || - target.closest('.gh-unsplash-button-download') || - target.closest('.gh-unsplash-photo-author'); + const isOverlayButtonClick = GhUnsplashPhoto.OVERLAY_BUTTON_SELECTORS.some(selector => target.closest(selector)); if (this.isTouchDevice && isOverlayButtonClick) { return; From a97542017f37543252f79a608e3b01025e18e74a Mon Sep 17 00:00:00 2001 From: niranjan-uma-shankar Date: Sun, 10 Aug 2025 19:18:23 +0530 Subject: [PATCH 4/5] Prevents small viewports in non-touch devices from zooming in Ref https://github.com/TryGhost/Ghost/issues/24585 When the browser window on a desktop is resized to a small viewport, this fix ensures that the zoom behaviour is disabled. Zoom continues to work in tab viewports in non-touch devices. --- ghost/admin/app/components/gh-unsplash-photo.js | 13 ++++++------- ghost/admin/app/styles/components/unsplash.css | 6 ++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ghost/admin/app/components/gh-unsplash-photo.js b/ghost/admin/app/components/gh-unsplash-photo.js index 3c710a96d36..ffd6b634f39 100644 --- a/ghost/admin/app/components/gh-unsplash-photo.js +++ b/ghost/admin/app/components/gh-unsplash-photo.js @@ -48,10 +48,6 @@ export default class GhUnsplashPhoto extends Component { this.height = this.width * this.args.photo.ratio; } - get isTouchDevice() { - return window.matchMedia('(pointer: coarse)').matches; - } - @action select(event) { event.preventDefault(); @@ -62,13 +58,16 @@ export default class GhUnsplashPhoto extends Component { @action zoom(event) { const {target} = event; - const isOverlayButtonClick = GhUnsplashPhoto.OVERLAY_BUTTON_SELECTORS.some(selector => target.closest(selector)); + const isOverlayButtonClick = GhUnsplashPhoto.OVERLAY_BUTTON_SELECTORS.some(selector => target.closest(selector)); + const isMobileViewport = window.matchMedia('(max-width: 540px)').matches; + const isTouchDevice = window.matchMedia('(pointer: coarse)').matches; + const shouldNotZoom = isMobileViewport || isTouchDevice; - if (this.isTouchDevice && isOverlayButtonClick) { + if (shouldNotZoom && isOverlayButtonClick) { return; } - if (this.isTouchDevice) { + if (shouldNotZoom) { event.stopPropagation(); event.preventDefault(); return; diff --git a/ghost/admin/app/styles/components/unsplash.css b/ghost/admin/app/styles/components/unsplash.css index 407844c1171..0bd36d70e26 100644 --- a/ghost/admin/app/styles/components/unsplash.css +++ b/ghost/admin/app/styles/components/unsplash.css @@ -131,6 +131,12 @@ cursor: zoom-in; } +@media (max-width: 540px) { + .gh-unsplash-photo { + cursor: default; + } +} + .gh-unsplash-photo-container > img { position: absolute; display: block; From 0400ae38dfc62c1011598017b026055e95f24775 Mon Sep 17 00:00:00 2001 From: Steve Larson <9larsons@gmail.com> Date: Wed, 10 Jun 2026 16:26:18 -0500 Subject: [PATCH 5/5] Aligned no-zoom cursor media query with coarse pointer detection --- ghost/admin/app/styles/components/unsplash.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ghost/admin/app/styles/components/unsplash.css b/ghost/admin/app/styles/components/unsplash.css index 0bd36d70e26..1fff17af048 100644 --- a/ghost/admin/app/styles/components/unsplash.css +++ b/ghost/admin/app/styles/components/unsplash.css @@ -131,7 +131,7 @@ cursor: zoom-in; } -@media (max-width: 540px) { +@media (pointer: coarse) { .gh-unsplash-photo { cursor: default; }