Sass variable concatenation in loops in Shopify - sass

My SCSS compiles fine on sassmeister 1:
$black: "black_rgb(0,0,0)";
$honey-brown: "honey-brown_rgb(144,122,106)";
$red: "red_rgb(255,0,0)";
$paints: $black, $honey-brown, $red;
#each $color in $paints {
$colSplit: str-index($color, _);
$colName: str-slice($color, 1, $colSplit - 1);
$colVal: str-slice($color, $colSplit + 1);
.paint-#{$colName}-paint {background-color: #{$colVal};}
}
However Shopify is throwing an error:
Invalid CSS after ".paint-str-slice": expected selector, was
"("black_rgb(0,0..." at 9706
So it looks like the variable concatenation .paint-#{$colName}-paint isn't working properly.
I am not sure if it is to do with versions of software - I set Sassmeister to the lowest settings (v3.3.14) but it still works fine there. I do not know how to find out the version of scss Shopify uses.

Try to use a map:
$paints:(
black: rgb(0,0,0),
honey-brown: rgb(144,122,106),
red: rgb(255,0,0)
);
#each $name, $color in $paints {
.paint-#{$name}-paint {background-color: $color;}
}

It turns out that Shopify uses an old version of Sass which doesn't support some of the latest features such as #import for partials or indeed Maps1:
Note: Shopify is using a forked version of Sass v3.2 which does not support importing partial Sass files with the #import directive. This may cause some issues when trying to work with 3rd party Sass libraries.

Related

WARNING: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0

After I've updated my Angular application, and by doing so also updated Sass compiler I started getting this error
$val: 100px;
.some-sellector {
padding: $val / 2;
}
WARNING: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
Dart Sass compiler had some changes. Now to use division inside *.scss file you need to use the methods: math.div(value, divider) or calc(value / 2).
However, I found it easier to use multiplication with decimal number:
padding: $val * 0.5;

SASS - Complement function on a variable from another scope

I have two separate SASS files among many, on a ReactJS repository, such as _main.sass and _partials.sass. They are combined using #use on a separate file named index.css.
The SASS package as a dependency is just sass via npm.
_main.sass and all of its variables can be accessed by _partials.sass, thanks to #use "./main" as *.
I have the following code on _main.sass which detects OS preference for dark mode:
#media (prefers-color-scheme: light)
body
background-color: $white
color: $black
#media (prefers-color-scheme: dark)
body
background-color: $dark
color: $light
All of these color variables are defined and they're working well.
But the problem is that I need to use complement() function on the background-color which is currently active, in _partials.sass.
The main issue seems to me that when I assign a variable e.g. $accent on both ends of the media queries, the variable does not get picked up by the remote file. I could not wrap my head around to do it in such way, since I'm only a beginner at coding SASS.
Unfortunately, I need the plain CSS #media query implementations for automatically detecting the preference. But any suggestion is appreciated in case it is impossible to keep it like that and achieve what I wanted.
Thank you!
I've found the solution myself.
So, I was trying to make a light/dark theme compliant SASS implementation.
What complement function does is that it rotates the color in the input for 180deg on the RGB hue. I needed this to get corresponding inverted-like colors for each color, for better dark-mode contrast. The difference between invert and complement are listed here.
But, I realized that I did not need that. Here is the code for my theme implementation using SASS.
// rainbow
$blue: #00a4ef
$yellow: #f4b400
$red: #db4437
$green: #61b500
$purple: #6e14ef
$pink: #ff0090
$carmine: #c6004b
// monochroma
$white: #fff
$light: #f5f5f5
$lgray: #c2c2c2
$dgray: #6e6e6e
$ldark: #363636
$dark: #232323
$black: #000
$themes: (light: (logo: url("../static/logo-light.svg"), bg: $white, card-bg: $light, text: $black, link: $red, hover: $pink, active: $carmine, border: $lgray, button: $yellow), dark: (logo: url("../static/logo-dark.svg"), bg: $dark, card-bg: $ldark, text: $light, link: $red, hover: $pink, active: $carmine, border: $dgray, button: $purple))
#mixin themeProperty($theme, $property, $color, $additionalProperties)
#if $additionalProperties
#{$property}: unquote(map-get($theme, $color) + " " + $additionalProperties)
#else
#{$property}: unquote(map-get($theme, $color))
#mixin theme($property, $color, $additionalProperties: "")
$light: map-get($themes, light)
$dark: map-get($themes, dark)
#media (prefers-color-scheme: light)
#include themeProperty($light, $property, $color, $additionalProperties)
#media (prefers-color-scheme: dark)
#include themeProperty($dark, $property, $color, $additionalProperties)
There is a color map named "themes" which lists each color for light and dark themes for different use cases.
Furthermore, the mixins match the exact color for exact usage for the desired theme mode, whichever is being used by the client-side (browser or OS), thanks to #media queries.
For example, if you'd like to color a background-color using the button preset on the theme mapping, the usage is as follows:
#include theme("background-color", button)

Sass: rgba function is not working as per documentation

I have two examples that I'm trying to solve:
Example 1
$test: #101E41
body
--colors-dim: rgba(#{$test}, 0.64)
Output: rgba(#101E41, 0.64)
Example 2
body
--colors-active: #101E41
--colors-dim: rgba(var(--colors-active), 0.64)
Output: rgba(var(--colors-active), 0.64)
Both of these look like are examples that should be valid as shown here: https://sass-lang.com/documentation/modules#rgb
Is there something I'm missing?
You need to make use of interpolation to use Sass inside CSS Custom Properties
CSS custom properties, also known as CSS variables, have an unusual declaration syntax: they allow almost any text at all in their declaration values. What’s more, those values are accessible to JavaScript, so any value might potentially be relevant to the user. This includes values that would normally be parsed as SassScript.
Because of this, Sass parses custom property declarations differently than other property declarations. All tokens, including those that look like SassScript, are passed through to CSS as-is. The only exception is interpolation, which is the only way to inject dynamic values into a custom property.
$bar: #900;
:root {
--foo: #{rgba($bar, 0.5)};
}
Results in:
:root {
--foo: rgba(153, 0, 0, 0.5);
}
For your second example, you're going to have to get a little... creative... since Sass will bail and ignore any CSS Custom Property syntax it sees, you can't make use of Sass's rgba function with Custom Properties - the Sass compiler won't resolve the values for you.
Thankfully, you can still use the native CSS rgba function with Custom Properties, the only downside is that you'll need to break your hexadecimal value into its R, G, and B values.
#function toRGB($color)
#return red($color), green($color), blue($color)
$bar: #900
:root
--foo: #{$bar}
--foo-rgb: #{toRGB($bar)}
--foo-dim: #{rgba($bar, 0.5)}
--foo-dim: rgba(var(--foo-rgb), 0.5)
.button
background-color: var(--foo-dim)
Compiles to:
:root {
--foo: #900;
--foo-rgb: 153, 0, 0;
--foo-dim: rgba(153, 0, 0, 0.5);
--foo-dim: rgba(var(--foo-rgb), 0.5);
}
.button {
background-color: var(--foo-dim);
}
https://www.sassmeister.com/gist/39ffc57c492de73066831afe5a9696f6

Error: argument `$color` of `darken($color, $amount)` must be a color

I have the same problem as this question: Sass color variable not working inside darken()
But the difference between me and this question's poster is that I use the color already as color (not as string).
My code looks like this:
body {
#each $name, $num, $color in ('ClassName1', '01', #f39c12) ('ClassName2', '02', ) {
&.#{$name} {
background-color: darken($color, 10%);
background-image: url('img/bg-#{$num}');
}
}
}
Of course I already removed the unnecessary stuff. I am still getting this error:
Error: argument `$color` of `darken($color, $amount)` must be a color
I got the same problem with rgba:
Error: argument `$color` of `rgba($color, $alpha)` must be a color
Edit.: Now i see that i get this problem not because anything is wrong with my code... i just forgot to place any color in the second array... #each $name, $num, $color in ('ClassName1', '01', #f39c12) ('ClassName2', '02', #FORGOT-THIS)
Install 4.0.0-alpha.6 version of bootstrap. it should fix the issue.
npm install bootstrap#4.0.0-alpha.6
You would be using 4.0.0+ version of bootstrap
I have used it and it worked for me , please share your error details if still not works for you. :)

Shortening code by using a variable for including mixin

I'd like to know if there is a way to include a mixin (compass or my own) by a value of a specific variable.
Currently I have the following mixin (which works)
#mixin aligned-top-bottom-border($size, $side){
#if $side == "left"{
#include border-top-left-radius($size);
#include border-bottom-left-radius($size);
}
#else{
#include border-top-right-radius($size);
#include border-bottom-right-radius($size);
}
}
I'd like to turn it to something like the code below (or any other alternative that is shorter and more readable)
#mixin aligned-top-bottom-border($size, $side){
#include border-top-#{side}left-radius($size);
#include border-bottom-#{side}-radius($size);
}
I'm using Sass 3.4.5 (Selective Steve)
Sass documentation has this to say about interpolation:
You can also use SassScript variables in selectors and property names
using #{} interpolation syntax
Nothing about using them in mixins or functions. But there is nothing stopping you from adding your own vendor loop to the mixin instead of using the compass mixin. Like this:
#mixin aligned-top-bottom-border($size, $side){
#each $vendor in ('-webkit-', '-moz-', '-ms-', '-o-', ''){
#{$vendor}border-top-#{$side}-radius: $size;
#{$vendor}border-bottom-#{$side}-radius: $size;
}
}
It gets a bit DRYer but a lot bigger in final output. But it possible.

Resources