SeedlogicSeedlogic

Shopify

How to Create A Shopify Theme with TailwindCSS in 2021

Date Published: 6/3/2021

hero image

Last Updated: 8/25/2021

Shopify has plenty of pre-built themes but in some cases where you want to start from scratch, we recommend using a robust css framework to make designing and building easier.

What is TailwindCSS?

Tailwind describes themselves as a "utility-first CSS framework". You can read more on their approach to development and design here.

As someone who was an avid Bootstrap 3 and 4 fan, I made the switch to Tailwind after seeing their abstracted and robust class system. Tailwind gives you more tools to build the site you want without having to write custom styles.

A few small examples are while Bootstrap only has padding sizes from 1 through 5, Tailwind has 1 through 96. Headings are default unstyled giving the user more customization abilities. Also, just about every class has a state, such as hover and focus, so you can create a more dynamic page without creating a single custom class.

Even in these few examples you can see how Bootstrap is left in the dust.

How To Create a Shopify Theme

Tailwind + Shopify themeing are a perfect match. You can focus on building the best experience for your product and service without having to worry about a long list of custom styles.

Getting Started With Themekit

#1 Install Themekit

The first thing you'll need to do to create a Shopify theme is to install Theme Kit. Themekit is available on macOS, Windows and Linux operating systems.

Linux:

Use the following installation script to automatically download and install the latest version of Theme Kit:

curl -s https://shopify.dev/themekit.py | sudo python

Use Homebrew to install Theme Kit by running the following commands:

$ brew tap shopify/shopify
$ brew install themekit

According to Shopify the Apple M1 architecture is not yet natively supported, but Theme Kit will work if you start the terminal with the Open using Rosetta option.

Windows

Install Theme Kit with Chocolatey by running the following command:

$ choco install themekit

#2 Generate API Credentials

When Theme Kit is installed you will need to create Shopify API credentials in order to connect to your store. You have the options of using a private app or using the Theme Kit Access app.

How to create a private app

1) From your Shop's Admin, click on Apps, then Manage private apps.

Screen Shot 2021-06-03 at 10.18.33 AM

2) Then click on Create new private app.

Screen Shot 2021-06-03 at 10.19.27 AM

3) You'll be presented with a screen asking for API permissions. Find Themes and select Read and write permissions.

Screen Shot 2021-06-03 at 10.20.35 AM

4) Click Save and then you'll be able to see your API credentials. Copy and save your API password to be used later.

Screen Shot 2021-06-03 at 10.32.46 AM

#3 Setup Theme Folder

In order to create your new theme you'll need to place it somewhere. In your terminal, create a directory for your new theme:

$ mkdir some/folder/name

Then navigate to inside that folder:

$ cd some/folder/name

#4 Create Config File and Initiate New Theme

Once you are inside of that folder you'll need to run the below command to initiate a config file and to automatically build out the Shopify folder scaffold for your new theme. To get your API password, you'll need to paste your API password that you saved from the above step #2.

$ theme new --password=[your-api-password] --store=[your-store.myshopify.com] --name=[theme name]

Add Tailwind to New Theme

Inside the root of your new theme's directory run the following command. I'm using Yarn package manager but you can also use NPM.

$ yarn add tailwindcss @tailwindcss/forms @tailwindcss/typography autoprefixer postcss

This command does a few things:

  • It installs Tailwind, Tailwind's forms which you'll more than likely use on a Product page template as well as Tailwind's Typography which allows you to use the Prose class.

  • It also installs necessary dependancies Autoprefixer and PostCSS

Next we'll need create a tailwind.config.js file. Run this command:

$ npx tailwindcss init

Inside of your new tailwind.config.js file paste the following:

module.exports = {
  purge: {
    enabled: true,
    content: [
      './layout/*.liquid',
      './templates/*.liquid',
      './sections/*.liquid',
      './snippets/*.liquid'
    ]
  },
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {}
  },
  variants: {
    extend: {}
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography')
  ]
}

Create a new folder at the root director called css and then create a new file called application.css. In that new file, paste the following:

/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */
@tailwind utilities;

After you've updated this file, run the following command:

$ npx tailwindcss build css/application.css -o assets/application.css.liquid

If you open the file assets/application.css.liquid you should now see all of the tailwind styles 🎉!

Finally, open your package.json file add the following

"scripts": {
    "build": "npx tailwindcss build css/application.css -o assets/application.css.liquid && theme deploy --allow-live"
  }

The your final file should look like this:

{
  "scripts": {
    "build": "npx tailwindcss build css/application.css -o assets/application.css.liquid && theme deploy --allow-live"
  },
  "dependencies": {
    "@tailwindcss/forms": "^0.3.3",
    "@tailwindcss/typography": "^0.4.1",
    "autoprefixer": "^10.3.2",
    "postcss": "^8.3.6",
    "tailwindcss": "^2.2.7"
  }
}

*Important Note*

Whenever you add a new Tailwind class anywhere in your theme, you'll need to run npm run build or npx tailwindcss build css/application.css -o assets/application.css.liquid so those classes get added to your application.css or else they might not display correctly.

Testing & Development

To begin, run theme watch --allow-live and if you have your store theme open, you'll be able to see all your changes in real-time.

Additional Information

Github

Use our starter theme from this article – https://github.com/themarketlabs/shopify-tailwind-starter-theme.

*Extras*

How to add JQuery to your theme

  1. Create a new file in the folder assets called jquery.min.js

  2. Download the file from https://jquery.com/download/

  3. Upload the file into jquery.min.js

  4. In the theme.liquid paste the following before the closing </head>

{{ 'jquery.min.js' | asset_url | script_tag }}

How to add AlpineJS to your theme

  1. The easiest thing to do is to copy the CDN links from here

  2. Paste that link before the closing </head>

<script src="//unpkg.com/alpinejs" defer></script>

How to add Shopify Option Selectors

1. This is how to use Shopify's new multiple option JavaScript helper. Before the closing </head> paste the following:

{{ 'option_selection.js' | shopify_asset_url | script_tag }}

2. Inside your product.liquid file, ensure you have a <form> element that posts to the /cart/add action, and that contains a <select> element that contains all the variants for your given product.

<form action="/cart/add" method="post">
  <div id="product-variants">
    <div id="price-field"></div>
    <select id="product-select" name="id">
      {% for variant in product.variants %}
      <option value="{{ variant.id }}"
        >{{ variant.title }} - {{ variant.price | money }}</option
      >
      {% endfor %}
    </select>
  </div>
  <input
    type="image"
    src="{{ 'purchase.png' | asset_url }}"
    name="add"
    value="Purchase"
    id="purchase"
  /></form>

3. To use Shopify's JavaScript helper, you must instantiate Shopify.OptionSelectors with the id of the <select>, a JavaScript representation of the product, and a callback. This will hide the existing <select> element, build new <select> elements for each product option, and bind the callback to each selector.

Here's a complete jQuery script that calls the Shopify JavaScript helper to enabled multiple options for a product:

// <![CDATA[
  var selectCallback = function(variant, selector) {
    if (variant) {
      if (variant.available) {
        // Selected a valid variant that is available.
        $('#add').removeClass('disabled').removeAttr('disabled').val('Add to Cart').fadeTo(200,1);
      } else {
        // Variant is sold out.
        $('#add').val('Sold Out').addClass('disabled').attr('disabled', 'disabled').fadeTo(200,0.5);
      }
      // Whether the variant is in stock or not, we can update the price and compare at price.
      if ( variant.compare_at_price > variant.price ) {
        $('#price-field').html('<span class="product-price on-sale">'+ Shopify.formatMoney(variant.price, "") +'</span>'+'&nbsp;<s class="product-compare-price">'+Shopify.formatMoney(variant.compare_at_price, "")+ '</s>');
      } else {
        $('#price-field').html('<span class="product-price">'+ Shopify.formatMoney(variant.price, "") + '</span>' );
      }
    } else {
      // variant doesn't exist.
      $('#add').val('Unavailable').addClass('disabled').attr('disabled', 'disabled').fadeTo(200,0.5);
    }
  }
  // initialize multi selector for product
  jQuery(function($) {
    new Shopify.OptionSelectors("product-select", { product: , onVariantSelected: selectCallback });
  });
  // ]]>

How to add SplideJS for Product Page Images

Splide is a lightweight javascript slider and carousel. It's perfect for displaying product images with clickable thumbnails.

1. To get started, create a file called splide.js and splide.css in your assets folder

2. Add the following before the closing </head> in theme.liquid

{{ 'splide-css.css' | asset_url | stylesheet_tag }}
{{ 'splide.js' | asset_url | script_tag }}

3. Download Splide and upload the javascript and css files to their associated Shopify files.

4. Based on this tutorial, create a Splide gallery. However you scaffold your product.liquid template, you can use this code for inspiration:

<div class="col-span-12 md:col-span-6 border-gray-200 border-b md:border-none py-5 md:py-0">
            <div class="md:px-10 flex flex-col top-0 sticky">
                <div id="primary-slider" class="splide">
                    <div class="splide__track">
                        <ul class="splide__list">
                            {% for image in product.images %}
                            <li class="splide__slide">
                                <img data-id="{{image.id}}" data-src="{{img.src}}" data-variant-id="{{ image.variants }}" class="thumbnail-image" src="{{ image.src | img_url: '' }}" alt="{{ image.alt | escape }}">
                            </li>
                            {% endfor %}
                        </ul>
                    </div>
                </div>
                <div id="secondary-slider" class="splide pt-3">
                    <div class="splide__track">
                        <ul class="splide__list">
                            {% for image in product.images %}
                            <li data-id="{{image.id}}" class="splide__slide">
                                <img class="thumbnail-image" src="{{ image.src | img_url: '' }}" alt="{{ image.alt | escape }}">
                            </li>
                            {% endfor %}
                        </ul>
                    </div>
                </div>
            </div>
        </div>

5. Next you'll need to add some javascript to initiate the Splide carousel.

var secondarySlider = new Splide('#secondary-slider', {
    fixedWidth: 100,
    height: 60,
    gap: 10,
    cover: true,
    isNavigation: true,
    pagination: false,
    arrows: false,
    //focus: 'center',
    breakpoints: {
        '600': {
            fixedWidth: 66,
            height: 40,
        }
    },
}).mount();
var primarySlider = new Splide('#primary-slider', {
    type: 'fade',
    heightRatio: 1,
    pagination: false,
    arrows: false,
    cover: false,
}); 

6. Lastly, you'll need to modify the code from the Shopify Option Selector to make it so when a variant is selected, the product image is also changed.

if (variant) {
        if (variant.featured_image) {
            var slidesArr = secondarySlider.Components.Elements.slides
            slidesArr.forEach(function(el, index) {
                if (variant.featured_image.id == el.dataset.id) {
                    secondarySlider.go(index)
                }
         })
}