Is there a way to Get a variable that is set in the global scss file from a ts file in Angular (8)
I'm looking to use some of the defined variables dynamically in a canvas element defined in the ts code.
I have a way to do this using a styles service based on
https://en.programqa.com/question/52907585/
Within Global.SCSS
#mixin ExportVariables($map, $prefix: null) {
$mapPrefix: "--#{$prefix}";
#if ($prefix){
$mapPrefix: "#{$mapPrefix}-";
}
body {
#each $name, $value in $map {
#{$mapPrefix}#{$name}: $value;
}
}
}
--idle-state: #29ABE2;
// Import each of these in the theme service
$stateSCSS:(
idle: var(--idle-state),
);
#include ExportVariables($stateSCSS, 'stateSCSS');
In the Service
const bodyStyles = window.getComputedStyle(document.body);
this.stateSCSS = {
idle: bodyStyles.getPropertyValue('--stateSCSS-idle'),
};
I think this answers your questions: access SASS values ($colors from variables.scss) in Typescript (Angular2 ionic2)
TLDR:
Unfortunately, there is no way to access SASS variable directly from typescript/javascript code. However, we can make a workaround to access those variables.
You can view the workaround in the post mentioned above
Related
I'm trying to pass some CSS Custom Properties to a SASS Mixin. I'm able use the variables when applied directly in the styling I want. But when I try to use a variable in an If statement, it doesn't work.
Mixin Example:
#mixin bg-color($hue, $status) {
background: hsl($hue, 50%, 50%); // $hue works as expected
#if $status == 'danger' { // doesn't work!
color: 'red';
} #else if $status == 'warning' { // doesn't work!
color: 'orange';
} #else { // always enters the else branch
color: 'black';
}
}
CSS:
:root {
--hue: 195;
--status: 'default';
}
.demo {
#include bg-color(var(---hue), var(---status));
}
If I manually add the status value to the mixin, it works:
.demo {
#include bg-color(var(---hue), 'danger');
}
Any idea what might be the issue?
UPDATE: As #temani-afif mentioned, this approach isn't possible because SASS files are compiled before CSS variables are used.
If you have some file, where you import all SCSS files, it depends which is imported first and which are imported after.
Make sure that one that you need to be Read by VS is first.
For example i needed to read first my variables, so it have to be first, other way, my code read mixin, and doesnt know yet what is '$blue'.
I am working with ionic 4 project and scss. I am having some strange behaviour, while I am trying to create a global CSS variables using #each:
:host {
$colors-availability: (
early-day: #e8ab00,
long-day: #854fa5,
whole-day: #fe307b,
all-day: #32773e,
morning: #87cc93,
afternoon: #4bb15d,
late: #fa8072,
twilight: #40e0d0,
night: #16151b
);
#each $name, $color in $colors-availability {
--ion-color-#{$name}: $color;
}
}
This is my code in theme/variables.scss file. I am expecting to have all these variable with respecting colours, but the output is this:
I don't have the hash colour values. Any idea? I tried everything(color() function, etc..). Thanks.
Try something like this as below:
--ion-color-#{$name}: #{$color};
On my project, I need to generate a second Sass file with theme-specific code, which will be generated when Sass (inside a Gulp task) is processed.
#mixin theme-set($key, $value) {
#if not global_variable_exists(theme-config) {
$theme-config: () !global;
}
// magic stuff here, which will be appended to $theme-config
}
.class1 {
#include theme-set(foo, bar);
}
.class2 {
#include theme-set(bar, baz);
}
The mixin theme-set will generate Sass map key-value pairs that will be appended to $theme-config.
Now, my issue is that I need to pass $theme-config back to the Gulp stream so I can generate a separate theme.sass (or theme.css) file as override stylesheet of the main.css
Then, the $theme-config should be imported in another file (ideally in the same stream, or passing it to another stream in the same task, using merge-stream) that would then generate theme.css.
Any advice on how to do this?
I'm trying to create a mixin in Sass to generate multiple background, problem is the number of background is unknow, it's can be 3, 4 or even 5. Here what I try and fail.
#mixin multiBg($page: index, $sec: sec01,$from: 1, $to: 3, $type: jpg){
$url: (); // i'm try to create a empty array first
$newUrl: null; // and an empty variable
#for $i from $from through $to {
$newUrl: append($url, url(../img/#{$page}/#{$sec}_bg0#{$i}.#{$type})); // then append value to variable;
}
background: $newUrl;
}
#sec05 {
#include multiBg(index,sec05);
}
current output:
background: url(../img/index/sec05_bg03.jpg);
expected output:
background: url(../img/sec05_bg01.jpg),url(../img/sec05_bg02.jpg), url(../img/sec05_bg03.jpg);
I don't know how to fix this problem since i'm still learing SASS. Can someone enlighten me please.
You're on the right track! But your syntax and logic are slightly off. Here's what I came up with:
#mixin multiBg($page: index, $sec: sec01, $from: 1, $to: 5, $type: jpg) {
$url_list: ();
#for $i from $from through $to {
// I broke constructing the url and adding it to the set into two steps here.
// We could do this all at once, but separating it can make it easier to read.
// First, generate the url.
$url_string: url(../img/#{$page}/#{$sec}_bg0#{$i}.#{$type});
// Then add it to the list (the 'comma' part is important)
$url_list: append($url_list, $url_string, comma);
}
// Done looping? Output the final list!
background-image: $url_list;
}
That seems to return what you're looking for. Here are the official docs on list functions - I always forget one or two, may be useful for you too.
Also, since you mentioned you're new to sass - check out Sassmeister if you haven't already. It's a handy little sandbox for quickly prototyping and trying things out in sass; similar to Codepen but a bit more specialized. It's what I used to experiment with this question.
This is a cleaner answer, I believe.
#mixin image-resolve($image) {
$images: ();
#each $i in $image {
$path: ();
$images: append($images, $path, comma);
}
background-image: $images;
}
I'm trying to make a library of react components that's external to an application. This will be an npm module, loaded with Webpack. I'm styling the component using CSS Modules, and I'm trying to see how to make some of its properties customizable. For instace, background color.
I would like to use css variables for this to have for instance this syntax in the css file:
.myClass {
backgrond-color: var(--backgroundColor, red);
}
Where --backgroundColor is a variable I can set, and red is the default. My question is, is there a way I can pass variables to the .css file when loading it from the .jsx file? So I could pass a variables object to the component, which then would influence how it loads it style? Could I use PostCSS for this?
Thanks.
PS: I know this could be solved by using inline JS styles, but I'm trying to give CSS a shot first.
You cannot inject javascript into a css file and PostCSS can only transform your css files, but not inject/replace variables.
However, one way of doing this would be to create .scss (sass) files with default variables, e.g. $background-color: red; One could then import your module and .scss files to their .scss files and overwrite any variables like $background-color with their own variables if they wish.
I'm not sure I understood you right, but here what I'm thinking of:
When you are requiring .css file with Webpack it adds this css as a string to the <head> element of the page behind the scene.
Why don't you do what Webpack does using your own function, like so.
Your module:
import $ from 'jquery';
/* this function builds string like this:
:root {
--bg: green;
--fontSize: 25px;
}
from the options object like this:
{
bg: 'green',
fontSize: '25px'
}
*/
function buildCssString(options) {
let str = ':root {\n'
for(let key in options) {
str += '\t--' + key + ': ' + options[key] + ';\n'
}
str += '}';
return str;
}
/* this function adds css string to head element */
export const configureCssVariables = function(options) {
$(function() {
var $head = $('head'),
$style = $('<style></style>');
$style.text(buildCssString(options));
$style.appendTo($head)
});
}
Usage:
import {configureCssVariables} from './your-module';
configureCssVariables({
bg: 'green',
fontSize: '25px'
});
And your css is simple
/* default variables that will be overwritten
by calling configureCssVariables()
*/
:root {
--bg: yellow;
--fontSize: 16px;
}
.myClass {
backgrond-color: var(--bg);
font-size: var(--fontSize);
}
It can be acheived by adding PostCSS and the postcss-custom-properties plugin in your pipeline. It has a variables option which will inject JS defined variables (properties) to any file being processed.
This eliminate the need to #import anything inside every CSS module file.
const theme = {
'color-primary': 'green',
'color-secondary': 'blue',
'color-danger': 'red',
'color-gray': '#ccc',
};
require('postcss-custom-properties')({
variables: theme,
});
See how to use it with babel-plugin-css-modules-transform https://github.com/pascalduez/react-module-boilerplate/blob/master/src/theme/index.js and https://github.com/pascalduez/react-module-boilerplate/blob/master/.babelrc#L21 but that works with Webpack as well.
I actually found a solution that already does this and takes advantage of the latest standardized JavaScript features
https://github.com/styled-components/styled-components
It may just be what I was looking for.