[object Object]

← back to Designer Wallcoverings

Fix grid slider: force setProperty with !important to override Boost inline styles

24ae0051c77162285d489dea1dee9e894eabcb6b · 2026-06-22 19:35:17 -0700 · Steve Abrams

Files touched

Diff

commit 24ae0051c77162285d489dea1dee9e894eabcb6b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jun 22 19:35:17 2026 -0700

    Fix grid slider: force setProperty with !important to override Boost inline styles
---
 shopify/_cwGRID/assets/dw-grid-control.js          |   5 +-
 .../assets/dw-card-hover.js                        |  87 +++++++++++----------
 v51-attempt.png                                    | Bin 1627744 -> 0 bytes
 v51-collection.png                                 | Bin 3257667 -> 0 bytes
 v51-working.png                                    | Bin 1530585 -> 0 bytes
 5 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/shopify/_cwGRID/assets/dw-grid-control.js b/shopify/_cwGRID/assets/dw-grid-control.js
index 54d68345..79dcf714 100644
--- a/shopify/_cwGRID/assets/dw-grid-control.js
+++ b/shopify/_cwGRID/assets/dw-grid-control.js
@@ -43,8 +43,9 @@
 
   function applyGrid(container, cols) {
     container.style.display = 'grid';
-    container.style.gridTemplateColumns = 'repeat(' + cols + ', 1fr)';
-    container.style.gap = '4px';
+    // Force grid columns with !important to override Boost's inline styles
+    container.style.setProperty('grid-template-columns', 'repeat(' + cols + ', 1fr)', 'important');
+    container.style.setProperty('gap', '4px', 'important');
     var imgWidth = container.offsetWidth / cols;
     container.style.paddingRight = imgWidth + 'px';
     // Dense-mode class: hides descriptions via CSS when > 4 cols
diff --git a/shopify/theme-infinite-scroll-142250278963/assets/dw-card-hover.js b/shopify/theme-infinite-scroll-142250278963/assets/dw-card-hover.js
index adabe1db..d2f1d53c 100644
--- a/shopify/theme-infinite-scroll-142250278963/assets/dw-card-hover.js
+++ b/shopify/theme-infinite-scroll-142250278963/assets/dw-card-hover.js
@@ -1,21 +1,17 @@
 /* ============================================================================
-   DW card hover overlay  v2  (2026-06-22) — collection / search product grids.
+   DW card hover overlay  v3  (2026-06-22) — collection / search product grids.
 
-   Layout (Steve, 2026-06-22): clean image-ONLY grid — the entire native text
-   band below each card image is removed (nothing below). On HOVER of the image
-   an overlay fades in over the image bottom showing:
-       Pattern name      (full SEO title minus "wallcovering(s)" and "| vendor")
-       VENDOR            (smaller, uppercase, beneath the pattern)
+   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
 
-   The full SEO title + vendor links stay in the DOM (visually hidden via the
-   clip technique, not removed) so search engines / screen readers still see
-   them, and the image itself stays a link to the product page.
-
-   This store's grids are rendered through the THEME product template
-   (.product-list-item*), even on Boost AI Search & Discovery surfaces.
-   We also support Boost's native markup (.boost-sd__product-item) so the
-   behavior is correct on every collection / search / vendor / tag grid.
-   Re-applies to lazy/infinite-scroll-appended cards via a MutationObserver.
+   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
@@ -24,12 +20,10 @@
   if (window.__dwCardHover) return;
   window.__dwCardHover = true;
 
-  // selector config — first match wins per card, covers theme + Boost markup
   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, [class*="boost-sd__product-image"]:not(img)';
-  var BAND   = '.product-list-item-details, .boost-sd__product-info';
+  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)) {
@@ -38,11 +32,11 @@
     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 below the image to zero height. Boost keeps
-         the vendor/title/price as siblings (not all inside product-info), so each
-         is clipped directly. Kept in DOM for SEO + a11y via the clip technique. */
+      /* 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,',
@@ -52,18 +46,27 @@
         '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 hover overlay — sits on the bottom of the image */
+      /* the overlay — rises over the image bottom on reveal */
       '.dw-hover-overlay{position:absolute;left:0;right:0;bottom:0;z-index:2;',
-        'padding:16px 12px 11px;pointer-events:none;opacity:0;transition:opacity .18s ease;',
-        'background:linear-gradient(to top,rgba(20,20,20,.66) 0%,rgba(20,20,20,.30) 55%,rgba(20,20,20,0) 100%);}',
+        '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;}',
-      '.dw-hover-overlay .pat{font-size:13px;font-weight:600;line-height:1.25;color:#fff;',
-        'white-space:normal;text-shadow:0 1px 2px rgba(0,0,0,.4);}',
-      '.dw-hover-overlay .ven{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;',
-        'color:rgba(255,255,255,.85);margin-top:3px;white-space:normal;text-shadow:0 1px 2px rgba(0,0,0,.4);}'
+      '.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;}}',
+      /* reduced motion: no slide */
+      '@media (prefers-reduced-motion:reduce){.dw-hover-overlay{transition:opacity .12s linear;transform:none;}}'
     ].join('');
     document.head.appendChild(st);
   }
@@ -75,37 +78,39 @@
   }
 
   // Boost renders titles lowercase; Title-Case for a luxe look. Small stop-words
-  // (and/or/of/on/in/the/a/an) stay lowercase unless they lead the line, per DW's
-  // title-case conventions. Only the first letter of other words is forced up so
-  // already-proper text is left intact.
+  // (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) {
     var i = 0;
-    return s.replace(/\w\S*/g, function (w) {
-      var lower = w.toLowerCase();
+    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 name = title.split('|')[0].trim()        // drop "| vendor"
-      .replace(/\s*wallcoverings?\b/ig, '')       // drop "wallcovering(s)"
-      .replace(/[,\s]+$/, '').trim();             // tidy trailing comma/space
-    return titleCase(name);
+    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-overlay')) return;          // already done
+    if (card.querySelector('.dw-hover-overlay')) return;
     var tEl = card.querySelector(TITLE);
     if (!tEl) return;
     var name = patternName(tEl.textContent || '');
     if (!name) return;
     var vEl = card.querySelector(VENDOR);
-    var vendor = (vEl ? vEl.textContent : '').trim();
+    var vendor = (vEl ? vEl.textContent : '').replace(/\s+/g, ' ').trim();
 
-    // anchor the overlay to the image wrapper (never the <img> itself)
     var imgWrap = card.querySelector(THUMB);
     if (!imgWrap) {
       var img = card.querySelector('img');
diff --git a/v51-attempt.png b/v51-attempt.png
deleted file mode 100644
index 3f515f56..00000000
Binary files a/v51-attempt.png and /dev/null differ
diff --git a/v51-collection.png b/v51-collection.png
deleted file mode 100644
index ecfd5424..00000000
Binary files a/v51-collection.png and /dev/null differ
diff --git a/v51-working.png b/v51-working.png
deleted file mode 100644
index cb71205f..00000000
Binary files a/v51-working.png and /dev/null differ

← 1cde7666 card-hover v3: hide vendor on touch (mobile shows pattern na  ·  back to Designer Wallcoverings  ·  auto-save: 2026-06-22T19:38:17 (4 files) — shopify/theme-5.0 4fb13ceb →