Read this article => https://davidwalsh.name/sass-color-variables-dont-suck
This will help developers with easy additional customization and also things will be better organized and most importantly this convention is unique and memorable
Here's what i am suggesting for the foundation pallete,
Update: Updated code as per @ncoden comments about unused colors. Removed non used color variables ( for eg: $pink. Let user add them themselves as per there needs.
_All the colors here i am using is current set of foundation colors_
// Assign color names to specific hex values.
$black: #0a0a0a !default;
$white: #fefefe !default;
$blue: #1779ba !default;
$green: #3adb76 !default;
$orange: #ffae00 !default;
$red: #cc4b37 !default;
// grayscale
$gray: #767676 !default;
$light-gray: #e6e6e6 !default;
$medium-gray: #cacaca !default;
$dark-gray: #8a8a8a !default;
// Reassign color variables to semantic colors in foundation pallete
$foundation-palette: (
primary: $blue,
secondary: $gray,
success: $green,
warning: $orange,
alert: $red,
);
Benefits ( same like *custom grid ):*
Special Note: Final code might be different but hope you get my idea.
👎 We cannot pollute the Sass namespace with color global variables. If developers want a custom color palette, they can define it themselves. There is no need to rely on Foundation.
Just now you added two labels .... if you see carefully those two labels has a color different than the current foundation pallete
or, maybe somebody wants a different primary/secondary color than the current one
or, maybe somebody create a site with a blue color and then his boss says to change it to a variant of red
There are many scenarios out there where you want to change colors and need to add colors and surely this can be the best use case .
=> Mine is thumbs up for this :+1:
There is no such pollution !
I agree there _are many scenarios out there where you want to change colors_. All I am saying is that if you need other colors, you can declare your own color variables and use it where it is needed.
$my-blue: #0000FF;
// On your own label
.my-label {
background: $my-blue;
}
// On Foundation label
$label-background: $my-blue;
And yes: any global variable without prefix pollutes the global namespace ;) .
I am just asking you to be semantic!
I agree there are many scenarios out there where you want to change colors. All I am saying is that if you need other colors, you can declare your own color variables and use it where it is needed.
And yes: any global variable without prefix pollutes the global namespace
If that's the case then, lets remove the colors which foundation isn't using but still do it this way because this will be more semantic and easily customizable ?
My Updated code in that case then
// Assign color names to specific hex values.
$black: #0a0a0a !default;
$white: #fefefe !default;
$blue: #1779ba !default;
$green: #3adb76 !default;
$orange: #ffae00 !default;
$red: #cc4b37 !default;
// grayscale
$gray: #767676 !default;
$light-gray: #e6e6e6 !default;
$medium-gray: #cacaca !default;
$dark-gray: #8a8a8a !default;
// Reassign color variables to semantic colors in foundation pallete
$foundation-palette: (
primary: $blue,
secondary: $gray,
success: $green,
warning: $orange,
alert: $red,
);
All the colors here now i am using is current foundation colors
and as you said if somebody wanna use other color they can do it like this
$purple: #613d7c;
$foundation-palette: (
primary: $purple,
);
Hmm... Semantic color are primary, error, info... "Semantic" does not mean that we give them a name, but that they are a part of the application semantic, they refer to a status.
We can assume that any application using Foundation rely on this semantic. But the color itself ($blue is blue, $red is red...), we cannot assume it:
$blue to contain an other color than blue.But atleast we can assign and fix them!
$red: #ff0000;
$green: #00ff00;
$blue: #0000ff;
$primary: blue;
and the over ride by user
$primary: $green;
Its has a very simple and better organized use case
But the color itself ($blue is blue, $red is red...), we cannot assume it.
If we gonna assume that we can't assume the user's head and thus can't do the affirmation. There will be no success bro
$primary: $green;
// my-app.scss
$my-green: #FEDCBA; // This is my app and I am sure it is green, so I call it `$my-green`.
$foundation-palette: (
primary: $my-green; // I use my green as primary color
...
);
I am sorry but I do not understand the benefits of named color variables.
And i am sorry but i am repeating my above comment
If we gonna assume that we can't assume the user's head and thus can't do the affirmation. There will be no success bro
Your above :arrow_up: example just showing up that you are assuming about user's head.
Its there headache if they are thinking that #FEDCBA is Green rather than Sandy beach.
It not the framework fault.
Read this article => https://davidwalsh.name/sass-color-variables-dont-suck
Wouldn't it be nice if you could name your variables after colors like you were trying to do at the start, but without all the naming difficulty?
Now your variables are named after colors, but they're unique and memorable
Yes the article is little bit different regarding the current affirmation i made but it perfectly fits what i am recommending here => unique and memorable
Moreover @ncoden we can recommend ( in comments/docs ) command line utility like
https://www.npmjs.com/package/namethatcolor
for letting them name the correct color with a correct name if they wanna add there own variables ?
Its there headache if they are thinking that #FEDCBA is Green rather than Sandy beach.
It not the framework fault.
I choosed an HEX color randomly. The point is they declare their own, use them like them want, and there is no non-semantic color variable we could provide that would be useful to them.
Named colors are useful in the end app, I agree, but they does make any sense in a library.
The point is they declare their own, use them like them want, and there is no non-semantic color variable we could provide that would be useful to them.
But if we can provide a recommendation like Name That color
( https://www.npmjs.com/package/namethatcolor )
Then it might be useful as mentioned in my above comment!
Benefits ( same like custom grid ):
@DaSchTour i would like to know your thoughts buddy on this ?
Thanks @IamManchanda for bringing this up.
I Have to say that this will help change the whole site main colors ( primary/secondary/success ) with ease. Quite useful for templates.
@RamanCool Why not declaring by yourself the colors you need ?
Yes the article is little bit different regarding the current affirmation i made but it perfectly fits what i am recommending here => unique and memorable
...
Moreover @ncoden we can recommend ( in comments/docs ) command line utility like [ Name That color ]
I agree this package should be recommanded.
- We are allowing them to modify current foundation pallete colors.
map-merge($foundation-palette, ('primary', $my-color));
- We are allowing them to create custom color variables for foundation pallete.
map-merge($foundation-palette, ('my-semantic-state', $my-color));
If the user want color variables with a good name, ze can declare it. The best we can do for them is to provide all the colors that have an official name as prefixed variables, but in an external package since it is not used inside Foundation and not specific to Foundation projects. I can even create that package for you if you want !
Moreover @ncoden we can recommend ( in comments/docs ) command line utility like [ Name That color ]
I agree this package should be recommended.
That would be great sir !
We are allowing them to modify current foundation pallete colors.
map-merge($foundation-palette, ('primary', $my-color));
We are allowing them to create custom color variables for foundation pallete.
map-merge($foundation-palette, ('my-semantic-state', $my-color));
If that's the case buddy, then this should be documented in the docs as there is no current documentation for the same. There is only get-color() function is the docs and nothing else i can find for the same.
The best we can do for them is to provide all the colors that have an official name as prefixed variables, but in an external package since it is not used inside Foundation and not specific to Foundation projects. I can even create that package for you if you want !
That would be great sir but will it be referenced within foundation docs ?
If that's the case buddy, then this should be documented in the docs as there is no current documentation for the same. There is only get-color() function is the docs and nothing else i can find for the same.
You are right, it should at least be in an example.
That would be great sir but will it be referenced within foundation docs ?
This would be a package unrelated to Foundation, so I don't think we should put it its the current doc. But maybe we could add some page about the good practices in Foundation projects ?
You are right, it should at least be in an example.
Will be great if you can create PR for the same
This would be a package unrelated to Foundation, so I don't think we should put it its the current doc. But maybe we could add some page about the good practices in Foundation projects ?
That would be great sir!!
Instead of creating multiple variables, I would rather keep them within a map. This way you aren't using global variables as well.
For example:
$color-palette: (
'blue': #2199e8,
'green': #3adb76,
'yellow': #ffae00,
'red': #ec5840,
'white': #fefefe,
'grey': #8a8a8a,
'black': #0a0a0a
);
$foundation-palette: (
'primary': get-color('blue'),
'secondary': get-color('grey-dark'),
'success': get-color('green'),
'warning': get-color('yellow'),
'alert': get-color('red')
);
Note: I do realize get-color() currently gets the color from the Foundation palette, but the function could be modified to return a value from either, or have a separate function for getting the color from the color palette, or foundation palette.
@ncoden, @IamManchanda: Thoughts?
@natewiebe13 This is like using a namespace. It prevent to pollute the global namespace, but do not solve the problem of the concept itself of providing named colors that we cannot use inside Foundation and are only useful in the end application.
@ncoden, I think it may be beneficial to add since it's much more flexible than specifying colors directly to states, though I do understand your point. This is always step 1 for us when we import foundation, is to create a new color palette and overwrite the $foundation-palette variable to get the color from a map.
Even if we were to leave it as is, what are your thoughts on changing the name of the get-color() function to something else, as this function doesn't really return a color, but rather a state color. Ex: get-state-color(), get-palette-color().
I can make a PR for this if you think any of these would be okay.
I agree there is currently confusions with the color functions and variables. $foundation-palette has been already taken for a color palette dedicated to the end application, and get-color really need a less generic name.
@DaSchTour What do you think ?
i agree with @natewiebe13 !
Infact my code might might be different but my thoughts are similar to mr nate!!
I can make a PR for this if you think any of these would be okay.
That would be great, infact awesome sir.
@ncoden I guess the problem here is, that foundation-palette doesn't only define a color palette but also "creates new elements". So I guess the best solution would be to create a map that defines the color names, assigns a color value and defines in which components it should create new elements. Something like:
$foundation-palette: (
primary: (color: #1779ba, components: (buttons, callout)),
secondary: (color: #767676, components: (buttons)),
success: (color: #3adb76, components: (buttons, callout)),
warning: (color: #ffae00, components: (buttons, callout)),
alert: (color: #cc4b37, components: (buttons, callout)),
light-gray: (color: #e6e6e6),
medium-gray: (color: #cacaca),
dark-gray: (color: #8a8a8a),
black: (color: #0a0a0a),
white: (color: #fefefe),
);
Than the get-color function would retrieve the color values and all colors used in a project would be in one map.
Another solution could be, that $foundation-palette would remain as it is.
$foundation-palette: (
primary: #1779ba,
secondary: #767676,
success: #3adb76,
warning: #ffae00,
alert: #cc4b37,
light-gray: #e6e6e6,
medium-gray: #cacaca,
dark-gray: #8a8a8a,
black: #0a0a0a,
white: #fefefe,
);
And the configuration would be per component like:
$button-colors: (primary, secondary, success, warning, alert);
$callout-colors: (success, warning, alert);
$label-colors: (primary, secondary, success, warning, alert, black);
I guess this could even solve #9646 and #9608
For example by adding:
$button-colors: (facebook, twitter, google-plus);
$text-colors: (light-gray, black);
$background-colors: (light-gray, black);
So in the end it's not get-color which has a to generic name but the fact, that $foundation-palette does mire than it should?
@DaSchTour
I guess this could even solve #9646 and #9608
You are a rockstar bro !!!
$botton-colors: (primary, secondary, success, warning, alert); $botton-colors: (facebook, twitter, google-plus);
Typo correction, this should be $button-colors instead !
Please, i would urge and humbly request you to please have a PR.
{{ Because. as always.... i think you are the right person for it! }}
@IamManchanda Thanks. I'll wait for some feedback to see which variant is the preferred one.
@DaSchTour So $foundation-palette become a simple reference between color names and values, and we precise in each components the color names it should use from the map.
I see two problem:
So like I said before: let's, at least, do mix semantic and named colors, because it is two different things, and at best do not is overload Foundation with things that are meaningless inside it and could totally be in a separated package.
See also: https://github.com/zurb/foundation-sites/pull/9459
@IamManchanda Please wait for a consensus before asking for a PR ;)
@ncoden Well by calling it semantic colors the whole concepts feels wrong. So I guess the solution should look like this.
$foundation-palette: (
blue: #1779ba,
gray: #767676,
green: #3adb76,
yellow: #ffae00,
red: #cc4b37,
light-gray: #e6e6e6,
medium-gray: #cacaca,
dark-gray: #8a8a8a,
black: #0a0a0a,
white: #fefefe,
);
$button-colors: (primary: blue, secondary: gray, success: green, warning: yellow, alert: red, promotion: black);
$callout-colors: (success: green, warning: yellow, alert: red);
$label-colors: (primary: blue, secondary: medium-gray, success: green, warning: yellow, alert: red);
The generic name of get-color is map-get and it's build into SASS already. get-color is a shortcut to not have map-get($foundation-palette, primary) over and over in your SCSS. get-color was never meant to generic and it only makes sense in combination with $foundation-palette. Adding an own color map also includes adding own features for simple access.
But on the other hand, maybe the definition of named colors with color names is also a very dangerous way. Just thinking of a line like this:
.class {
background-color: get-color(blue);
border-color: blue;
}
So maybe the foundation-palette should look more like this, to have meanings
(The examples are not the best, but I guess the concept should be clear)
$foundation-palette: (
primary: #1779ba,
secondary: #767676,
success: #3adb76,
warning: #ffae00,
alert: #cc4b37,
disabled: #e6e6e6,
text: #0a0a0a,
background: #fefefe,
);
While thinking about this, I think it's very bad, that $black is not black. It can introduce unwanted errors and makes finding errors hard. Just think of two components that should be the same. Embedded into many many lines of style this could be easily overseen.
.comp1 {
background: $white;
}
.comp2 {
background: white;
}
@DaSchTour In your first example, you are just throwing away the global map of semantic color and replacing them with a _color palette_. It still break inheritance.
But on the other hand, maybe the definition of named colors with color names is also a very dangerous way.
In this example, get-color(blue) is dangerous by itself if used inside Foundation. Because we build a component with the assumption that (blue) will be blue, so or we prevent the user to customize the color, or the color can be customized and using a blue color name does not make any sense.
So whatever the form it will takes, it will not be used inside Foundation. This is why I say it _can_, and maybe _should_ be provided in a plugin _or_ an other package.
In your second example, your are extending $foundation-palette with other semantic colors that are not used to build states. Why not, but take care how this map will be used, _modularity_ and _inheritance_ must still work. I means we still need two different global maps, with maybe one extending/filtering the other.
I've made something a little similar in a previous project, but with variables instead of a map, see: https://github.com/CaliOpen/caliopen.web-client-ng/blob/master/src/styles/config/theme/dark.scss
@IamManchanda Thanks. I'll wait for some feedback to see which variant is the preferred one.
@IamManchanda Please wait for a consensus before asking for a PR ;)
Sorry and no issue!
@ncode well that's why I suggested to have a palette with different named colors and than a map with states that are created from this colors.
What I don't clearly understand is what you mean with "breaking inheritance"?
The big question is, what is the goal of all this and what it the goal of foundation?
Do we want to have a SCSS that is as slim as the generated CSS?
Should everything be customizable and how easy should it be?
Can we expect users to create their own functions?
Going from the start of this issue I think there is nothing todo. Everybody could add the suggested settings to his own SCSS Setup and everything is fine.
I think the main problem that becomes obvious is, that there is not SPOT for colors. So at first we should consolidate all colors to $foundation-colors and get color from there with get-color(). Then the next step would be to fix the mixing of state, semantic and color and move to a modular configurable way.
Just while thinking about this, foundation already has a big gap there that could be filled very easy. Looking at forms there is $input-background-invalid: get-color(alert) !default; it's a state and access the color palette, but in this case there is just a 1:1 mapping. In other cases we already generate components for every state, or nearly every state. States that are defined in a variable called $foundation-palette, so it's not state. Why is there no easy possibility to say which input states I would like to have? $input-states: (success, warning, alert);? So looking at all the inconsistency and the possibilities I think there is a lot to improve.
Creating a $foundation-colors variable with simple access through get-color() is a great way to improve color handling a lot. It even encourages to put all colors used inside a project into $foundation-colors instead of spreading color definitions all over the project.
Every component already has a mapping between $foundation-palette and $component-palette. So the only think there is left to do is, to make this easier to use by creating a mapping configuration, that is then used to generate the palette for components from $foundation-colors.
@ncoden, @DaSchTour
I feel like there are a couple issues that need to be solved.
get-color('success') because they want to get a green color that is consistent with the theme. But what happens if the client wants to change it to another brand color? This becomes increasingly difficult to understand how a style was originally intended if you have a large group working on the same project.I would like to see something similar to this:
$foundation-colors: (
'blue': #1779ba,
'green': #3adb76,
'yellow': #ffae00,
'red': #cc4b37,
'grey': #767676,
);
$foundation-color-states: (
primary: get-color('blue'),
secondary: get-color('grey'),
success: get-color('green'),
warning: get-color('yellow'),
alert: get-color('red'),
);
.button.alert {
background-color: get-state-color('alert');
}
.custom-class-for-element {
background-color: get-color('blue');
}
Doing something like this wouldn't change how the palettes currently work, just how the original list is created. @ncoden, is this approach work without changing functionality too much?
@DaSchTour
What I don't clearly understand is what you mean with "breaking inheritance"?
For:
$botton-colors: (primary, secondary, success, warning, alert);
(or any other way to set state colors on components that cannot be used the same way and require a hidden processing).
If you add a new semantic color in the global palette, you also have to enable it in every single component. Component settings are no longer automatically inherited from global settings.
Creating a $foundation-colors variable with simple access through get-color() is a great way to improve color handling a lot. It even encourages to put all colors used inside a project into $foundation-colors instead of spreading color definitions all over the project.
True. But we have to keep _named colors_ and _semantic (state) colors_ separated. See below.
@natewiebe13
I like your example. To extend it with components and make things even more clear, I would propose something like this:
// scss/global
$foundation-states: (
primary: #1779ba, // or get-color(blue), see below.
secondary: #767676,
success: #3adb76,
warning: #ffae00,
alert: #cc4b37
);
// scss/component_label
$label-states: $foundation-states;
// scss/util/color
// not used inside Foundation
$foundation-colors: (
'blue': #1779ba,
'green': #3adb76,
'yellow': #ffae00,
'red': #cc4b37,
'grey': #767676,
(...all color names...)
);
// --- User side ---
// add states globally
$foundation-states: map-merge($foundation-states, (
apocalypse: #ffff00,
));
// add states to label
$label-states: map-merge($foundation-states, (
info: #0000ff,
disastrous: #ff0000
));
.my-component {
background: get-color(blue);
&--alert { background: get-state(alert); }
&--apocalypse { background: get-state(apocalypse); }
}
In that way:
✓ Components stay modular.
✓ Components settings stay inherited.
✓ State and named colors stay separated.
You changed my mind in one point: we can provide this Color Utility inside Foundation, by default (in this case we can use get-color for default settings) or as a plugin (like for Js plugins), with a lot of features to manage colors. But we have to make sure it is clear for our folks that it is not semantic colors
@natewiebe13 so what if we end up with the following. Ideally every declaration in another file.
$foundation-colors: (
'blue': #1779ba,
'green': #3adb76,
'yellow': #ffae00,
'red': #cc4b37,
'grey': #767676,
);
$foundation-color-states: (
primary: get-color('blue'),
secondary: #777777,
success: get-color('green'),
warning: get-color('yellow'),
alert: get-color('red'),
);
$light-gray: #e6e6e6;
$medium-gray: #cacaca;
$dark-gray: #8a8a8a;
$black: #0a0a0a;
$white: #fefefe;
$error-red: #ff0000;
Then while developing, we get to the point were we get an error while trying this
.error {
color: get-state(error);
}
.error-text {
color: get-color(error);
}
Two lists with two functions to access is a guarantee for errors.
@DaSchTour
Two lists with two functions to access is a guarantee for errors.
True. This is why we have to make clear that we have two different things:
In any case, putting named colors and states in the same map leads to even more problems in our side (using named color inside Foundation components) and enclose the user in the process we use to pick only states while generating components.
sorry guys i haven't fallowed along from some last 15-20 comments due to being a bit busy but what i can say that i am liking the final code where its going
But there are two main things should be taken care of
get-color(blue)@DaSchTour Please buddy can i get a bit code brief about how ( and how much) is this gonna solve ( implement) with social buttons ? Please Pleasee
Reason why i am asking this is because there is some difference there with regards to color utilities?
- The code that user of this repo would use should be very simple like for eg. get_color(blue)
Agreed. But the convention in CSS/Sass is lisp-case, so it would be rather be get-color ;)
Agreed. But the convention in CSS/Sass is lisp-case, so it would be rather get-color ;)
I Changed it already infact in a minute after commenting .... sorry that was by mistake bro ..... C'mon :stuck_out_tongue:
@ncoden, I do like your example. I still feel like we should be able to assign colors to the states from the colors like in my example. We would still end up doing this on our projects every time.
@DaSchTour, I've never been a fan of global variables for colors. Since they do exist in Foundation, I would use the get-color function to get the color from the colors map.
@ncoden, just so I understand, what is the reason you want to specify the hex code for the states directly, rather than pulling the appropriate color from the map? So, let's say that the success state should be green. We could use the green color from the map. When we implement the frontend to match branding, the green could change ever so slightly, but you would still want the green buttons to match the green branding. I don't ever foresee a time where you'd want to have two slightly different colors.
We would still end up doing this on our projects every time
@natewiebe13 But bro if this will be well documented , why would users be doing this in projects every time ?
yes there will be few exceptions but then those exceptions will be one like who use foundation but don't use our grid or even our custom sass grid code and instead make there own.....
I will say it again though that Documentation becomes a key role here when it comes to color customization! For eg. the current documentation is not solving anything .... even not the current implementations for customization
@IamManchanda I'm saying we would be overwriting the $foundation-color-states to use the color map instead of them being directly assigned every time. This way if we change the shade of green a bit, we change it in one spot, rather than two.
what is the reason you want to specify the hex code for the states directly, rather than pulling the appropriate color from the map?
It depend on how we consider the color names: as a plugin or an utility. If it is as an utility, we can use it to set default states.
@natewiebe13 yes you are write on that, infact spot on! We should really be considering that ..... this can specially helpful for buttons and backgrounds
Also something like grayscale output would be great for color variables
something like using $green as input but generating => `$light-green , $green, $dark-green color variables will be great also
Yes by default its should be only .... primary, secondary, success etc..... as globally
something like using $green as input but generating => `$light-green , $green, $dark-green color variables will be great also
See: scale-color. http://sass-lang.com/documentation/Sass/Script/Functions.html#scale_color-instance_method
@DaSchTour @natewiebe13 @IamManchanda
Does one of you want to open a PR (I can too)
I would like to have @DaSchTour for the PR !
sorry for being partial.....
I would like to have @DaSchTour for the PR !
I do not see any reason to choose someone to do a PR. Everything is reviewed in the end. Since we all know Sass enough, it will mainly depend on our availability.
I do not see any reason to choose someone to do a PR. Everything is reviewed in the end. Since we all know Sass enough, it will mainly depend on our availability.
Ohk no issue @ncoden ...... please open PR bro
please open PR bro
Same. Wait for answers of @DaSchTour and @natewiebe13.
@ncoden, I can quickly get something ready. I'm assuming this should be on v6.4, correct?
yes 6.4 ... (new) feature request....
@natewiebe13 Yep, make sure to be availaible for after the review too. ;)
And please try to do the least breaking changes possible.
I agree that using variables for $black and $white are contradictory. Rather use color: black if you want #000 or color: $darkest-gray if you want a shade of gray. However there should be more shades of gray in Foundation, eg:
$lightest-gray
$lighter-gray
$light-gray
$medium-gray
$dark-gray
$darker-gray
$darkest-gray
Foundations SASS variable names should stay semantic IMO and words like "blue" and "yellow" have no place in the framework. I set all my own color variables with names like $brand-blue and $site-green before importing Foundation's settings and then I basically just assign them to Foundation's semantic variables like $primary-color: $brand-blue, $success-color: $site-green.
Most helpful comment
@ncoden I guess the problem here is, that foundation-palette doesn't only define a color palette but also "creates new elements". So I guess the best solution would be to create a map that defines the color names, assigns a color value and defines in which components it should create new elements. Something like:
Than the
get-colorfunction would retrieve the color values and all colors used in a project would be in one map.Another solution could be, that
$foundation-palettewould remain as it is.And the configuration would be per component like:
I guess this could even solve #9646 and #9608
For example by adding:
So in the end it's not
get-colorwhich has a to generic name but the fact, that$foundation-palettedoes mire than it should?