Currently, I've a list of colors (for example):
#colors: {
base: #716aca;
brand: #716aca;
danger: #c14549;
warning: #ffb822;
success: #34bfa3;
primary: #5867dd;
black: #000000;
}
I have each function that iterates over all the colors and makes all the possible rule colors that we can use:
each(#colors, .(#value, #key, #index) {
.rules-here-#{key} {
attribute: #value;
}
}
What I can't make work is something like this:
.getColor(#color);
Where I would use on other places, like:
div.system-warning-notification {
background-color: .getColor('base');
color: .getColor('danger');
}
I have no idea if this is even possible. I have been losing my mind over this for over a week now without any progress.
If that isn't possible, can I generate the variables so I can access them like:
#color-base: #716aca;
Without having to manually create them?
Thank you very much and I hope I asked this right. I am new here.
Related
There is a way to specify the usage of variables only for certain properties.
It is used to not overwrite say a padding with a color variable.
So if you would declare a variables like this:
--myColor: red
you could not use the variable in a padding like this:
.p {
/* should NOT be possible */
padding: var(--myColor);
}
Could someone help me out with the name of this feature, please?
So, basically the code will be more complex then --myColor: red.
I think I remember something like an object structure (but I might be wrong):
myColor { color: red; elements: color }
I found the answer, see here explanations https://youtu.be/3IUxyBx_PnM?t=1660
CSS.registerProperty({
name: "--stop-color",
syntax: "<color>",
inherits: false,
initialValue: "black"
})
it's actually Houdini CSS
I am new to using CSS pre-compilers and started using Less. I found Sass code to add themes to my web app and it works great.
https://codepen.io/dmitriy_borodiy/pen/RKzwJp
I am trying to convert it to Less and having difficulty rewriting it. I have gone through Less documentation but sorry to say that I am not even able to create a multilevel themes variable.
sass variable is as follows:
$themes: (
light: (
backgroundColor: white,
textColor: #408bbd
),
dark: (
backgroundColor: #222,
textColor: #ddd
),
);
Below conversion is totally wrong but this is what I have tried:
#set: {
light: {
backgroundColor: white,
textColor: #408bbd
},
dark: {
backgroundColor: #222,
textColor: #ddd
},
}
EDIT:
Example of what I am trying to achieve:
.theme(key) {
return all outcomes using #themes variable.
}
div {
background: .theme(divBackgroundColor)
}
it should return the following css :
.light-theme div{
background: white
}
.dark-theme div{
background:grey
}
Any help is appreciated.
A question like this ...
... ("I'm learning a language X and I found some program in language Y that looks like what I need. How to do the same thing using X?") is pretty much impossible to answer in (and too broad for) the SO format, as soon as the snippet goes beyond a single distinct minimalistic statement/feature.
Either way, to not leave the Q unanswered:
To be able to write a similar code in Less you will need to get familiar with the following features:
Maps
Rulesets as values/parameters
plus all typical language basic facilities like variables, functions, scope etc. etc. and the last (but not the least) Mixins.
Answering how to make something like background: .theme(backgroundColor) to do what you need would require explaining all of this from scratch (i.e. turning the answer into a book or a very loooong tutorial). Technically, you should not really be able to miss that the code in the linked snippet is a waaaaaay more complex than just background: .theme(backgroundColor).
And here's a (minimalistic) Less equivalent of the snipped at CodePen you pointed to.
(No comments there. They are pointless since nothing magic happens in it - to understand what it does you just need to get familiar with the languages features I listed above):
#theme: {
#light: {
backgroundColor: white;
textColor: #408bbd;
}
#dark: {
backgroundColor: #222;
textColor: #ddd;
}
}
// ....................................
// usage:
.themify({
div {
background: .theme[backgroundColor];
}
span {
color: .theme[textColor];
}
// etc.
});
// ....................................
// impl.:
.themify(#style) {
each(#theme, {
#name: replace(#key, '#', '.');
.theme() {#value()}
#{name}-theme {#style()}
});
}
For other possible techniques and solutions related to similar "Theming" use-cases see also:
Variables based on ancestor class
How to thematize in ...
and other Q/As linked/referenced there.
Try this code
#light: #f9f9f9;
#dark: #333333;
.theme(#theme: #color, #background: #background) {
color: #theme;
background: #background;
a {
color: #theme;
}
}
.light-theme {
.theme(#theme: #light, #background: #dark);
}
.dark-theme {
.theme(#theme: #dark, #background: #light)
}
<div class="light-theme">
Light Theme<br> Light Theme
</div>
<div class="dark-theme">
Light Theme<br> Light Theme
</div>
I'm trying to generate a rather automated system to define colours in SASS. I have a list of colours, defined with a hexidecimal value (like so: $color--deep-ocean: #123143;) and a global $colors: (); definition.
I then want to create their RGBA values dynamically, and given variable interpolation isn't an option in SASS, I've tried my hands at maps.
The idea is to feed a set-color function a name and a color to populate my $colors variable with map-merge, which I can then retrieve with get-color. Here below are my two function definitions and how I'm trying to use them:
#function color-set($name, $hex) {
$submap: (hex: $hex);
#for $o from 0 to 20 { // Going in increments of 5
$percentage-decimal: $o*0.05;
$percentage: $o*5;
$submap: map-merge($submap, ($percentage: rgba($hex, $percentage-decimal)));
}
$colors: map-merge($colors, ($name: $submap));
/* We should then have a map that looks like this:
$colors: (colorname: (
hex: #000000,
0: rgba(0,0,0,0),
5: rgba(0,0,0,.05),
// and so on…
100: rgba(0,0,0,1)
)
)
… right? */
}
#function color-get($name, $opacity: hex) {
#if $opacity != hex { // Returns RGBA value
#return map-get(map-get($colors,$name), $opacity);
}
#else { // Returns hexidecimal value
#return map-get(map-get($colors,$name), hex);
}
}
Please let me know if my functions are confusing! I'll try to comment them better.
This is how I'm trying to define a colour (part of _variables.scss):
color-set(bkgrnd, $color--deep-ocean);
And here's how I'm trying to use my colours:
body { // These colours have been defined, too …supposedly
background-color: color-get(bkgrnd, 80);
color: color-get(white);
}
Here is the error I get on _variables.scss:
Invalid CSS after "...ackground color": expected 1 selector or at-rule, was "color-set(bkgrnd, $"
So I feel like I'm missing something. I've had my head wrapped around this for four hours and I'm going mad. It's probably super simple stuff but I can't seem to figure it out. I use SASS casually, so I might not be aware of some syntax issue but if anyone has a clue about how to fix this, I'd be quite grateful.
Have a nice day and thank you for taking the time to read my post!
Regards,
Chris
PS: I compile this in Brackets with the Brackets SASS plugin, if ever that information is relevant.
After digging some more, I found out what my issue was. SASS functions must have a #return directive in order to work. As a result, I updated my color-set function, and added #return $colors; at the end of it. Then, I just needed to give some directive so the function wouldn't be called "out of the blue", so I assigned my $colors variable to it like such:
$colors: color-set(bkgrnd, $color--deep-ocean);
I think it might be a bit repetitive to reassign $colors to itself all the time, but given this only affects performance during compilation, and not on my final CSS file, I can get away with it. There might be a better way (and I'm all ears if you have an idea!) but for now this fits my needs just fine.
And like that, I am able to handle my colors using maps. Thanks to anyone who had a look at my problem, and sorry for posting this - I should have taken some time to cool down and think some more. I hope this helps someone else who is stumbling on the same problem to fix their issues!
Take care,
Chris
PS: If ever you wanted it, below is the full code.
_colors.scss
$color--deep-ocean: #123143;
$color--yellow: #ffce00;
// And so on, and so forth…
_mixins.scss
#function color-set($name, $hexval) {
#return map-merge($colors, ($name: $hexval));
}
#function color-get($name, $opacity: hex) {
#if $opacity != hex { // Returns RGBA value
$opacity-decimal: $opacity/100;
#return rgba(map-get($colors,$name), $opacity-decimal);
}
#else { // Returns hexidecimal value
#return map-get($colors, $name);
}
}
_variables.scss
$colors: color-set(bkgrnd, $color--deep-ocean);
$colors: color-set(main, $color--yellow);
// And so on, and so forth again…
Usage example:
body {
background-color: color-get(bkgrnd); // Returns #123143
color: color-get(main); // Returns #ffce00
}
button {
border: 2px solid color-get(main, 50); // Returns rgba(255, 206, 0, 0.5)
}
I have a problem with scsslint in this variable
ColorVariable: Color literals like blue should only be used in
variable declarations; they should be referred to via variable
everywhere else.
I have this sass palette:
$color-palettes: (
blue: (
light : lighten($grey, 6%),
base : $grey,
),
);
//using sass palettes
p {
color: palette(blue);
}
//wrong way
p {
color:blue;
}
// right way by scsslint I totally agree
// creating the variable
$blue:#0055FF;
p {
color:$blue;
}
the problem is I am passing the value palette(blue); and this make scsslint complain about blue.
I know I can change the scss-lint.yml to false ans solve that
ColorVariable:
enabled: false
but the problem I want avoid bad practices like:
p {
color:blue;
}
p {
color:white;
}
so in that case what the best I should do? to Keep Using the validation in my file jumping some classes that ColorVariable?
Thanks.
I'm just getting started with Sass and Compass, and I'm loving it. Something I'd like to do is take advantage of the #each function to simplify repetitive tasks. However, I've only seen examples of #each inserting one variable, and I'd like to be able to use multiple variables.
The standard way (from the Sass Reference):
#each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
Which is great, but I'd like to be able to do something like:
#each {$animal $color} in {puma black}, {sea-slug green}, {egret brown}, {salamander red} {
.#{$animal}-icon {
background-color: #{$color};
}
}
Is this possible?
Just came across this, have the answer for you. In Sass, you can actually have a multidimensional list, so instead of constructing individual variables, you'd create one variable to hold them all, then loop over them:
$zoo: puma black, sea-slug green, egret brown, salamander red;
#each $animal in $zoo {
.#{nth($animal, 1)}-icon {
background-color: nth($animal, 2);
}
}
You can have multidimensional lists just like you would have single dimensional lists as long as each nested dimension is separated in a different manner (in our case, commas and spaces).
UPDATE Oct 24, 2013
In Sass 3.3, there is a new data type called maps which are a hashed set of items. With this, we can rewrite my previous answer in the following way to much more closely resemble the desired result:
$zoo: ("puma": black, "sea-slug": green, "egret": brown, "salamander": red);
#each $animal, $color in $zoo {
.#{$animal}-icon {
background-color: $color;
}
}
You can see this in action over at SassMeister
I'm in the same boat (beginner to Sass/Compass) and had to do something similar. Here's what I came up with, using nested lists:
$flash_types: (success #d4ffd4) (error #ffd5d1);
#each $flash_def in $flash_types {
$type: nth($flash_def, 1);
$colour: nth($flash_def, 2);
&.#{$type} {
background-color: $colour;
background-image: url(../images/#{$type}.png);
}
}
It's not the most elegant solution but it should work if you can't find anything else. Hope it helps! I'd appreciate a better method too :)
Another way I used if anyone needs it:
$i:0;
#each $name in facebook, twitter, google_plus, instagram, youtube, pinterest {
$i:$i+1;
}
This functionality is supported for Sass 3.3.0 and above (I just updated from 3.2.14 to 3.4.4 in order to use it).
#each $animal, $color in (puma, black), (sea-slug, green), (egret, brown), (salamander, red) {
.#{$animal}-icon {
background-color: $color;
}
}
I'd recommend to check the changelog for backwards incompatibilities, if you're updating Sass.
Sass reference for multiple assignments with #each
Another solution could be to create different lists and "zip" them.
//Create lists
$animals: puma, sea-slug, egret, salamander;
$animals-color: black, green, brown, red;
//Zip lists
$zoo: zip($animals, $animals-color);
//Do cycle
#each $animal, $color in $zoo {
.#{$animal}-icon {
background-color: $color;
}
}
Probably this solution is more complicated to mantain than the others, but if you use a list more than one time, you can save time. (was my case)