Shopify Products Grid Section – Advanced
{% comment %}
GV Featured Grid – NO SNIPPETS (Final Clean)
Requested updates:
– Mobile: Add to cart button goes to next line (below price)
– Image: NO background box, NO forced height/padding — only original image shows (natural ratio)
– Remove Card background settings (red box in editor) ✅
– Card background always follows Dawn color scheme (var(–color-background)) ✅
– Title uses scheme foreground (no blue)
– Title clamped so footer stays aligned
{% endcomment %}
{%- liquid
assign sid = 'gvfp-' | append: section.id
assign limit = section.settings.products_to_show | default: 4
assign columns_desktop = section.settings.columns_desktop | default: 4
assign columns_mobile = section.settings.columns_mobile | default: 2
-%}
<section id="{{ sid }}" class="gvfp color-{{ section.settings.color_scheme }} gradient">
<div class="gvfp__wrap page-width">
{%- if section.settings.heading != blank or section.settings.subheading != blank -%}
<header class="gvfp__head gvfp__head--{{ section.settings.heading_align }}">
{%- if section.settings.heading != blank -%}
<h2 class="gvfp__title">{{ section.settings.heading | escape }}</h2>
{%- endif -%}
{%- if section.settings.subheading != blank -%}
<p class="gvfp__sub">{{ section.settings.subheading | escape }}</p>
{%- endif -%}
</header>
{%- endif -%}
{%- if section.settings.collection != blank -%}
<div class="gvfp__grid" style="--cols:{{ columns_desktop }};--cols-m:{{ columns_mobile }};">
{%- for product in section.settings.collection.products limit: limit -%}
{%- liquid
assign badge = blank
if section.settings.enable_badges
if product.compare_at_price_max > product.price
assign badge = 'Sale'
elsif product.tags contains 'new' or product.tags contains 'New'
assign badge = 'New'
elsif product.tags contains 'bestseller' or product.tags contains 'Best Seller' or product.tags contains 'Best-Seller'
assign badge = 'Best Seller'
endif
endif
assign has_one_variant = false
if section.settings.enable_quick_add and product.variants.size == 1 and product.available
assign has_one_variant = true
endif
assign img = product.featured_media
-%}
<article class="gvfp__card">
<a href="{{ product.url }}" class="gvfp__media" aria-label="{{ product.title | escape }}">
{%- if badge != blank -%}
<span class="gvfp__badge">{{ badge }}</span>
{%- endif -%}
{%- if img != blank -%}
{{ img | image_url: width: 900 | image_tag:
loading: 'lazy',
class: 'gvfp__img',
widths: '360, 540, 720, 900',
sizes: '(max-width: 640px) 92vw, (max-width: 990px) 45vw, 23vw',
alt: product.title
}}
{%- endif -%}
</a>
<div class="gvfp__info">
{%- if section.settings.show_vendor -%}
<div class="gvfp__vendor">{{ product.vendor | escape }}</div>
{%- endif -%}
<h3 class="gvfp__name">
<a class="gvfp__link" href="{{ product.url }}">{{ product.title | escape }}</a>
</h3>
{%- comment -%} Short description removed {%- endcomment -%}
<div class="gvfp__foot">
{%- if section.settings.show_price -%}
<div class="gvfp__price">{{ product.price | money }}</div>
{%- endif -%}
{%- if has_one_variant -%}
<form method="post" action="/cart/add" class="gvfp__form">
<input type="hidden" name="id" value="{{ product.variants.first.id }}">
<button type="submit" class="gvfp__btn">Add to cart</button>
</form>
{%- else -%}
<a href="{{ product.url }}" class="gvfp__btn">Add to cart</a>
{%- endif -%}
</div>
</div>
</article>
{%- endfor -%}
</div>
{%- if section.settings.show_view_all -%}
<div class="gvfp__viewall">
<a class="gvfp__viewallBtn" href="{{ section.settings.collection.url }}">View all</a>
</div>
{%- endif -%}
{%- endif -%}
</div>
<style>
#{{ sid }}{
padding: {{ section.settings.padding_top }}px 0 {{ section.settings.padding_bottom }}px;
--accent: #E10600;
--radius: 14px;
/* ✅ Card background always from Dawn scheme (no editor control) */
--card-bg: var(--color-background);
/* Content background optional (scheme/custom) */
--content-bg: {% if section.settings.content_bg_mode == 'scheme' %} var(--color-background) {% else %} {{ section.settings.content_custom_bg }} {% endif %};
--txt: var(--color-foreground);
--muted: color-mix(in srgb, var(--color-foreground) 65%, transparent);
--border: color-mix(in srgb, var(--color-foreground) 12%, transparent);
}
#{{ sid }} .gvfp__wrap{ width:min(1200px, 92vw); margin:0 auto; }
#{{ sid }} .gvfp__head{ margin-bottom: 18px; }
#{{ sid }} .gvfp__head--left{ text-align:left; }
#{{ sid }} .gvfp__head--center{ text-align:center; }
#{{ sid }} .gvfp__head--right{ text-align:right; }
#{{ sid }} .gvfp__title{
margin:0 0 6px;
color: var(--txt);
font-size: clamp(20px, 2.2vw, 34px);
letter-spacing:.3px;
text-transform: uppercase;
font-weight: 800;
}
#{{ sid }} .gvfp__sub{ margin:0; color: var(--muted); }
#{{ sid }} .gvfp__grid{
display:grid;
gap: 18px;
grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
}
@media(max-width:990px){
#{{ sid }} .gvfp__grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media(max-width:640px){
#{{ sid }} .gvfp__wrap{ width:100%; padding: 0 12px; }
#{{ sid }} .gvfp__grid{
grid-template-columns: repeat(var(--cols-m), minmax(0, 1fr));
gap: 12px;
}
}
#{{ sid }} .gvfp__card{
background: var(--card-bg);
border-radius: var(--radius);
overflow:hidden;
border: 1px solid var(--border);
box-shadow: 0 10px 28px rgba(0,0,0,.18);
transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
display:flex;
flex-direction:column;
min-height: 100%;
}
#{{ sid }} .gvfp__card:hover{
transform: translateY(-4px);
box-shadow: 0 16px 34px rgba(0,0,0,.22);
border-color: color-mix(in srgb, var(--color-foreground) 20%, transparent);
}
@media (prefers-reduced-motion: reduce){
#{{ sid }} .gvfp__card{ transition:none; }
#{{ sid }} .gvfp__card:hover{ transform:none; }
}
/* ✅ MEDIA: only original image, no background box, no forced height/padding */
#{{ sid }} .gvfp__media{
position: relative;
display:block;
text-decoration:none;
color:inherit;
}
#{{ sid }} .gvfp__img{
display:block;
width:100%;
height:auto;
}
#{{ sid }} .gvfp__badge{
position:absolute;
top:12px; left:12px;
background: var(--accent);
color:#fff;
font-weight: 800;
font-size: 11px;
letter-spacing:.4px;
text-transform: uppercase;
padding: 6px 10px;
border-radius: 6px;
z-index: 2;
}
#{{ sid }} .gvfp__info{
background: var(--content-bg);
padding: 16px 16px 14px;
display:flex;
flex-direction:column;
gap: 8px;
min-height: 150px;
}
#{{ sid }} .gvfp__vendor{
color: color-mix(in srgb, var(--accent) 80%, transparent);
font-weight: 800;
font-size: 11px;
letter-spacing: 2.2px;
text-transform: uppercase;
}
/* Title clamp (2 lines) to keep footer aligned */
#{{ sid }} .gvfp__name{
margin: 0;
font-weight: 800;
text-transform: uppercase;
font-size: 14px;
line-height: 1.25;
display:-webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow:hidden;
min-height: calc(14px * 1.25 * 2);
}
#{{ sid }} .gvfp__link{
color: var(--txt);
text-decoration:none;
}
#{{ sid }} .gvfp__link:hover{
color: var(--accent);
text-decoration:none;
}
/* Footer bottom aligned */
#{{ sid }} .gvfp__foot{
margin-top: auto;
display:flex;
align-items:center;
justify-content:space-between;
gap: 10px;
}
#{{ sid }} .gvfp__price{
color: var(--txt);
font-size: 18px;
font-weight: 900;
white-space: nowrap;
}
#{{ sid }} .gvfp__btn{
display:inline-flex;
align-items:center;
justify-content:center;
height: 38px;
padding: 0 14px;
background: var(--accent);
color:#fff;
border:0;
border-radius: 0;
text-decoration:none;
font-weight: 900;
letter-spacing: 1.6px;
text-transform: uppercase;
font-size: 12px;
cursor:pointer;
white-space: nowrap;
min-width: 128px;
}
#{{ sid }} .gvfp__btn:hover{ filter: brightness(.92); }
#{{ sid }} .gvfp__form{ margin:0; }
/* ✅ Mobile: button on next row */
@media(max-width:640px){
#{{ sid }} .gvfp__foot{
flex-direction: column;
align-items: stretch;
}
#{{ sid }} .gvfp__btn{
width: 100%;
min-width: 0;
}
}
#{{ sid }} .gvfp__viewall{ margin-top: 18px; text-align:center; }
#{{ sid }} .gvfp__viewallBtn{
display:inline-flex;
align-items:center;
justify-content:center;
height: 40px;
padding: 0 18px;
color: var(--txt);
text-decoration:none;
border: 1px solid var(--border);
border-radius: 10px;
font-weight: 800;
letter-spacing: 1.6px;
text-transform: uppercase;
font-size: 12px;
}
#{{ sid }} .gvfp__viewallBtn:hover{
border-color: color-mix(in srgb, var(--color-foreground) 25%, transparent);
}
</style>
</section>
{% schema %}
{
"name": "GV Featured Grid",
"settings": [
{ "type": "color_scheme", "id": "color_scheme", "label": "Color scheme", "default": "background-1" },
{ "type": "text", "id": "heading", "label": "Heading", "default": "Featured Products" },
{ "type": "text", "id": "subheading", "label": "Subheading", "default": "Shop premium GymVaro equipment" },
{ "type": "select", "id": "heading_align", "label": "Heading alignment", "default": "left",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Center" },
{ "value": "right", "label": "Right" }
]
},
{ "type": "collection", "id": "collection", "label": "Collection" },
{ "type": "range", "id": "products_to_show", "min": 1, "max": 12, "step": 1, "label": "Products to show", "default": 4 },
{ "type": "range", "id": "columns_desktop", "min": 2, "max": 6, "step": 1, "label": "Columns (desktop)", "default": 4 },
{ "type": "select", "id": "columns_mobile", "label": "Columns (mobile)", "default": "2",
"options": [
{ "value": "1", "label": "1" },
{ "value": "2", "label": "2" }
]
},
{ "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": true },
{ "type": "checkbox", "id": "show_price", "label": "Show price", "default": true },
{ "type": "checkbox", "id": "enable_badges", "label": "Enable badges (sale/new/bestseller by tags)", "default": true },
{ "type": "checkbox", "id": "enable_quick_add", "label": "Quick add (only if 1 variant)", "default": true },
{ "type": "checkbox", "id": "show_view_all", "label": "Show View all", "default": true },
{ "type": "header", "content": "Content background" },
{ "type": "select", "id": "content_bg_mode", "label": "Content background mode", "default": "custom",
"options": [
{ "value": "scheme", "label": "Use color scheme background" },
{ "value": "custom", "label": "Use custom color" }
]
},
{ "type": "color", "id": "content_custom_bg", "label": "Content background color", "default": "#1c1c1c" },
{ "type": "range", "id": "padding_top", "min": 0, "max": 120, "step": 4, "label": "Padding top", "default": 40 },
{ "type": "range", "id": "padding_bottom", "min": 0, "max": 120, "step": 4, "label": "Padding bottom", "default": 40 }
],
"presets": [
{ "name": "GV Featured Grid" }
]
}
{% endschema %}
