---
title: Stylesheet content subsetting
description: >-
  Learn how Shopify subsets CSS from stylesheet tags so that storefront pages
  only load the styles they need, and how to make your theme compatible.
source_url:
  html: >-
    https://shopify.dev/docs/storefronts/themes/best-practices/performance/stylesheet-subsetting
  md: >-
    https://shopify.dev/docs/storefronts/themes/best-practices/performance/stylesheet-subsetting.md
api_name: liquid
---

# Stylesheet content subsetting

Shopify automatically subsets CSS from [`{% stylesheet %}`](https://shopify.dev/docs/api/liquid/tags/stylesheet) tags so that each storefront page only loads the styles it needs. Instead of bundling all `{% stylesheet %}` CSS from every theme file into a single payload, Shopify identifies which files are part of the page's render tree — the set of Liquid files (sections, blocks, and snippets) that are actually rendered on that page — and includes only their CSS.

This reduces the amount of CSS that browsers download and parse, which improves page load times for merchants and their customers.

***

## How subsetting works

When a storefront page is rendered, Shopify determines which Liquid files are part of the page's render tree. Only the CSS from those files' `{% stylesheet %}` tags is included in the linked `styles.css` file.

For example, if `sections/collection.liquid` renders `snippets/product-card.liquid` using `{% render 'product-card' %}`, then both files' `{% stylesheet %}` CSS is included on any page that renders the collection section. The snippet's CSS is included because its parent (the collection section) is in the render tree.

### What isn't affected

The following types of CSS aren't subject to subsetting:

* **Asset stylesheets**: CSS files in the `assets/` folder that are loaded through `{{ 'style.css' | asset_url | stylesheet_tag }}` continue to work as before. They're included based on where you reference them in your layouts and templates.
* **Inline styles**: Inline `style` attributes on HTML elements aren't affected.
* **HTML `<style>` tags**: CSS in `<style>` tags (not `{% stylesheet %}`) renders as-is with the HTML output.
* **CSS inside the liquid `{% style %}` tag**: CSS inside the liquid `{% style %}` tag isn't affected.

***

## Compatible and incompatible patterns

A theme is compatible with subsetting when each file's CSS classes are used only within that file or files it directly renders. Most themes that follow a co-located, component-scoped pattern for `{% stylesheet %}` tags are already compatible. The following examples show what works and what doesn't.

### Compatible pattern: self-contained styles

CSS classes that are defined and used in the same file are always safe:

## /sections/product.liquid

```liquid
{% stylesheet %}
  .product-title { font-size: 1.5rem; font-weight: bold; }
  .product-price { color: #333; }
{% endstylesheet %}


<div class="product-title">{{ product.title }}</div>
<div class="product-price">{{ product.price | money }}</div>
```

### Compatible pattern: parent styles used by rendered children

CSS classes that a parent file defines and a rendered child uses through `{% render %}` are safe, because the parent is always in the render tree when the child is:

## /sections/collection.liquid

```liquid
{% stylesheet %}
  .collection-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  .collection-grid__item { border: 1px solid #eee; padding: 1rem; }
{% endstylesheet %}


<div class="collection-grid">
  {% for product in collection.products %}
    {% render 'product-card', product: product %}
  {% endfor %}
</div>
```

## /snippets/product-card.liquid

```liquid
<div class="collection-grid__item">
  {{ product.title }}
</div>
```

### Incompatible pattern: cross-file CSS dependency

A CSS class that's defined in one file's `{% stylesheet %}` tag but used in a different, unrelated file is incompatible. If the defining file isn't in the page's render tree, then the styles won't be included:

## /sections/header.liquid

```liquid
{% stylesheet %}
  .site-banner { background: var(--color-accent); padding: 0.5rem 1rem; }
{% endstylesheet %}


<div class="site-banner">{{ section.settings.announcement }}</div>
```

## /sections/footer.liquid

```liquid
<div class="site-banner">
  {{ section.settings.promo_text }}
</div>
```

In this example, `footer.liquid` uses `.site-banner` but doesn't define it. It relies on `header.liquid`'s `{% stylesheet %}` being on the same page. If a page doesn't render the header section, then the class won't be available, and the footer won't be styled correctly.

***

## Checking your theme

The `ValidScopedCSSClass` check in [Theme Check](https://shopify.dev/docs/storefronts/themes/tools/theme-check) detects cross-file CSS dependencies. It's enabled by default in the recommended configuration.

Run Theme Check on your theme:

```bash
shopify theme check
```

The check reports warnings when a CSS class that's used in an HTML `class` attribute is defined in another file's `{% stylesheet %}` tag, and that file isn't a direct ancestor in the render tree. For example:

CSS class \`site-banner\` is defined in another liquid file's stylesheet tags

that isn't an explicit ancestor: \`sections/header.liquid\`

CSS classes defined in `assets/*.css` are allowlisted, so they won't trigger warnings when used in Liquid files.

***

## Fixing flagged issues

There are a few approaches to fixing any classes that the Theme Check linter flags:

### Move CSS to the file that uses it

If a class is used in one or a few specific files, then either add the class definition to each file's `{% stylesheet %}` tag, or define it once in a common parent.

### Move CSS to a shared asset stylesheet

If a class is truly global and used across many unrelated sections (such as utility classes or shared typography), then move it to a `.css` file in the `assets/` folder and load it through [`stylesheet_tag`](https://shopify.dev/docs/api/liquid/filters/stylesheet_tag) in your layout:

## /assets/global.css

```css
.site-banner { background: var(--color-accent); padding: 0.5rem 1rem; }
```

## /layout/theme.liquid

```liquid
{{ 'global.css' | asset_url | stylesheet_tag }}
```

Asset stylesheets aren't subject to subsetting and are always available on every page that loads them.

***

## Subsetting and the Section Rendering API

Subsetting also applies when sections are fetched dynamically. When you use the [Section Rendering API](https://shopify.dev/docs/api/ajax/section-rendering) to fetch a section, the response includes a `<style data-section-stylesheet>` tag containing the section's subsetted CSS:

```html
<section id="shopify-section-sections--28375442096184__featured_collection" class="shopify-section">
  <style data-section-stylesheet>
    .collection-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  </style>
  <!-- section content -->
</section>
```

If you insert the full section response into the DOM, then the styles are included automatically. If you insert only a portion of the response, then you also need to extract the `<style data-section-stylesheet>` element and insert it into the DOM so the section's styles are applied.

***
