← back to Designer Wallcoverings
card-hover v3: hide vendor on touch (mobile shows pattern name only)
1cde76665c4cf1901f90aaf69a6a4d7aeca27ad5 · 2026-06-22 19:27:22 -0700 · Steve Abrams
Files touched
M shopify/theme-5.0-duplicate/assets/dw-card-hover.js
Diff
commit 1cde76665c4cf1901f90aaf69a6a4d7aeca27ad5
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jun 22 19:27:22 2026 -0700
card-hover v3: hide vendor on touch (mobile shows pattern name only)
---
.../theme-5.0-duplicate/assets/dw-card-hover.js | 139 ++++++++++++++++-----
1 file changed, 109 insertions(+), 30 deletions(-)
diff --git a/shopify/theme-5.0-duplicate/assets/dw-card-hover.js b/shopify/theme-5.0-duplicate/assets/dw-card-hover.js
index c9d5ca46..1a2adcd3 100644
--- a/shopify/theme-5.0-duplicate/assets/dw-card-hover.js
+++ b/shopify/theme-5.0-duplicate/assets/dw-card-hover.js
@@ -1,54 +1,133 @@
+/* ============================================================================
+ DW card hover overlay v3 (2026-06-22) — collection / search product grids.
+ Clean image-ONLY grid: the native text band below every card image is removed
+ (kept in DOM for SEO/a11y via the clip technique). On HOVER / focus, a refined
+ overlay rises over the image bottom:
+ Pattern name Title-Cased, scales with grid density
+ ── hairline
+ VENDOR uppercase, wide tracking
-/* ============================================================================
- DW card hover label (2026-06-22) — Boost product grid cards.
- Default: clean image-only grid (full SEO title hidden).
- On hover: reveal "Pattern, Color" (full title minus "wallcovering(s) | vendor")
- + the vendor on a smaller line. Full title stays in DOM for SEO.
- Re-applies to infinite-scroll-appended / Boost-rerendered cards via observer.
+ Touch devices (no hover) get a compact persistent label so phone shoppers
+ still see names. Honors prefers-reduced-motion. Works on the theme markup
+ (.product-list-item*) AND Boost AI Search markup (.boost-sd__product-item),
+ re-applying to lazy / infinite-scroll / re-rendered cards via a MutationObserver.
+
+ Source asset: assets/dw-card-hover.js (loaded by layout/theme.liquid).
+ v1 backup: assets/dw-card-hover.js.v1-bak
========================================================================== */
(function () {
if (window.__dwCardHover) return;
window.__dwCardHover = true;
+ var CARD = '.product-list-item, .boost-sd__product-item';
+ var TITLE = '.product-list-item-title, .boost-sd__product-title';
+ var VENDOR = '.product-list-item-vendor, .boost-sd__product-vendor';
+ var THUMB = '.product-list-item-thumbnail, .boost-sd__product-image-wrapper, [class*="boost-sd__product-image"]:not(img)';
+
var STYLE_ID = 'dw-card-hover-style';
if (!document.getElementById(STYLE_ID)) {
var st = document.createElement('style');
st.id = STYLE_ID;
- st.textContent =
- '.boost-sd__product-item .boost-sd__product-title,' +
- '.boost-sd__product-item .boost-sd__product-vendor{opacity:0;transition:opacity .15s;}' +
- '.boost-sd__product-item:hover .dw-hover-label{opacity:1;}' +
- '.dw-hover-label{opacity:0;transition:opacity .15s;padding:6px 2px 0;pointer-events:none;}' +
- '.dw-hover-label .pat{font-size:13px;font-weight:600;color:#1a1a1a;line-height:1.2;}' +
- '.dw-hover-label .ven{font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:#888;margin-top:2px;}' +
- /* Mobile: no real hover -> always show, and ONLY the pattern name (hide vendor). */
- '@media(max-width:768px){.boost-sd__product-item .dw-hover-label{opacity:1 !important;}.dw-hover-label .ven{display:none !important;}}';
+ st.textContent = [
+ /* image wrapper = positioning context for the overlay */
+ '.product-list-item .product-list-item-thumbnail,',
+ '.boost-sd__product-item .boost-sd__product-image-wrapper,',
+ '.boost-sd__product-item [class*="boost-sd__product-image"]:not(img){position:relative;}',
+
+ /* collapse the native text band to zero height. Boost keeps vendor/title/
+ price as siblings, so each is clipped directly. Kept in DOM for SEO/a11y. */
+ '.product-list-item .product-list-item-details,',
+ '.boost-sd__product-item .boost-sd__product-info,',
+ '.boost-sd__product-item .boost-sd__product-title,',
+ '.boost-sd__product-item .boost-sd__product-vendor,',
+ '.boost-sd__product-item [class*="boost-sd__product-price"],',
+ '.boost-sd__product-item [class*="boost-sd__format-price"]{',
+ 'position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;',
+ 'overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;}',
+
+ /* the overlay — rises over the image bottom on reveal */
+ '.dw-hover-overlay{position:absolute;left:0;right:0;bottom:0;z-index:2;',
+ 'padding:22px 14px 13px;pointer-events:none;opacity:0;transform:translateY(7px);',
+ 'transition:opacity .28s cubic-bezier(.4,0,.2,1),transform .28s cubic-bezier(.4,0,.2,1);',
+ 'background:linear-gradient(to top,rgba(16,16,18,.80) 0%,rgba(16,16,18,.46) 46%,rgba(16,16,18,0) 100%);',
+ 'font-family:-apple-system,system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;}',
+ '.product-list-item:hover .dw-hover-overlay,',
+ '.product-list-item:focus-within .dw-hover-overlay,',
+ '.boost-sd__product-item:hover .dw-hover-overlay,',
+ '.boost-sd__product-item:focus-within .dw-hover-overlay{opacity:1;transform:translateY(0);}',
+ '.dw-hover-overlay .pat{font-size:clamp(12px,1.02vw,14px);font-weight:600;line-height:1.22;',
+ 'color:#fff;letter-spacing:.004em;text-shadow:0 1px 3px rgba(0,0,0,.55);}',
+ '.dw-hover-overlay .ven{font-size:10px;letter-spacing:.16em;text-transform:uppercase;',
+ 'color:rgba(255,255,255,.86);margin-top:6px;text-shadow:0 1px 3px rgba(0,0,0,.55);}',
+ '.dw-hover-overlay .ven::before{content:"";display:block;width:18px;height:1px;',
+ 'background:rgba(255,255,255,.5);margin:0 0 6px;}',
+
+ /* touch / no-hover: show a compact persistent label */
+ '@media (hover:none){.dw-hover-overlay{opacity:1;transform:none;padding:18px 12px 11px;}.dw-hover-overlay .ven{display:none;}}',
+ /* reduced motion: no slide */
+ '@media (prefers-reduced-motion:reduce){.dw-hover-overlay{transition:opacity .12s linear;transform:none;}}'
+ ].join('');
document.head.appendChild(st);
}
+ function esc(s) {
+ return s.replace(/[&<>"']/g, function (c) {
+ return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
+ });
+ }
+
+ // Boost renders titles lowercase; Title-Case for a luxe look. Small stop-words
+ // (and/or/of/on/in/the/a/an/to/with) stay lowercase unless they lead the line.
+ var STOP = { and:1, or:1, of:1, on:1, in:1, the:1, a:1, an:1, to:1, with:1 };
function titleCase(s) {
- return s.replace(/\w\S*/g, function (w) { return w.charAt(0).toUpperCase() + w.slice(1); });
+ var i = 0;
+ return s.replace(/\w[\w']*/g, function (w) {
+ i++;
+ var lower = w.toLowerCase();
+ if (i > 1 && STOP[lower]) return lower;
+ return w.charAt(0).toUpperCase() + w.slice(1);
+ });
+ }
+
+ function patternName(title) {
+ var t = title;
+ if (t.indexOf('|') !== -1) t = t.split('|')[0]; // "Name | Vendor"
+ else { // "Name By Designer"
+ var by = t.split(/\s+by\s+/i);
+ if (by.length > 1) t = by[0];
+ }
+ t = t.replace(/\s*wallcoverings?\b/ig, '') // drop "wallcovering(s)"
+ .replace(/[,\s]+$/, '').trim();
+ return titleCase(t);
}
function labelCard(card) {
- if (card.querySelector('.dw-hover-label')) return;
- var tEl = card.querySelector('.boost-sd__product-title');
- var vEl = card.querySelector('.boost-sd__product-vendor');
+ if (card.querySelector('.dw-hover-overlay')) return;
+ var tEl = card.querySelector(TITLE);
if (!tEl) return;
- var vendor = (vEl ? vEl.textContent : '').trim();
- var name = tEl.textContent.split('|')[0].trim() // drop "| vendor"
- .replace(/\s*wallcoverings?\b/ig, '') // drop "wallcovering(s)"
- .replace(/[,\s]+$/, '').trim();
- var lab = document.createElement('div');
- lab.className = 'dw-hover-label';
- lab.innerHTML = '<div class="pat">' + titleCase(name) + '</div>' +
- (vendor ? '<div class="ven">' + titleCase(vendor) + '</div>' : '');
- tEl.parentElement.appendChild(lab);
+ var name = patternName(tEl.textContent || '');
+ if (!name) return;
+ var vEl = card.querySelector(VENDOR);
+ var vendor = (vEl ? vEl.textContent : '').replace(/\s+/g, ' ').trim();
+
+ var imgWrap = card.querySelector(THUMB);
+ if (!imgWrap) {
+ var img = card.querySelector('img');
+ imgWrap = img ? img.parentElement : null;
+ }
+ if (!imgWrap) return;
+ if (getComputedStyle(imgWrap).position === 'static') imgWrap.style.position = 'relative';
+
+ var ov = document.createElement('div');
+ ov.className = 'dw-hover-overlay';
+ ov.innerHTML = '<div class="pat">' + esc(name) + '</div>' +
+ (vendor ? '<div class="ven">' + esc(vendor) + '</div>' : '');
+ imgWrap.appendChild(ov);
}
function run() {
- var cards = document.querySelectorAll('.boost-sd__product-item');
+ var cards = document.querySelectorAll(CARD);
for (var i = 0; i < cards.length; i++) labelCard(cards[i]);
}
@@ -58,7 +137,7 @@
run();
}
- // Re-apply when Boost renders a grid or infinite scroll appends more cards.
+ // Re-apply when the grid re-renders or lazy/infinite scroll appends cards.
var t;
var obs = new MutationObserver(function (muts) {
for (var i = 0; i < muts.length; i++) {
← 7df3fcf8 Bucket-B PR + Hollywood sample-only roll-variant scripts (DT
·
back to Designer Wallcoverings
·
Fix grid slider: force setProperty with !important to overri 24ae0051 →