-
Notifications
You must be signed in to change notification settings - Fork 365
CSS Custom Variable - Liquid variable or control flow tags #541
Comments
One potential solution would be to copy and prepend any liquid outside of the {%- assign font_body_bold = settings.font_body | font_modify: 'weight', 'bolder' -%}
{%- assign color_special = '#FF0000' -%}
{%- if settings.capitalize_product_title -%}
{%- assign product_title_transform = 'uppercase' -%}
{%- else -%}
{%- assign product_title_transform = 'normal' -%}
{%- endif -%}
<style>
{{ settings.font_body | font_face }}
{{ font_body_bold | font_face }}
:root {
--color-accent: {{ settings.color_accent }};
--color-special: {{ color_special }};
--font-body: {{ settings.font_body.family }}, {{ settings.font_body.fallback_families }};
--font-body-weight: {{ settings.font_body.weight }};
--font-body-style: {{ settings.font_body.style }};
--font-body-bold-weight: {{ font_body_bold.weight | default: 'bold' }};
--product-title-transform: {{ product_title_transform }};
}
</style> Then during the build or deploy process the liquid outside of the {%- assign font_body_bold = settings.font_body | font_modify: 'weight', 'bolder' -%}
{%- assign color_special = '#FF0000' -%}
{%- if settings.capitalize_product_title -%}
{%- assign product_title_transform = 'uppercase' -%}
{%- else -%}
{%- assign product_title_transform = 'normal' -%}
{%- endif -%}
body{
font-family: {{ settings.font_body.family }};
}
a {
color: {{ settings.color_accent }};
}
span.special{
color:{{ color_special }};
}
.product_title{
text-transform:{{ product_title_transform }};
} This would also be a huge improvement for free / premium theme developers supporting merchants. Often when a merchant wants to make an adjustment to how much darker the accent color is on hover, or tweak another SCSS variable they can do so by changing one or two lines in the .scss.liquid file. Personally I have been concerned about the impact of loosing this since Slate 1.x moves towards compressed CSS with the liquid tags duplicated many times throughout the file. With an approach of copying the liquid tags over we could have an organized approach where we assign all sorts of variables linked to theme settings or modifying theme settings using booleans, color filters, font filters, etc. This would give more knowledgable merchants and Shopify experts a much easier path to overwrite some style defaults—especially if liquid comments and line breaks are preserved. {%- comment -%}
Colors
{%- endcomment -%}
{%- assign color_text = settings.color_text -%}
{%- assign color_tex_title = settings.color_text | color_darken: 30 -%}
{%- assign color_accent = settings.color_accent -%}
{%- assign color_accent_hover = color_accent | color_darken: 20 -%}
{%- comment -%}
Fonts
{%- endcomment -%}
{%- assign font_body = settings.font_body -%}
{%- assign font_bod_bold = font_body | font_modify: 'weight', 'bolder' -%}
{%- comment -%}
Default variables
{%- endcomment -%}
{%- assign page_width = '1180px' -%}
body{...... |
I still believe that there are many normal theme use cases where it would make sense to incorporate a solution into Slate, however as a temporary solution on my end I created a new |
Thanks @jonathanmoore -- clearly I need to dig into our new styling solution and flush out some of these very important edge cases! |
As a temporary solution, I'm solving this with a new // slate.config.js
/* eslint-disable no-undef */
const path = require('path');
const fs = require('fs');
const WrapperPlugin = require('wrapper-webpack-plugin');
const alias = {
jquery: path.resolve('./node_modules/jquery'),
'lodash-es': path.resolve('./node_modules/lodash-es'),
};
const liquidVariables = fs.readFileSync(
'src/snippets/liquid-variables.liquid',
'utf8',
);
module.exports = {
slateCssVarLoader: {
cssVarLoaderLiquidPath: ['src/snippets/css-variables.liquid'],
},
slateTools: {
extends: {
dev: {resolve: {alias}},
prod: {
resolve: {alias},
module: {},
plugins: [
new WrapperPlugin({
test: /\.css\.liquid$/,
header: liquidVariables,
}),
],
},
},
},
}; |
@jonathanmoore I have used this in my theme :) https://github.com/montalvomiguelo/starter-debut/tree/liquid-variables |
@jonathanmoore this is awesome, finally getting a chance to play around with this. I extended it a little further, I really wanted the Liquid variables to be in the same file as the css custom variables. So am reading the css-variables file, then splitting the contents at the "style" tag and putting it to the top of the file. snippets/css-variables.liquid <!-- Liquid Variables -->
{{ settings.font_heading | font_face }}
{{ settings.font_body | font_face }}
{%- assign font_body_bold = settings.font_body | font_modify: 'weight', 'bolder' -%}
{%- assign font_body_bold_italic = font_body_bold | font_modify: 'style', 'italic' -%}
{{ font_body_bold | font_face }}
{{ font_body_bold_italic | font_face }}
{% if settings.text_transform %}
{% assign text_transform = 'uppercase' %}
{% else %}
{% assign text_transform = 'normal' %}
{% endif %}
<style>
:root {
--color-accent: {{ settings.color_accent }};
--color-body-text: {{ settings.color_body_text }};
--color-main-background: {{ settings.color_main_bg }};
--color-border: {{ settings.color_body_text | color_lighten: 50 }};
--font-heading: {{ settings.font_heading.family }}, {{ settings.font_heading.fallback_families }};
--font-body: {{ settings.font_body.family }}, {{ settings.font_body.fallback_families }};
--font-body-weight: {{ settings.font_body.weight }};
--font-body-style: {{ settings.font_body.style }};
--font-body-bold-weight: {{ font_body_bold.weight | default: 'bold' }};
--text_transform: {{ text_transform }};
}
</style> slate.config.js const path = require('path');
const fs = require('fs');
const WrapperPlugin = require('wrapper-webpack-plugin');
const alias = {
jquery: path.resolve('./node_modules/jquery'),
'lodash-es': path.resolve('./node_modules/lodash-es'),
};
const cssVariableFile = fs.readFileSync(
'src/snippets/css-variables.liquid',
'utf8',
);
const liquidVariables = cssVariableFile.split("<style>")[0];
module.exports = {
slateCssVarLoader: {
cssVarLoaderLiquidPath: ['src/snippets/css-variables.liquid'],
},
slateTools: {
extends: {
dev: {resolve: {alias}},
prod: {
resolve: {alias},
module: {},
plugins: [
new WrapperPlugin({
test: /\.css\.liquid$/,
header: liquidVariables,
}),
],
},
},
},
}; |
@t-kelly Any updates on this? As of right now I'm sort of stuck with 1.0.0 beta 7 and not sure if it's worth upgrading or taking the time to rework this into the new configs. |
No updates yet -- but it should take less than 10 minutes to switch over your Slate config. Let me know if you have any questions! |
@jonathanmoore did you have any luck migrating this over to the new config? Just looking at it now and running into some roadblocks getting it to work. |
@rainerbird Same here. I have been short on time to figure out how to properly update it. Once I have some time to figure it out, I'll post it back in here. |
I had a go over the weekend and think I've got it working using this, hope this helps: const plugins = [];
var liquidWrapper = new WrapperPlugin({
test: /\.css\.liquid$/,
header: liquidVariables,
});
if (process.env.NODE_ENV === 'production') {
plugins.push(liquidWrapper);
}
module.exports = {
'cssVarLoader.liquidPath': ['src/snippets/css-variables.liquid'],
'webpack.extend': {
resolve: {
alias: {
jquery: path.resolve('./node_modules/jquery'),
'lodash-es': path.resolve('./node_modules/lodash-es'),
},
},
plugins: plugins
},
}; |
@rainerbird can confirm your updated config is working for me as well, im on slate v1.0.0-beta.12. Thank you and @jonathanmoore for figuring this out. |
native css variables should be supported by liquid and theme-kit This would allow global vars in an easy way. |
Problem
The current approach with passing liquid tags from
snippets/css-variables.liquid
to the CSS style assets does not allow for any variable (capture
orassign
) or control flow (if
) tags. Shopify/starter-theme has a bug where liquid assigns variables are passed to layout.theme.css.liquid on build or deploy, however the values always return null.Shopify/starter-theme#60
Replication steps
Here are two specific examples of challenges with theme customization settings and the way css-variables work:
Applying liquid filters to objects and then returning a variable
Below
font_body_bold
is a new drop fromsettings.font_body
after applying thefont_modify
filter. This assignment will not carry over from a theme's snippets to the theme's assets (css/scss).When Slate is deployed or built the liquid tag {{ font_body_bold.weight | default: 'bold' }} is dropped into the layout.theme.css.liquid file. However since the variable assignment happens in a snippet outside of the style asset the value of font_body_bold.weight is null which always defaults to bold regardless of the font_modify filters.
Invalid example from shopify/starter-theme
Using a boolean setting for CSS
Having a checkbox/boolean theme setting like Capitalize product titles is a common option many themes have. Currently there is not a way to take a setting's true/false value to apply CSS like
text-transform: [uppercase|lowercase]
.The expectation would be that you could use a basic if/else statement to assign the uppercase or lowercase value based on a theme's setting. Below is an example that I think many would expect to work, but only returns nil values.
More Details
Similar issue from the perspective of SCSS functions #503 It's important to note that this specific issue does not occur while running
yarn start
and live processing the SCSS changes locally. In that case the snippet's CSS vars are doing the work to pass along anything processed with liquid.The text was updated successfully, but these errors were encountered: