Every Shopify store eventually needs custom CSS. Whether you are tweaking font sizes, adjusting section spacing, or overhauling the look and feel of your product pages, understanding how and where to add custom styles is fundamental to getting your store looking exactly the way you want.

The problem is that Shopify gives you multiple ways to add CSS, and choosing the wrong approach can lead to styles that break on theme updates, slow down your pages, or create specificity nightmares that become impossible to maintain. After building and maintaining hundreds of Shopify stores, we have seen every CSS mistake in the book.

This guide covers every method available to you, when to use each one, and the patterns that will keep your custom styles clean, performant, and maintainable as your store grows.

Why you need custom CSS on Shopify

Shopify themes are designed to be customisable through the theme editor, but there are always limits. The theme editor gives you control over colours, fonts, spacing, and layout options that the theme developer chose to expose. Everything else requires CSS.

Here are the most common reasons merchants need custom CSS:

  • Brand alignment. Your brand guidelines specify exact colours, spacing, and typography that the theme editor cannot match precisely.
  • Layout adjustments. Moving elements, changing grid structures, or altering the visual hierarchy of product pages and collection pages.
  • Third-party app styling. Apps inject their own HTML into your store, and their default styling rarely matches your theme perfectly.
  • Responsive fixes. Addressing mobile layout issues that the theme does not handle well for your specific content.
  • Conversion optimisation. Making add-to-cart buttons more prominent, improving the visual flow of your checkout, or highlighting trust signals.

The key is knowing which method to use for each scenario. A small button colour change does not belong in the same place as a comprehensive typography overhaul.

Before you start: essential preparation

Before writing a single line of CSS, there are three things you must do. Skipping any of these will cost you time and potentially break your live store.

1. Duplicate your theme

Always work on a duplicate. In your Shopify admin, navigate to Online Store > Themes, click the three dots next to your live theme, and select Duplicate. Make all your CSS changes on the duplicate first, preview them, and only publish once you are satisfied.

2. Learn your browser's developer tools

Right-click any element on your store and select Inspect (or press F12). The Elements panel shows you the HTML structure, and the Styles panel shows every CSS rule affecting that element. This is where you will spend most of your time when writing custom CSS for Shopify.

Browser developer tools showing CSS inspection on a Shopify store
Browser developer tools are essential for identifying the correct selectors to target in your custom CSS.

The key information you need from dev tools:

  • The CSS class names or IDs of the elements you want to style
  • The current CSS rules applied to those elements
  • The specificity of existing rules (so you know how specific your overrides need to be)
  • The file and line number where existing styles are defined

3. Understand CSS specificity

Specificity determines which CSS rule wins when multiple rules target the same element. This is the single most important concept for custom CSS on Shopify, because you are always overriding existing theme styles.

/* Specificity hierarchy (lowest to highest):
   Element selectors:     h1, p, div           (0,0,1)
   Class selectors:       .product-title        (0,1,0)
   ID selectors:          #product-title        (1,0,0)
   Inline styles:         style="color: red"    (1,0,0,0)
   !important:            Overrides everything  (avoid this)
*/

/* BAD: Too broad, will affect every h2 on the site */
h2 { font-size: 24px; }

/* GOOD: Targets only product page titles */
.product__title h2 { font-size: 24px; }

/* BETTER: Uses the theme's own class structure */
.product__title.h1 { font-size: 24px; }

Method 1: Theme editor Custom CSS field

This is the simplest method and the one Shopify recommends for small, section-specific changes. Every Online Store 2.0 theme includes a Custom CSS field in the theme editor.

How to access it

  1. Go to Online Store > Themes > Customise
  2. Select the section or block you want to style
  3. Scroll to the bottom of the section settings
  4. Find the Custom CSS text field
  5. Enter your CSS rules
  6. Click Save

What makes this method special

When you add CSS through the theme editor, Shopify automatically scopes it to that specific section instance. You do not need to write complex selectors because Shopify handles the scoping for you.

/* In the theme editor Custom CSS field, you write: */
.button { background-color: #2D5A27; }

/* Shopify renders it as: */
#shopify-section-template--xxxxx .button {
  background-color: #2D5A27;
}

This is powerful because it means your styles only affect that one section, not every instance of the same section type across your store.

When to use this method

  • Small visual tweaks to individual sections
  • Adjusting padding, margins, or colours on a single section
  • Quick fixes that do not need to be applied globally
  • Testing CSS changes before committing them to a stylesheet

Limitations

  • Not suitable for global styles that should apply across the entire store
  • Difficult to manage when you have many sections with custom CSS
  • No syntax highlighting or error checking
  • Cannot use @media queries or @font-face declarations in some themes
Shopify theme editor showing the Custom CSS field for a section
The Custom CSS field in the theme editor is ideal for section-specific styling changes.

Method 2: Editing theme asset files

For global styles that need to apply across your entire store, you will need to edit the theme's asset files directly. This gives you full control but requires more care.

Accessing the code editor

  1. Go to Online Store > Themes
  2. Click the three dots next to your theme
  3. Select Edit code
  4. In the Assets folder, find the main CSS file (usually base.css, theme.css, or component-*.css)

Most modern Shopify themes split their CSS across multiple files. Dawn, for example, uses a modular structure with files like base.css, component-card.css, section-header.css, and so on. You could add your custom CSS at the end of the relevant file, but this is risky because theme updates will overwrite these files.

The better approach is Method 3.

Method 3: Creating a dedicated custom stylesheet

This is the approach we use on every Shopify project. It keeps your custom CSS completely separate from the theme's core files, making it safe from theme updates and easy to maintain.

Step 1: Create the file

  1. Go to Online Store > Themes > Edit code
  2. In the Assets folder, click Add a new asset
  3. Select Create a blank file
  4. Name it custom and select .css as the extension
  5. Click Add asset

Step 2: Link it in your theme

Open layout/theme.liquid and add the following line just before the closing </head> tag:

{{ 'custom.css' | asset_url | stylesheet_tag }}

By placing it last in the head, your custom styles will naturally override the theme's default styles without needing excessive specificity or !important declarations.

Step 3: Add your custom CSS

Now open assets/custom.css and start adding your styles. Here is a template structure we recommend:

/* ============================================
   CUSTOM CSS — [Store Name]
   Last updated: 2026-03-16
   ============================================ */

/* ---- Global Typography ---- */

/* ---- Header & Navigation ---- */

/* ---- Product Pages ---- */

/* ---- Collection Pages ---- */

/* ---- Cart & Checkout ---- */

/* ---- Footer ---- */

/* ---- Third-Party App Overrides ---- */

/* ---- Responsive Overrides ---- */
@media screen and (max-width: 749px) {
  /* Mobile-specific overrides */
}

@media screen and (min-width: 750px) and (max-width: 989px) {
  /* Tablet-specific overrides */
}
Organised custom CSS file structure in Shopify code editor
A well-organised custom CSS file with clear section comments is easier to maintain long-term.

Why this method is superior

  • Update-safe. Theme updates do not touch custom asset files. Your styles persist.
  • Single source of truth. All custom styles live in one file, making auditing and debugging straightforward.
  • Version control friendly. If you use a custom theme development workflow, a single file is easy to track in Git.
  • Performance efficient. One additional CSS file is negligible compared to the performance cost of inline styles scattered across templates.

Method 4: Using Liquid for conditional CSS

Liquid, Shopify's templating language, opens up powerful possibilities for conditional CSS. You can output different styles based on the current page, customer group, or even metafield values.

Page-specific stylesheets

If you have substantial CSS that only applies to certain page types, you can conditionally load it:

{% comment %} In layout/theme.liquid, before </head> {% endcomment %}

{% if template.name == 'product' %}
  {{ 'custom-product.css' | asset_url | stylesheet_tag }}
{% endif %}

{% if template.name == 'collection' %}
  {{ 'custom-collection.css' | asset_url | stylesheet_tag }}
{% endif %}

This keeps your page-specific CSS from loading on pages where it is not needed, which is a small but meaningful performance optimisation for stores with extensive customisations.

Dynamic CSS with Liquid variables

You can also use Liquid to generate dynamic CSS values. This is particularly useful when you want theme settings to control aspects of your custom styling:

{% comment %} In a section's Liquid file {% endcomment %}

{% style %}
  .custom-banner {
    background-color: {{ section.settings.background_colour }};
    padding: {{ section.settings.padding_top }}px 0 {{ section.settings.padding_bottom }}px;
  }

  .custom-banner__heading {
    color: {{ section.settings.heading_colour }};
    font-size: {{ section.settings.heading_size }}px;
  }
{% endstyle %}

Targeting specific pages and templates

Shopify adds template-specific classes to the body element, which makes page-specific CSS straightforward. Understanding this pattern is essential for any serious customisation work.

Template body classes

/* Target only product pages */
.template-product .product-form__buttons .btn {
  background-color: #2D5A27;
  border-radius: 0;
}

/* Target only collection pages */
.template-collection .collection-hero {
  min-height: 300px;
}

/* Target the homepage */
.template-index .hero__heading {
  font-size: 3.5rem;
}

/* Target the cart page */
.template-cart .cart__footer {
  border-top: 2px solid #2D5A27;
}

Targeting specific product or collection handles

For even more granular control, you can use Liquid to output the current handle as a body class. Add this to your theme.liquid body tag:

<body class="template-{{ template.name }}
  {% if template.name == 'product' %} product-{{ product.handle }}{% endif %}
  {% if template.name == 'collection' %} collection-{{ collection.handle }}{% endif %}">

Then target specific products or collections in your CSS:

/* Style a specific product page */
.product-premium-leather-bag .product__price {
  font-size: 2rem;
  color: #8B4513;
}

/* Style a specific collection page */
.collection-sale .collection-product-card {
  border: 2px solid #e74c3c;
}

Working with CSS custom properties

Modern Shopify themes use CSS custom properties extensively. Dawn and its derivatives define variables for colours, fonts, spacing, and more on the :root element. Understanding and leveraging these variables is the most efficient way to make sweeping visual changes.

/* Override theme CSS variables globally */
:root {
  --color-base-text: #1a1a1a;
  --color-base-background: #fafaf8;
  --color-base-accent-1: #2D5A27;
  --font-heading-family: 'Fraunces', serif;
  --font-heading-weight: 600;
  --font-body-family: 'DM Sans', sans-serif;
  --page-width: 1200px;
  --spacing-sections-desktop: 36px;
  --spacing-sections-mobile: 24px;
}

/* Use variables in your custom CSS */
.custom-announcement-bar {
  background-color: var(--color-base-accent-1);
  color: var(--color-base-background);
  font-family: var(--font-body-family);
  padding: var(--spacing-sections-mobile) 0;
}

This approach is powerful because changes to the variables cascade through every rule that references them. Change --color-base-accent-1 once, and every element using that variable updates automatically.

CSS custom properties in Shopify theme development
CSS custom properties let you make sweeping visual changes by updating a single variable value.

Responsive design techniques

Shopify themes use specific breakpoints for responsive design. When writing custom CSS, you need to match these breakpoints to ensure your styles integrate seamlessly with the theme's responsive behaviour.

Common Shopify theme breakpoints

/* Dawn theme breakpoints */
@media screen and (max-width: 749px) {
  /* Mobile */
}

@media screen and (min-width: 750px) and (max-width: 989px) {
  /* Tablet */
}

@media screen and (min-width: 990px) {
  /* Desktop */
}

/* Some themes also use: */
@media screen and (min-width: 1200px) {
  /* Large desktop */
}

Mobile-first custom CSS

We always recommend writing mobile-first CSS for Shopify stores. This means your base styles target mobile devices, and you use min-width media queries to add complexity for larger screens:

/* Base: mobile styles */
.custom-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  padding: 0 16px;
}

/* Tablet and up */
@media screen and (min-width: 750px) {
  .custom-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    padding: 0 32px;
  }
}

/* Desktop and up */
@media screen and (min-width: 990px) {
  .custom-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
    max-width: var(--page-width);
    margin: 0 auto;
    padding: 0 48px;
  }
}

Performance considerations

CSS itself is rarely a significant performance bottleneck, but poorly managed custom CSS can contribute to slower rendering and worse Core Web Vitals scores. Here is how to keep your styles lean. For a deeper dive into performance, read our guide to Shopify customisation and scripts.

Keep your CSS file size small

A well-written custom CSS file for a Shopify store should rarely exceed 15-20KB. If yours is significantly larger, you are probably overriding too many theme defaults and should consider whether a custom theme build would be more appropriate.

Avoid render-blocking patterns

/* BAD: Forces the browser to recalculate layout */
.product-card {
  width: calc(100% / 3 - 20px) !important;
  float: left !important;
  margin: 10px !important;
}

/* GOOD: Uses modern CSS that the browser can optimise */
.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

Minimise the use of !important

Every !important declaration is a sign that your CSS architecture has a specificity problem. Instead of reaching for !important, increase your selector specificity:

/* BAD: Using !important */
.btn { background-color: #2D5A27 !important; }

/* GOOD: Using higher specificity */
.template-product .product-form .btn {
  background-color: #2D5A27;
}

/* ALSO GOOD: Doubling the class for extra specificity */
.btn.btn { background-color: #2D5A27; }

Common CSS customisations with code

Here are production-ready CSS snippets for the most frequently requested Shopify customisations. These have been tested across Dawn and other popular Online Store 2.0 themes.

Custom announcement bar

.announcement-bar {
  background-color: #2D5A27;
  color: #ffffff;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 0.75rem;
  padding: 8px 0;
}

.announcement-bar a {
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 2px;
}

Product page price styling

/* Make the price more prominent */
.price__regular .price-item--regular {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-base-text);
}

/* Sale price styling */
.price--on-sale .price-item--sale {
  color: #c0392b;
  font-weight: 700;
  font-size: 1.5rem;
}

.price--on-sale .price-item--regular {
  text-decoration: line-through;
  opacity: 0.6;
  font-size: 1rem;
}

Custom button styles

/* Primary button override */
.button--primary,
.shopify-payment-button__button--unbranded {
  background-color: #2D5A27;
  color: #ffffff;
  border: none;
  border-radius: 4px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 14px 28px;
  transition: background-color 0.2s ease, transform 0.1s ease;
}

.button--primary:hover,
.shopify-payment-button__button--unbranded:hover {
  background-color: #1e3d1a;
  transform: translateY(-1px);
}

/* Secondary button */
.button--secondary {
  background-color: transparent;
  color: #2D5A27;
  border: 2px solid #2D5A27;
  border-radius: 4px;
}

Collection page card hover effects

.card-wrapper {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card-wrapper:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

.card-wrapper .card__heading a {
  transition: color 0.2s ease;
}

.card-wrapper:hover .card__heading a {
  color: var(--color-base-accent-1);
}
Custom CSS hover effects on Shopify collection page product cards
Subtle hover effects on product cards can improve the browsing experience and encourage clicks.

Custom scrollbar styling

/* Modern scrollbar styling (Chromium browsers) */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
}

::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #555;
}

/* Firefox */
html {
  scrollbar-width: thin;
  scrollbar-color: #888 #f1f1f1;
}

Debugging CSS issues

When your custom CSS does not work as expected, it is almost always one of three problems: specificity, cascade order, or targeting the wrong element.

Step-by-step debugging process

  1. Open developer tools (F12 or right-click > Inspect)
  2. Select the element you are trying to style
  3. Check the Styles panel for your custom rule. If it appears with a strikethrough, another rule is overriding it.
  4. Check the Computed tab to see the final calculated value and which rule won.
  5. Verify your selector matches the actual HTML structure. Copy the element's selector from dev tools to confirm.

Common debugging tools

/* Temporarily outline all elements to see box model */
* { outline: 1px solid red !important; }

/* Highlight a specific element */
.element-im-debugging {
  outline: 3px solid blue !important;
  background: rgba(0, 0, 255, 0.1) !important;
}

/* Check if your CSS file is loading */
body::after {
  content: 'Custom CSS loaded';
  position: fixed;
  bottom: 0;
  right: 0;
  background: green;
  color: white;
  padding: 4px 8px;
  font-size: 12px;
  z-index: 99999;
}

Mistakes to avoid

After reviewing hundreds of Shopify stores with custom CSS issues, these are the patterns we see most often:

1. Using !important everywhere

If your stylesheet is full of !important declarations, your specificity architecture is broken. Every !important makes future changes harder because you can only override !important with another !important at higher specificity.

2. Editing core theme files

Never add custom CSS directly to base.css, theme.css, or any of the theme's built-in stylesheets. Theme updates will overwrite your changes without warning. Always use a separate custom file.

3. Not testing on mobile

Over 70% of ecommerce traffic comes from mobile devices. If you only test your CSS changes on desktop, you are ignoring the majority of your customers. Always preview changes across multiple screen sizes.

4. Overly broad selectors

/* DANGEROUS: Affects every paragraph on the entire site */
p { margin-bottom: 0; }

/* SAFE: Only affects paragraphs in product descriptions */
.product__description p { margin-bottom: 0; }

5. Not documenting changes

Add comments to your custom CSS explaining what each section does and why. Your future self (or the next developer) will thank you. When the time comes for a full custom theme development project, documented CSS makes migration significantly easier.

The best custom CSS is the CSS you do not write. Before adding a custom rule, check whether the theme editor already offers the control you need. Custom CSS should fill gaps, not replace the theme's built-in customisation system.

Andrew Simpson, Founder

Adding custom CSS to Shopify is not difficult, but doing it well requires discipline. Use a dedicated custom stylesheet, keep your selectors specific, test on mobile, and document everything. These practices will keep your store maintainable as it grows and save you significant time when theme updates roll around.

If your store needs more than simple CSS customisations, it might be time to consider a professional Shopify development approach. Sometimes what starts as a CSS tweak reveals deeper structural needs that benefit from expert attention. Get in touch if you would like to discuss your project.