Add Quickview Button to Your Shopify Product Card

Add Quickview Button to Your Shopify Product Card

Compatibility: Compatible with any Shopify 2.0 FREE themes

If you're running a Shopify store, you know how important it is to provide your customers with an enjoyable and seamless shopping experience. One way to do this is by adding a quickview button to your product cards.

A quickview button allows customers to see a preview of a product without having to leave the current page they're on. This feature can significantly improve the user experience of your website, as it eliminates the need for customers to navigate away from their current location and wait for a new page to load.

By using Shopify's section rendering API, you can easily add a quickview button to your product cards without having to install any external libraries or apps. This means you can customize the functionality and design of the button to match your brand's aesthetic and needs.

With a quickview button, customers can easily view product information, add items to their cart, and continue shopping without interruption. By providing this feature, you're showing your customers that you value their time and want to make their shopping experience as enjoyable as possible.

It's worth noting that while some of Shopify's free 2.0 themes do offer a built-in quick view button, the features may be limited and not fully customizable to your preferences. By using our code, you'll have more control over the design and functionality of your quick view button.

Don't miss out on the opportunity to improve your store's user experience. Add a quickview button to your product cards today and watch your conversion rates soar.

Check DEMO store here 💻. Password: made4uo

What is a quick view button?

A quick view button is a user interface element typically placed on product listings that allows customers to see a product's details in a pop-up window without leaving the current page. This functionality provides a convenient way for customers to browse product information without interrupting their shopping flow.

 

Why add a quick view button?

There are several reasons to incorporate a quick view button into your Shopify store:

  • Improved User Experience: Quick view buttons allow customers to efficiently explore product details without navigating away from the current page.
  • Increased Sales: By providing easy access to product information, quick view buttons can encourage customers to learn more about products and potentially add them to their cart.
  • Reduced Bounce Rate: Quick view functionality can help keep customers engaged on your store by minimizing the need to click through to individual product pages.

Additional Considerations

  • Mobile-friendliness: Ensure the quick view button and pop-up function seamlessly on all devices, especially smartphones.
  • Content Optimization: For optimal presentation within the quick view pop-up, consider the structure and detail level of the displayed product information.
  • Loading Speed: A quick view pop-up that loads slowly can disrupt the user experience. Ensure the pop-up content is optimized for fast loading times.

What you are buying:

  • Hide and show the quickview button with hover
  • Mobile friendly with small button provided
  • Previous and next navigation provided for easy collection view
  • Thumbnail sliders available

What makes our code better:

  • We do not use external libraries, with that being said, our code will have no to minimal effect to your website's speed performance
  • We do not leave or add codes use to advertise for our website
  • Our code is mobile friendly

Any issues related to the code will be fix with no additional cost, excluding code customization requests. Simply contact us with "Chat with us." We are just a button away. 

[]

Steps on how to add quick view button:

Step #1. Open your code editor

From you Admin page, go to Online store, then Themes. Choose the theme you want to edit, then click the three dots, then Edit code.

Step #2. Create a new section file

In Section folder, create a new section, name it "quick-view", then replace the default code with the code below.

{{ 'quick-view.css' | asset_url | stylesheet_tag }}
<product-viewer>
  <div class="hidden">
    <div id="buttonViewer">
      <div
        class="buttonViewer"
        style="background: {{section.settings.button_background}}; color: {{section.settings.button_font_color}}; font-size: clamp(12px, 1vw, 20px);"
      >
        <span class="desktopbutton">
          <span>{{ section.settings.button_label }}</span>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
            <style type="text/css">
            .st--0{fill:none;}
            .st--1{fill: {{section.settings.button_font_color}};}
            </style>
            <g id="icon-eye">
            <path class="st--0" d="M19.86,8.36c-5.96,0.26-11.2,3.82-15.25,8.02c-1.03,1.11-2,2.31-2.98,3.51c-0.33,0.41-0.31,0.96-0.01,1.42
            c0.21,0.31,0.41,0.63,0.66,0.9c10.1,13.8,25.85,13.6,35.76-0.3C40.34,16.95,24.74,7.44,19.86,8.36z"/>
            <path class="st--1" d="M19.86,8.36c8.91,0.49,17.14,7.75,18.5,12.53c0.05,0.19-0.01,0.47-0.13,0.63
            C28.31,35.31,12.34,35.96,2.27,22.2c-0.24-0.26-0.45-0.58-0.66-0.9c-0.3-0.45-0.32-1.01,0.01-1.42c0.98-1.19,1.95-2.4,2.98-3.51
            C8.65,12.18,13.9,8.62,19.86,8.36z M20.06,11.35c-8.99-0.25-8.86,18.67-0.1,18.52C28.97,30.08,28.9,11.12,20.06,11.35z
            M26.06,29.26c4.06-1.67,7.57-4.94,10.49-8.36c-1.8-3.77-6.61-7.15-10.51-8.97C29.7,17.74,29.68,23.5,26.06,29.26z M13.99,11.95
            c-0.03-0.04-0.03-0.03-0.06-0.07c-3.85,2.02-8.6,5.13-10.43,9.01c2.96,3.35,6.39,6.72,10.52,8.4
            C10.36,23.49,10.37,17.72,13.99,11.95z"/>
            <path class="st--0" d="M20.06,11.35c8.84-0.23,8.91,18.73-0.1,18.52C11.2,30.02,11.07,11.1,20.06,11.35z M21.23,15.55
            c-4.52-2.07-6.82,6.52-3.77,9.19c3.95,4.36,8.16-3.43,6.07-6.51C21.77,20.95,19.51,17.29,21.23,15.55z"/>
            <path class="st--0" d="M26.06,29.26c3.62-5.76,3.64-11.51-0.02-17.34c3.89,1.82,8.7,5.21,10.51,8.97
            C33.64,24.32,30.12,27.58,26.06,29.26z"/>
            <path class="st--0" d="M13.98,11.96c-3.61,5.77-3.62,11.53,0.04,17.33c-4.13-1.68-7.56-5.05-10.52-8.4
            c1.83-3.88,6.57-6.98,10.43-9.01C13.95,11.91,13.96,11.93,13.98,11.96z"/>
            <path class="st--1" d="M21.23,15.55c-1.72,1.75,0.54,5.39,2.3,2.68c2.1,3.09-2.11,10.87-6.07,6.51
            C14.41,22.07,16.71,13.48,21.23,15.55z"/>
            </g>
          </svg></span
        ><span class="mobilebutton">
          <svg viewBox="0 0 40 40" x="121" y="112">
            <use xlink:href="#icon-eye" />
          </svg>
        </span>
      </div>
    </div>
  </div>
  <div class="viewerBackground {% if template == 'page' %} view {% endif %}">
    <div class="productViewContainer color-{{ section.settings.color_scheme }}">
      <div class="quickViewButtonContainer">
        <div class="navigatorWrapper">
          <button
            type="button"
            class="prevNavigator navigatorBtn"
            name="prev"
            style="background: {{section.settings.button_background}}; color: {{section.settings.button_font_color}}"
          >
            PREV
          </button>
          <button
            type="button"
            class="nextNavigator navigatorBtn"
            name="next"
            style="background: {{section.settings.button_background}}; color: {{section.settings.button_font_color}}"
          >
            NEXT
          </button>
          <span class="errorMessage"></span>
        </div>
        <span
          class="productViewerClose"
          style=" stroke: {{section.settings.button_font_color}}; background: {{section.settings.button_background}}"
        >
          {%- render 'icon-close' -%}
        </span>
      </div>
      <div class="productViewer"></div>
    </div>
  </div>
</product-viewer>
<script src="{{ 'product-form.js' | asset_url }}" defer="defer"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
  function o() {
    const o = window.navigator.userAgent;
    const n = o.indexOf("MSIE ");
    const t = o.indexOf("Trident/");
    return n > 0 || t > 0;
  }
  if (!o()) return;
  const n = document.querySelector('#{{ product_form_id }} input[name="id"]');
  const t = document.createElement("div");
  const d =
    document.querySelector(
      'variant-radios[data-section="{{ product.id }}-{{forloop.index0}}"]'
    ) ||
    document.querySelector(
      'variant-selects[data-section="{{ product.id }}-{{forloop.index0}}"]'
    );
  t.innerHTML = document.querySelector(
    ".product-form__noscript-wrapper-{{ product.id }}-{{forloop.index0}}"
  ).textContent;
  d.outerHTML = t.outerHTML;
  document
    .querySelector("#Variants-{{ product.id }}")
    .addEventListener("change", function (o) {
      n.value = o.currentTarget.value;
    });
});
</script>
<script type="application/ld+json">
  {
  "@context": "http://schema.org/",
  "@type": "Product",
  "name": {{ product.title | json }},
  "url": {{ shop.url | append: product.url | json }},
  {% if seo_media -%}
  {%- assign media_size = seo_media.preview_image.width | append: 'x' -%}
  "image": [
  {{ seo_media | img_url: media_size | prepend: "https:" | json }}
  ],
  {%- endif %}
  "description": {{ product.description | strip_html | json }},
  {% if product.selected_or_first_available_variant.sku != blank -%}
  "sku": {{ product.selected_or_first_available_variant.sku | json }},
  {%- endif %}
  "brand": {
  "@type": "Thing",
  "name": {{ product.vendor | json }}
  },
  "offers": [
  {%- for variant in product.variants -%}
  {
  "@type" : "Offer",
  {%- if variant.sku != blank -%}
  "sku": {{ variant.sku | json }},
  {%- endif -%}
  "availability" : "http://schema.org/{% if variant.available %}InStock{% else %}OutOfStock{% endif %}",
  "price" : {{ variant.price | divided_by: 100.00 | json }},
  "priceCurrency" : {{ cart.currency.iso_code | json }},
  "url" : {{ shop.url | append: variant.url | json }}
  }{% unless forloop.last %},{% endunless %}
  {%- endfor -%}
  ]
  }
</script>
{% schema %}
{
  "name": "Quickview",
  "settings": [
    {
      "type": "header",
      "content": "Quickview button style"
    },
    {
      "type": "color",
      "id": "button_background",
      "label": "Button background",
      "default": "#000"
    },
    {
      "type": "color",
      "id": "button_font_color",
      "label": "Button font color",
      "default": "#fff"
    },
    {
      "type": "text",
      "id": "button_label",
      "label": "Button text",
      "default": "QUICKVIEW"
    },
    {
      "type": "header",
      "content": "Pop-up modal style"
    },
    {
      "type": "select",
      "id": "color_scheme",
      "options": [
        {
          "value": "accent-1",
          "label": "Accent 1"
        },
        {
          "value": "accent-2",
          "label": "Accent 2"
        },
        {
          "value": "background-1",
          "label": "Background 1"
        },
        {
          "value": "background-2",
          "label": "Background 2"
        },
        {
          "value": "inverse",
          "label": "Inverse"
        }
      ],
      "default": "background-1",
      "label": "t:sections.all.colors.label"
    }
  ],
  "presets": [
    {
      "name": "Quickview"
    }
  ]
}
{% endschema %}

Step #3. Create another section. 

We need to create another section for our template. We are using Section Rendering API from Shopify. Name this newly created section "quick-view-template." Then paste the code below.

{{ 'section-main-product.css' | asset_url | stylesheet_tag }}
{{ 'section-featured-product.css' | asset_url | stylesheet_tag }}
{{ 'component-price.css' | asset_url | stylesheet_tag }}
{{ 'component-rte.css' | asset_url | stylesheet_tag }}
{{ 'component-loading-overlay.css' | asset_url | stylesheet_tag }}
{{ 'quick-view.css' | asset_url | stylesheet_tag }}
<link rel="stylesheet" href="{{ 'component-deferred-media.css' | asset_url }}" media="print" onload="this.media='all'">
{%- assign first_3d_model = product.media | where: 'media_type', 'model' | first -%}
{%- if first_3d_model -%}
  {{ 'component-product-model.css' | asset_url | stylesheet_tag }}
  <link
    id="ModelViewerStyle"
    rel="stylesheet"
    href="https://cdn.shopify.com/shopifycloud/model-viewer-ui/assets/v1.0/model-viewer-ui.css"
    media="print"
    onload="this.media='all'"
  >
  <link
    id="ModelViewerOverride"
    rel="stylesheet"
    href="{{ 'component-model-viewer-ui.css' | asset_url }}"
    media="print"
    onload="this.media='all'"
  >
{%- endif -%}
<section>
  <div class="section-{{ section.id }}-padding">
    <div class="featured-product product grid grid--1-col gradient color-{{ section.settings.color_scheme }}{% if section.settings.secondary_background == false %} isolate{% endif %} {% if product.media.size > 0 %}grid--2-col-tablet{% else %}product--no-media{% endif %}">
      <div class="grid__item product__media-wrapper">
        {% if product %}
          <slider-quick-view>
            <ul class="largeImage">
              {%- for media in product.media -%}
                <li
                  class="
                    large-image-item product__media-item grid__item slider__slide {% if forloop.first %} is-active {% endif %}
                    {% if media.media_type != 'image' %} hide-modal {% endif %}
                  "
                  data-media-id="{{ media.id }}"
                >
                  {% render 'product-thumbnail',
                    media: media,
                    position: forloop.index,
                    loop: true,
                    modal_id: product.id,
                    xr_button: true
                  %}
                </li>
              {%- endfor -%}
            </ul>
            <div class="slider-wrapper">
              <button
                type="button"
                class="slider-button slider-button--prev bigger-slider {% if product.media.size <= 4 %}hidden{% endif %}"
                name="previous"
                aria-label="{{ 'accessibility.previous_slide' | t }}"
              >
                {% render 'icon-caret' %}
              </button>
              <ul class="product-slider-box slider" role="list">
                {%- assign variant_images = product.images | where: 'attached_to_variant?', true | map: 'src' -%}
                {%- for media in product.media -%}
                  <li class="product-slider slider__slide" data-thumb-id="{{ media.id }}">
                    {% if media.media_type == 'video' %}
                      <div class="video-btn" style="display: block">
                        <span class="product__media-icon motion-reduce v-btn" aria-hidden="true">
                          {%- liquid
                            case media.media_type
                              when 'video', 'external_video'
                                render 'icon-play'
                              when 'model'
                                render 'icon-3d-model'
                              else
                                render 'icon-zoom'
                            endcase
                          -%}
                        </span>
                        <img
                          class="slide-image {% if forloop.first %}active-thumb {% endif %}"
                          src="{{ media.preview_image | img_url: 'large' }}"
                          alt="{{ media.alt}}"
                          style="aspect-ratio: 1;"
                        >
                      </div>
                    {% else %}
                      <img
                        class="slide-image {% if forloop.first %}active-thumb {% endif %}"
                        src="{{ media.preview_image | img_url: 'large' }}"
                        alt="{{ media.alt }}"
                        style="aspect-ratio: 1;"
                      >
                    {% endif %}
                  </li>
                {% endfor %}
              </ul>
              <button
                type="button"
                class="slider-button slider-button--next bigger-slider {% if product.media.size <= 4 %}hidden{% endif %}"
                name="next"
                aria-label="{{ 'accessibility.next_slide' | t }}"
              >
                {% render 'icon-caret' %}
              </button>
            </div>
          </slider-quick-view>
        {% endif %}
      </div>
      <div class="product__info-wrapper grid__item">
        <div id="ProductInfo-{{ section.id }}" class="product__info-container">
          {%- assign product_form_id = 'product-form-' | append: section.id -%}
 
          <h2 class="h2 product__title" {{ section.shopify_attributes }}>
            {%- if product.title != blank -%}
              {{ product.title | escape }}
            {%- else -%}
              {{ 'onboarding.product_title' | t }}
            {%- endif -%}
          </h2>
          <div class="no-js-hidden" id="price-{{ section.id }}" role="status" {{ block.shopify_attributes }}>
            {%- render 'price', product: product, use_variant: true, show_badges: true, price_class: 'price--large' -%}
          </div>
          {%- if shop.taxes_included or shop.shipping_policy.body != blank -%}
            <div class="product__tax caption rte">
              {%- if shop.taxes_included -%}
                {{ 'products.product.include_taxes' | t }}
              {%- endif -%}
              {%- if shop.shipping_policy.body != blank -%}
                {{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
              {%- endif -%}
            </div>
          {%- endif -%}
          {%- if product != blank -%}
            <div {{ block.shopify_attributes }}>
              {%- form 'product', product -%}
                <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
                {{ form | payment_terms }}
              {%- endform -%}
            </div>
          {%- endif -%}
          <div
            class="product-form__input product-form__quantity{% if settings.inputs_shadow_vertical_offset != 0 and settings.inputs_shadow_vertical_offset < 0 %} product-form__quantity-top{% endif %}"
            {{ block.shopify_attributes }}
          >
            <label class="form__label" for="Quantity-{{ section.id }}">
              {{ 'products.product.quantity.label' | t }}
            </label>
            <quantity-input class="quantity">
              <button class="quantity__button no-js-hidden" name="minus" type="button">
                <span class="visually-hidden">
                  {{- 'products.product.quantity.decrease' | t: product: product.title | escape -}}
                </span>
                {% render 'icon-minus' %}
              </button>
              <input
                class="quantity__input"
                type="number"
                name="quantity"
                id="Quantity-{{ section.id }}"
                min="1"
                value="1"
                form="{{ product_form_id }}"
              >
              <button class="quantity__button no-js-hidden" name="plus" type="button">
                <span class="visually-hidden">
                  {{- 'products.product.quantity.increase' | t: product: product.title | escape -}}
                </span>
                {% render 'icon-plus' %}
              </button>
            </quantity-input>
          </div>
          <variant-viewer
            class="no-js-hidden"
            data-section="{{ section.id }}"
            data-url="{{ product.url }}"
            data-update-url="false"
            {{ block.shopify_attributes }}
          >
            {%- for option in product.options_with_values -%}
              <div class="product-form__input product-form__input--dropdown">
                <label class="form__label" for="Option-{{ section.id }}-{{ forloop.index0 }}">
                  {{ option.name }}
                </label>
                <div class="select">
                  <select
                    id="Option-{{ section.id }}-{{ forloop.index0 }}"
                    class="select__select"
                    name="options[{{ option.name | escape }}]"
                    form="{{ product_form_id }}"
                  >
                    {%- for value in option.values -%}
                      <option
                        value="{{ value | escape }}"
                        {% if option.selected_value == value %}
                          selected="selected"
                        {% endif %}
                      >
                        {{ value }}
                      </option>
                    {%- endfor -%}
                  </select>
                  {% render 'icon-caret' %}
                </div>
              </div>
            {%- endfor -%}
            <script type="application/json">
              {{ product.variants | json }}
            </script>
          </variant-viewer>
          <noscript class="product-form__noscript-wrapper-{{ section.id }}">
            <div class="product-form__input{% if product.has_only_default_variant %} hidden{% endif %}">
              <label class="form__label" for="Variants-{{ section.id }}">
                {{- 'products.product.product_variants' | t -}}
              </label>
              <div class="select">
                <select name="id" id="Variants-{{ section.id }}" class="select__select" form="{{ product_form_id }}">
                  {%- for variant in product.variants -%}
                    <option
                      {% if variant == product.selected_or_first_available_variant %}
                        selected="selected"
                      {% endif %}
                      {% if variant.available == false %}
                        disabled
                      {% endif %}
                      value="{{ variant.id }}"
                    >
                      {{ variant.title }}
                      {%- if variant.available == false %} - {{ 'products.product.sold_out' | t }}{% endif %}
                      - {{ variant.price | money | strip_html }}
                    </option>
                  {%- endfor -%}
                </select>
                {% render 'icon-caret' %}
              </div>
            </div>
          </noscript>
          <div {{ block.shopify_attributes }}>
            {%- if product != blank -%}
              <product-form class="product-form">
                <div class="product-form__error-message-wrapper" role="alert" hidden>
                  <svg
                    aria-hidden="true"
                    focusable="false"
                    role="presentation"
                    class="icon icon-error"
                    viewBox="0 0 13 13"
                  >
                    <circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"/>
                    <circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"/>
                    <path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"/>
                    <path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7"/>
                  </svg>
                  <span class="product-form__error-message"></span>
                </div>
                {%- form 'product',
                  product,
                  id: product_form_id,
                  class: 'form',
                  novalidate: 'novalidate',
                  data-type: 'add-to-cart-form'
                -%}
                  <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}" disabled>
                  <div class="product-form__buttons">
                    <button
                      type="submit"
                      name="add"
                      class="product-form__submit button button--full-width {% if section.settings.show_dynamic_checkout and product.selling_plan_groups == empty %}button--secondary{% else %}button--primary{% endif %}"
                      {% if product.selected_or_first_available_variant.available == false %}
                        disabled
                      {% endif %}
                    >
                      <span>
                        {%- if product.selected_or_first_available_variant.available -%}
                          {{ 'products.product.add_to_cart' | t }}
                        {%- else -%}
                          {{ 'products.product.sold_out' | t }}
                        {%- endif -%}
                      </span>
                      <div class="loading-overlay__spinner hidden">
                        <svg
                          aria-hidden="true"
                          focusable="false"
                          role="presentation"
                          class="spinner"
                          viewBox="0 0 66 66"
                          xmlns="http://www.w3.org/2000/svg"
                        >
                          <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle>
                        </svg>
                      </div>
                    </button>
                    {%- if section.settings.show_dynamic_checkout -%}
                      {{ form | payment_button }}
                    {%- endif -%}
                  </div>
                {%- endform -%}
              </product-form>
            {%- else -%}
              <div class="product-form">
                <div class="product-form__buttons form">
                  <button
                    type="submit"
                    name="add"
                    class="product-form__submit button button--full-width button--primary"
                    disabled
                  >
                    {{ 'products.product.sold_out' | t }}
                  </button>
                </div>
              </div>
            {%- endif -%}
          </div>
 
          {%- if product.metafields.reviews.rating.value != blank -%}
            {% liquid
              assign rating_decimal = 0
              assign decimal = product.metafields.reviews.rating.value.rating | modulo: 1
              if decimal >= 0.3 and decimal <= 0.7
                assign rating_decimal = 0.5
              elsif decimal > 0.7
                assign rating_decimal = 1
              endif
            %}
            <div
              class="rating"
              role="img"
              aria-label="{{ 'accessibility.star_reviews_info' | t: rating_value: product.metafields.reviews.rating.value, rating_max: product.metafields.reviews.rating.value.scale_max }}"
            >
              <span
                aria-hidden="true"
                class="rating-star color-icon-{{ settings.accent_icons }}"
                style="--rating: {{ product.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ product.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"
              ></span>
            </div>
            <p class="rating-text caption">
              <span aria-hidden="true">
                {{- product.metafields.reviews.rating.value }} /
                {{ product.metafields.reviews.rating.value.scale_max -}}
              </span>
            </p>
            <p class="rating-count caption">
              <span aria-hidden="true">({{ product.metafields.reviews.rating_count }})</span>
              <span class="visually-hidden">
                {{- product.metafields.reviews.rating_count }}
                {{ 'accessibility.total_reviews' | t -}}
              </span>
            </p>
          {%- endif -%}
 
          <a href="{{ product.url }}" class="link product__view-details animate-arrow">
            {{ 'products.product.view_full_details' | t }}
            {% render 'icon-arrow' %}
          </a>
        </div>
      </div>
    </div>
    <product-modal id="ProductModal-{{ section.id }}" class="product-media-modal media-modal">
      <div
        class="product-media-modal__dialog"
        role="dialog"
        aria-label="{{ 'products.modal.label' | t }}"
        aria-modal="true"
        tabindex="-1"
      >
        <button
          id="ModalClose-{{ section.id }}"
          type="button"
          class="product-media-modal__toggle"
          aria-label="{{ 'accessibility.close' | t }}"
        >
          {% render 'icon-close' %}
        </button>
 
        <div
          class="product-media-modal__content"
          role="document"
          aria-label="{{ 'products.modal.label' | t }}"
          tabindex="0"
        >
          {%- liquid
            if product.selected_or_first_available_variant.featured_media != null
              assign media = product.selected_or_first_available_variant.featured_media
              render 'product-media', media: media, loop: section.settings.enable_video_looping, variant_image: section.settings.hide_variants
            endif
          -%}
 
          {%- for media in product.media -%}
            {%- liquid
              if section.settings.hide_variants and media_to_render contains media.id
                assign variant_image = true
              else
                assign variant_image = false
              endif
              unless media.id == product.selected_or_first_available_variant.featured_media.id
                render 'product-media', media: media, loop: section.settings.enable_video_looping, variant_image: variant_image
              endunless
            -%}
          {%- endfor -%}
        </div>
      </div>
    </product-modal>
  </div>
</section>
{% javascript %}
if (!customElements.get("product-modal")) {
  customElements.define(
    "product-modal",
    class t extends ModalDialog {
      constructor() {
        super();
      }
      hide() {
        super.hide();
      }
      show(t) {
        super.show(t);
        this.t();
      }
      t() {
        this.querySelectorAll(
          `[data-media-id]:not([data-media-id="${this.i.getAttribute(
            "data-media-id"
          )}"])`
        ).forEach((t) => {
          t.classList.remove("active");
        });
        const t = this.querySelector(
          `[data-media-id="${this.i.getAttribute("data-media-id")}"]`
        );
        const a = t.querySelector("template");
        const d = a ? a.content : null;
        t.classList.add("active");
        t.scrollIntoView();
        const e = this.querySelector('[role="document"]');
        e.scrollLeft = (t.width - e.clientWidth) / 2;
        if (
          t.nodeName == "DEFERRED-MEDIA" &&
          d &&
          d.querySelector(".js-youtube")
        )
          t.o();
      }
    }
  );
}
{% endjavascript %}
<script src="{{ 'product-form.js' | asset_url }}" defer="defer"></script>
{%- if first_3d_model -%}
  <script type="application/json" id="ProductJSON-{{ product.id }}">
    {{ product.media | where: 'media_type', 'model' | json }}
  </script>
  <script src="{{ 'product-model.js' | asset_url }}" defer></script>
{%- endif -%}
{%- liquid
  if product.selected_or_first_available_variant.featured_media
    assign seo_media = product.selected_or_first_available_variant.featured_media
  else
    assign seo_media = product.featured_media
  endif
-%}
<script type="application/ld+json">
  {
  "@context": "http://schema.org/",
  "@type": "Product",
  "name": {{ product.title | json }},
  "url": {{ shop.url | append: product.url | json }},
  {% if seo_media -%}
  {%- assign media_size = seo_media.preview_image.width | append: 'x' -%}
  "image": [
  {{ seo_media | img_url: media_size | prepend: "https:" | json }}
  ],
  {%- endif %}
  "description": {{ product.description | strip_html | json }},
  {% if product.selected_or_first_available_variant.sku != blank -%}
  "sku": {{ product.selected_or_first_available_variant.sku | json }},
  {%- endif %}
  "brand": {
  "@type": "Thing",
  "name": {{ product.vendor | json }}
  },
  "offers": [
  {%- for variant in product.variants -%}
  {
  "@type" : "Offer",
  {%- if variant.sku != blank -%}
  "sku": {{ variant.sku | json }},
  {%- endif -%}
  "availability" : "http://schema.org/{% if variant.available %}InStock{% else %}OutOfStock{% endif %}",
  "price" : {{ variant.price | divided_by: 100.00 | json }},
  "priceCurrency" : {{ cart.currency.iso_code | json }},
  "url" : {{ shop.url | append: variant.url | json }}
  }{% unless forloop.last %},{% endunless %}
  {%- endfor -%}
  ]
  }
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
  function n() {
    const n = window.navigator.userAgent;
    const t = n.indexOf("MSIE ");
    const o = n.indexOf("Trident/");
    return t > 0 || o > 0;
  }
  if (!n()) return;
  const t = document.querySelector('#{{ product_form_id }} input[name="id"]');
  const o = document.createElement("div");
  const c =
    document.querySelector('variant-radios[data-section="{{ section.id }}"]') ||
    document.querySelector('variant-selects[data-section="{{ section.id }}"]');
  o.innerHTML = document.querySelector(
    ".product-form__noscript-wrapper-{{ section.id }}"
  ).textContent;
  c.outerHTML = o.outerHTML;
  document
    .querySelector("#Variants-{{ section.id }}")
    .addEventListener("change", function (n) {
      t.value = n.currentTarget.value;
    });
});
</script>
{% if product.media.size > 0 %}
<script src="{{ 'media-gallery.js' | asset_url }}" defer="defer"></script>
{% endif %}
{% schema %}
{
  "name": "Quick view template",
  "tag": "section",
  "class": "section section-featured-product",
  "settings": [
    {
      "type": "header",
      "content": "t:sections.featured-product.settings.header.content",
      "info": "t:sections.featured-product.settings.header.info"
    },
    {
      "type": "checkbox",
      "id": "hide_variants",
      "default": false,
      "label": "t:sections.main-product.settings.hide_variants.label"
    },
    {
      "type": "checkbox",
      "id": "show_dynamic_checkout",
      "default": true,
      "label": "t:sections.featured-product.blocks.buy_buttons.settings.show_dynamic_checkout.label",
      "info": "t:sections.featured-product.blocks.buy_buttons.settings.show_dynamic_checkout.info"
    },
    {
      "type": "text",
      "id": "share_label",
      "label": "t:sections.featured-product.blocks.share.settings.text.label",
      "default": "Share"
    }
  ],
  "presets": [
    {
      "name": "Quick view template"
    }
  ]
}
{% endschema %}

 

Step #4. Create a new CSS file.

Next, find the Asset folder, and create a new CSS file. Name it "quick-view." Then open the newly created file and paste the code below.

.card-wrapper {
  position: relative;
}
.card-wrapper:hover .buttonViewer {
  display: flex;
}
.buttonViewer {
  width: 80%;
  max-height: 4rem;
  height: max-content;
  top: 33%;
  margin: auto;
  left: 0;
  right: 0;
  position: absolute;
  z-index: 4;
  display: none;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  border-radius: 5px;
  padding: 3px;
}
.buttonViewer:hover {
  transform: scale(1.1);
}
.desktopbutton {
  display: flex;
  align-items: center;
}
.buttonViewer svg {
  max-width: 30px;
  width: 90%;
  margin: auto;
  aspect-ratio: 1;
}
.mobilebutton {
  display: none;
}
.productViewContainer {
  position: absolute;
  height: 65%;
  width: 60%;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  border-radius: 5px;
}
.productViewerClose {
  width: 30px;
  padding: 5px;
  border-radius: 3px;
  height: max-content;
  top: 15px;
  position: sticky;
  z-index: 1;
  display: flex;
  align-self: flex-end;
  transition: transform 0.2s ease;
}
.productViewerClose:hover {
  transform: scale(1.1);
}
.productViewerClose > svg {
  stroke-width: 1px;
}
.viewerBackground {
  position: fixed;
  width: 100vw;
  height: 100vh;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  z-index: 6;
  display: none;
}
.productViewer {
  display: flex;
  width: 100%;
  padding: 0% 5%;
}
.productViewer > section {
  width: 100%;
}
.productViewer .product__media-wrapper {
  width: 35%;
  height: max-content;
}
.productViewer .product__info-wrapper {
  padding: 0 !important;
  max-width: 65% !important;
}
.productViewer .featured-product {
  gap: 5% !important;
}
.largeImage {
  width: 70%;
  margin: auto;
}
.slider-wrapper img {
  width: 100%;
}
.productViewer:not(.product--no-media) > .product__info-wrapper {
  padding: 0 0 0 5% !important;
}
.cart__warnings a:after {
  z-index: 0;
}
.productViewContainer .is-active {
  padding: 0 !important;
  display: block !important;
}
.productViewContainer .product__media-item:not(.is-active) {
  display: none;
}
.productViewContainer .thumbnail-slider {
  display: flex !important;
}
.productViewContainer .thumbnail-list {
  margin: auto !important;
}
.productViewContainer
  .thumbnail-list.slider--tablet-up
  .thumbnail-list__item.slider__slide {
  width: calc(35% - 0.8rem) !important;
  aspect-ratio: 1;
}
.productViewContainer .slider-button {
  align-self: center;
  width: 25px;
}
.slider-button > .iconArrow {
  fill: black;
}
.slider-button[disabled] > .iconArrow {
  fill: rgba(var(--color-foreground), 0.3);
  cursor: not-allowed;
}
.quick-view-modal {
  display: flex !important;
}
.fixed {
  overflow: hidden !important;
}
@media only screen and (max-width: 750px) {
  .productViewContainer {
    width: 100%;
  }
}
@media only screen and (max-width: 481px) {
  .productViewer .featured-product {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
  }
  .productViewer .product__media-wrapper {
    width: 100% !important;
    margin: auto;
    max-width: 25rem;
  }
  .productViewer .product__info-wrapper {
    width: 100% !important;
    max-width: 100% !important;
  }
  .productViewer:not(.product--no-media) > .product__info-wrapper {
    padding: 0 !important;
  }
  .mobilebutton {
    display: flex;
  }
  .desktopbutton {
    display: none;
  }
  .desktopbutton > span {
    width: 100%;
    font-size: clamp(12px, 2vw, 20px);
  }
  .buttonViewer {
    width: 20%;
    height: 3rem;
    top: 5%;
    left: 75%;
    display: flex;
  }
}
.slider-container {
  margin: 0 auto;
  width: 90%;
  display: flex;
  flex-flow: column wrap;
  align-items: center;
  position: relative;
}
.large-image {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}
.large-image-item {
  max-width: 100%;
  width: 100%;
  max-height: 100%;
  padding: 0;
  position: relative;
  margin: 0 auto;
}
.xoomImage {
  position: absolute;
  top: 0;
  left: 0;
}
.large-image-item:not(:first-child) {
  display: none !important;
}
ul {
  padding-inline-start: 0px !important;
}
slider-component {
  position: relative;
  display: block;
  width: 100%;
}
.slider-wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
  margin-top: 1rem;
}
.slider__slide {
  scroll-snap-align: start;
  flex-shrink: 0;
}
.product-slider-box {
  flex-wrap: inherit;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  width: 100%;
  display: flex;
  z-index: 1;
  margin: 0 !important;
}
.product-slider {
  height: 100%;
  width: 25%;
  padding: 5px;
  display: inline-block;
}
.slide-image {
  width: 100%;
  object-fit: cover;
}
.slider {
  scrollbar-color: rgb(var(--color-foreground))
    rgba(var(--color-foreground), 0.04);
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.slider::-webkit-scrollbar {
  height: 0.4rem;
  width: 0.4rem;
  display: none;
}
.no-js .slider {
  -ms-overflow-style: auto;
  scrollbar-width: auto;
}
.no-js .slider::-webkit-scrollbar {
  display: initial;
}
.slider::-webkit-scrollbar-thumb {
  background-color: rgb(var(--color-foreground));
  border-radius: 0.4rem;
  border: 0;
}
.slider::-webkit-scrollbar-track {
  background: rgba(var(--color-foreground), 0.04);
  border-radius: 0.4rem;
}
.button-wrapper {
  height: 100%;
  width: 105%;
  position: absolute;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.slider-container::-webkit-scrollbar {
  display: none;
}
.slider-buttons {
  display: flex;
  align-items: center;
  justify-content: center;
}
.slider-button {
  color: rgba(var(--color-foreground), 0.75);
  background: transparent;
  border: none;
  cursor: pointer;
  width: 44px;
  height: 44px;
}
.slider-button:not([disabled]):hover {
  color: rgb(var(--color-foreground));
}
.slider-button .icon {
  height: 1.2rem;
}
.slider-button[disabled] .icon {
  color: rgba(var(--color-foreground), 0.3);
}
.slider-button--next .icon {
  margin-right: -0.2rem;
  transform: rotate(-90deg) translateX(0.15rem);
}
.slider-button--prev .icon {
  margin-left: -0.2rem;
  transform: rotate(90deg) translateX(-0.15rem);
}
.slider-button--next:not([disabled]):hover .icon {
  transform: rotate(-90deg) translateX(0.15rem) scale(1.07);
}
.slider-button--prev:not([disabled]):hover .icon {
  transform: rotate(90deg) translateX(-0.15rem) scale(1.07);
}
.video-btn {
  width: 100%;
  height: 100%;
  position: relative;
}
.v-btn {
  top: 2% !important;
  left: 2% !important;
}
.active-thumb {
  border: 3px solid white;
  outline: 2px solid black;
}
@media screen and (min-width: 750px) {
  .custom-width {
    padding: 0 10% !important;
  }
}
@media screen and (min-width: 990px) {
  .product__media-wrapper {
    max-width: 50% !important;
    width: calc(50% - 1rem / 2);
  }
  .product__info-wrapper {
    padding-left: 5rem !important;
    max-width: 50% !important;
    width: calc(50% - 1rem / 2);
  }
}
.quickViewButtonContainer {
  top: 5px;
  margin: 1rem;
  display: flex;
  justify-content: space-between;
  position: sticky;
  z-index: 2;
}
.errorMessage {
  margin-left: 5px;
  font-weight: 600;
}
.navigatorBtn {
  border-radius: 3px;
  height: 100%;
  padding: 1px 3px;
  margin-left: 5px;
}
.navigatorBtn:hover {
  background: red;
}
.navigatorBtn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
.productViewer .product__media-icon {
  display: none !important;
}
.video-btn .product__media-icon {
  display: flex !important;
}
.productViewer .product__media-toggle:hover {
  cursor: pointer !important;
}
.productViewer .slider-button > svg {
  stroke-width: 1px;
  height: 1.2rem !important;
}
 

 

Step #5. Open global.js file

Next, open the global.js file under the same folder, Asset and add the code below. 

class SliderQuickView extends HTMLElement {
  constructor() {
    super();
    this.t = this.querySelector(".slider");
    this.i = this.querySelectorAll(".product-slider");
    this.pageCount = this.querySelector(".slider-counter--current");
    this.h = this.querySelector(".slider-counter--total");
    this.u = this.querySelector('button[name="previous"]');
    this.l = this.querySelector('button[name="next"]');
    if (!this.t || !this.l) return;
    const t = new ResizeObserver((t) => this.o());
    t.observe(this.t);
    this.t.addEventListener("scroll", this.update.bind(this));
    this.u.addEventListener("click", this.m.bind(this));
    this.l.addEventListener("click", this.m.bind(this));
    this.i.forEach((t) => t.addEventListener("click", this.v.bind(this)));
  }
  o() {
    const t = Array.from(this.i).filter((t) => t.clientWidth > 0);
    this.p = t[t.length - 1];
    if (t.length === 0) return;
    this.k = Math.floor(this.t.clientWidth / t[0].clientWidth);
    this.g = t.length - this.k + 1;
    this.update();
  }
  update() {
    if (!this.pageCount || !this.h) return;
    this.currentPage = Math.round(this.t.scrollLeft / this.p.clientWidth) + 1;
    if (this.currentPage === 1) {
      this.u.setAttribute("disabled", true);
    } else {
      this.u.removeAttribute("disabled");
    }
    if (this.currentPage === this.g) {
      this.l.setAttribute("disabled", true);
    } else {
      this.l.removeAttribute("disabled");
    }
    this.pageCount.textContent = this.currentPage;
    this.h.textContent = this.g;
  }
  m(t) {
    t.preventDefault();
    const i =
      t.currentTarget.name === "next"
        ? this.t.scrollLeft + this.t.clientWidth
        : this.t.scrollLeft - this.t.clientWidth;
    this.t.scrollTo({ left: Math.floor(i) });
    this.M = Math.round(i / this.t.clientWidth);
    if (this.M === 0) {
      this.u.setAttribute("disabled", true);
    } else {
      this.u.removeAttribute("disabled");
    }
    if (this.M === this.g / 3) {
      this.l.setAttribute("disabled", true);
    } else {
      this.l.removeAttribute("disabled");
    }
  }
  v(t) {
    this.V = t.currentTarget.dataset.P;
    this.q(this.V);
    this.T(this.V);
  }
  q(t) {
    this.$ = this.querySelector(`[data-media-id="${t}"]`);
    this.B = this.$.parentElement;
    this.B.prepend(this.$);
    this.$.style.display = "block";
  }
  T(t) {
    this.C = this.querySelector(`[data-thumb-id='${t}']`);
    this.i.forEach((t) =>
      t.querySelector("img").classList.remove("active-thumb")
    );
    this.C.scrollIntoView({ H: "nearest", L: "center" });
    this.C.querySelector("img").classList.add("active-thumb");
  }
}
customElements.define("slider-quick-view", SliderQuickView);
class ButtonViewer extends HTMLElement {
  constructor() {
    super();
    this.O = document.querySelector("product-viewer");
    this.D();
    this.addEventListener("click", this.I.bind(this));
    this.N;
    this.U;
    this.buttons = document.querySelectorAll("button-viewer");
    this.A;
  }
  D() {
    this.closest("ul")
      .querySelectorAll("button-viewer")
      .forEach((t, i) => {
        t.setAttribute("data-view-index", i);
      });
    this.A = this.closest("ul").querySelectorAll("button-viewer").length;
    this.innerHTML = this.O.querySelector("#buttonViewer").innerHTML;
    this.insertAdjacentHTML("afterbegin", this.R(this.innerHTML));
  }
  R(t) {
    return new DOMParser().parseFromString(t, "text/html").querySelector("body")
      .innerHTML;
  }
  I(t) {
    this.S = t.currentTarget.dataset.product;
    this.O._(this.S);
    this.j = t.currentTarget.dataset.F;
    this.O.G(this.closest("ul"), this.j, this.A);
  }
}
customElements.define("button-viewer", ButtonViewer);
class ProductViewer extends HTMLElement {
  constructor() {
    super();
    this.J = this.querySelector(".viewerBackground");
    this.O = this.querySelector(".productViewer");
    this.K = this.querySelector(".productViewerClose");
    this.K.addEventListener("click", this.W.bind(this));
    this.u = this.querySelector(".prevNavigator");
    this.l = this.querySelector(".nextNavigator");
    this.X = this.querySelector(".errorMessage");
    this.u.addEventListener("click", this.m.bind(this));
    this.l.addEventListener("click", this.m.bind(this));
    this.Y = new Event("change", { bubbles: true });
    this.current;
    this.parent;
    this.A;
  }
  _(t) {
    this.Z(t);
    document.body.classList.toggle("fixed");
    this.J.classList.toggle("quick-view-modal");
  }
  Z(t) {
    fetch(`/products/${t}?section_id=quick-view-template`)
      .then((t) => t.text())
      .then((t) => {
        this.tt = this.R(t);
        this.O.innerHTML = this.tt;
      });
  }
  R(t) {
    return new DOMParser().parseFromString(t, "text/html").querySelector("body")
      .innerHTML;
  }
  W() {
    this.J.classList.toggle("quick-view-modal");
    document.body.classList.toggle("fixed");
  }
  m(t) {
    t.preventDefault();
    t.target.getAttribute("name") == "next"
      ? (this.current = this.current + 1)
      : (this.current = this.current - 1);
    if (this.current == 0) {
      this.it = "This is the first product.";
      this.u.disabled = true;
    } else if (this.current == this.A) {
      this.it = "This is the last product.";
      this.l.disabled = true;
    } else {
      this.it = " ";
      this.u.disabled = false;
      this.l.disabled = false;
    }
    this.X.innerHTML = this.it;
    this.st = this.parent.querySelector(`[data-view-index='${this.current}']`);
    if (!this.st) return;
    this.Z(this.st.dataset.product);
  }
  G(t, i, s) {
    this.parent = t;
    this.current = i * 1;
    this.A = s - 1;
  }
}
customElements.define("product-viewer", ProductViewer);
class VariantViewer extends VariantSelects {
  constructor() {
    super();
    this.O = document.querySelector("slider-quick-view");
  }
  ht() {
    if (!this.et) return;
    if (!this.et.rt) return;
    this.ct = this.et.rt.id;
    this.O.q(this.ct);
    this.O.T(this.ct);
  }
}
customElements.define("variant-viewer", VariantViewer);

Step #6. Call quick-view. 

We need to call this quick-view in the product card. Go to Snippet folder, if you have Dawn Theme version 2.5 above, open the card-product.liquid. Find the class "card-wrapper", then paste the code, after the line.

<button-viewer class="quickViewBtn" data-product="{{card_product.handle}}" ></button-viewer>

For Dawn Theme 2.5 and lower, follow same instruction above but paste the code below instead. 

<button-viewer class="quickViewBtn" data-product="{{product_card_product.handle}}" ></button-viewer>

Step #7. Go to theme.liquid

Last thing, go to the theme.liquid folder on top. Then find the  {% section 'announcement-bar' %},  paste the code above it. 

{% section 'quick-view' %}

 

Step #8. Save the changes

Once you've added the code, save your changes to the theme code by clicking the SAVE button on the right hand upper corner.

 

Step #9. Customize theme

Go to the theme editor by clicking three dots on your left hand upper corner, then Customize theme. Make sure to SAVE once you are done customizing

Conclusion

Adding a quick view button to your Dawn theme can be a valuable way to enhance the user experience and potentially boost sales within your Shopify store. By providing a convenient method for customers to explore product details without navigating away from the current page, quick view functionality can keep them engaged and informed throughout their shopping journey.

The article likely provides specific instructions for adding a quick view button using the Dawn theme, either through a recommended app or by manual code edits. Remember to consider factors like mobile-friendliness, content optimization, and loading speed to ensure the quick view experience is seamless and efficient. By implementing a well-designed and user-friendly quick view button, you can encourage customers to learn more about your products and ultimately drive sales within your store.

0 comments

Leave a comment