Shopify CSS Explained: {% stylesheet %} vs {% style %} vs <style>
If you've built a Shopify theme, you've probably used one of these:
{% stylesheet %};
{% style %}
<style>
They all write CSS.
So why did Shopify create three different ways to do what seems like the same job?
The answer isn't about syntaxβit's about performance, scalability, and architecture.
Let's explain it with something every developer understands.
π¦ Shopify CSS Is Like a Traffic Signal System
Imagine your Shopify theme is a busy city.
Thousands of cars (sections) move through it every day. Without traffic signals, every intersection would become chaotic.
Shopify's CSS methods work the same way.
Each one controls traffic differently.
π’ Green Light β {% stylesheet %};
This is the city's central traffic controller.
It creates one set of traffic rules and shares them with every intersection.
Every section follows the same rules without creating duplicate copies.
{% stylesheet %};
.product-card {
color: var(--heading-color);
padding: 20px;
border-radius: 12px;
}
{% endstylesheet %}
Why?
Shopify bundles this CSS once, making it reusable across the theme.
Best for
- Shared component styles
- Layouts
- Buttons
- Cards
- Grids
- Reusable UI
Trade-offs
β Smaller HTML
β Cached CSS
β Excellent performance
β Doesn't support Liquid variables
β Can't use:
{{ section.settings.heading_color }}
π‘ Yellow Light β {% style %};
Now imagine a traffic officer standing at a busy intersection.
Instead of following fixed rules, they react to what's happening right now.
That's exactly what {% style %}; does.
{% style %};
.product-card {
color: {{ section.settings.heading_color }};
}
{% endstyle %};
Why?
Every section generates its own CSS using Liquid values from the Theme Editor.
Best for
- Theme Editor settings
- Dynamic colors
- Typography controls
- Spacing controls
- Merchant customization
Trade-offs
β Supports Liquid
β Updates instantly in the Theme Editor
β Generates CSS for every section instance
β Larger HTML when many sections are rendered
π΄ Red Light β Raw <style>
This is like placing a temporary stop sign during road construction.
It works.
But it isn't connected to Shopify's CSS bundling system.
<style>
.notice {
color: red;
}
</style>
Why?
It's plain HTML.
No Shopify processing.
No Theme Editor integration.
Best for
- Small one-off styles
- Temporary experiments
- Static pages
Trade-offs
β Familiar HTML
β Simple
β Not bundled
β No Shopify-specific features
β Easy to duplicate accidentally
π Architecture Diagram
Shopify Theme
β
βββββββββββββββββΌββββββββββββββββ
β β β
β β β
{% stylesheet %} {% style %} <style>
Shared CSS Dynamic CSS Static CSS
Cached Once Per Section Plain HTML
Fastest Flexible One-Off
β‘ Performance Tip
Use CSS variables to combine the best of both worlds.
<div
class="product-card"
style="--heading-color: {{ section.settings.heading_color }};"
>
Then keep your reusable CSS bundled:
{% stylesheet %};
.product-card {
color: var(--heading-color);
}
{% endstylesheet %};
Now your CSS stays cached while each section receives its own custom value.
Benefits:
- Less duplicated CSS
- Smaller HTML
- Better scalability
- Faster rendering
π‘ Senior Developer Tip
Don't ask:
"Which CSS method should I use?"
Ask instead:
"Which responsibility belongs to which CSS method?"
Architecture beats shortcuts every time.
π― Final Takeaway
Great Shopify themes aren't built with more CSS.
They're built with better architecture.
Use:
-
{% stylesheet %};for reusable, cached styles. -
{% style %};for dynamic styles powered by Liquid. -
<style>only when plain HTML is all you need.
The best Shopify developers don't choose oneβthey know when to use each.
Have you used all three in your Shopify projects? Which one do you prefer and why?
Top comments (0)