i read this article http://www.sitepoint.com/dealing-color-schemes-sass/ and I wanted to try to apply the method but I've a question: It's possible use this with a variable?
Ex. I use bootstrap and i wanna change only value (without assign a property) for $brand-primary, can i change this value with this method?
I've assigned a dynamic class on my body ( or ), and i wanna change a $brand-primary value for every class...
Another Ex.
If body class is "en" $brand-primary: red; if body class is "it" $brand-primary: blue; if body class is "fr" $brand-primary: green;
It's possible?
Thanks for your reply.
Perhaps the cleanest way to accomplish this is to create a mixin, and then pass in theme color variables.
The theme mixin code takes in all necessary colors, as well as a name that corresponds to the body class:
#mixin theme($name, $brand-primary) {
body.#{$name} {
background-color: $brand-primary;
}
}
Create a separate Sass partial for housing your theme color variables. In this case, it would look something like this:
$brand-primary: green;
Create as many of these files as you have themes.
Using the themes is then as simple as:
#import 'Themes/_theme-name.scss';
#include theme("theme-name", $brand-primary);
Bonus - if you need to apply styles to a specific theme, it's as easy as an #if statement in the mixin:
#if ($name == "theme-name") {
.class-name {background-image: url(example.png);}
}
Related
I want to make a light mode for a website that uses SASS with variables in it. So, here are the variables and smth I tried (but doesn't work):
#media (prefers-color-scheme: dark), (prefers-color-scheme: no-preference) {
$bg: #0d0d0e;
$c0: #ffffff;
$c1: invert(#333);
$c2: #7c7c7c;
$c3: invert(#aaa);
$c4: invert(#eee);
}
#media (prefers-color-scheme: light) {
$bg: #fff;
$c0: #000;
$c1: #505050;
$c2: #66666a;
$c3: #aaa;
$c4: #eee;
}
I have to keep SCSS. Should I try #mixin?
That won't work with Sass variables during runtime since they are being compiled and then statically served. What you can do though is using CSS custom properties aka CSS variables. Those can be changed during runtime with Javascript (more versatile) or use media queries along with the boolean context value prefers-color-scheme. This value is unfortunately set by the user's browser environment and cannot be changed with Javascript.
You can however just switch the colors around with Javascript. With an onClick event you just save the state of current color in a buffer, assign the current color with the alternative color and then set the alternative color to the one saved in the buffer (aka the former current color).
I've tried switching around colors stored in CSS custom properties with a checkbox and the input:checked selector but the changes have only local scoping (thanks, W3C), so they won't do you any good - that is of course unless you want to wrap your whole website in your color switcher element.
The only way with Sass variables would be to recompile the Sass stylesheets when a user switches over the color scheme.
tl;dr: use CSS custom properties and either go with browser defaults in media queries or use a bit of Javascript. Everything else is very hacky.
I'm defining each theme side by side and using them inside #media (prefers-color-scheme).
Even made my self a mixin:
/** Helper to tigth properties to color preferences */
#mixin color-scheme($value: light) {
#media (prefers-color-scheme: $value) {
#content;
}
}
/** Usage */
.element {
/* ... */
#include color-scheme(dark) {
/* ... */
}
}
I wrote the code below in the file of “variables.scss” or “global.scss”:
ion-searchbar {
–placeholder-color: white;
–placeholder-opacity:1;
–icon-color:white;
}
it should make the text of placeholder with white color, however, it doesn’t work.
But, if I write the code just in the page css file, it does work.
Does somebody know why?
You have to put it within the :root pseudo selector, like this:
:root {
ion-searchbar {
--placeholder-color: white;
–-placeholder-opacity: 1;
–-icon-color: white;
}
}
This will ensure that any variables you set inside of :root will apply across your entire application.
Problem
About overriding !default variables -- I have two .sass files:
main.sass
$variable: black
#import "_another_import.sass"
#import "_import.sass"
_import.sass
$variable: blue !default
body
background: $variable
The $variable resolves to blue in the compiled CSS:
body {
background: blue;
}
However, if I specify the overriding variable value right before I import the _import.sass stylesheet, Sass compiles it to black:
main.sass
#import "_another_import.sass"
$variable: black
#import "_import.sass"
Question
Is this behavior intended? Is there a way to declare overrides for !default variable values earlier than the !default values are declared in imports (maybe even in a separate file)?
Actual setup (for reference)
My actual setup is a little bit more complicated than that. I am using Myg (NPM components) with myg-rails (generating file structure to customize variables) and Webpack. So I have a myg.sass file loading _variables.sass and _myg.sass. _variables.sass loads a couple of other files which define the variables. _myg.sass imports the Myg (NPM) components. I verified that when I define a variable in _variables.sass and use it + set a default in a Myg component, the default will override the already set value.
No, what you are doing should work. The resulting behavior you're experiencing is irregular and not intended.
From sass-lang docs:
You can assign to variables if they aren't already assigned by adding the !default flag to the end of the value. This means that if the variable has already been assigned to, it won't be re-assigned, but if it doesn't have a value yet, it will be given one.
I suspect there may be something else at play that we need to investigate.
I've verified the correct behavior with these files:
Sass source:
_t1.sass
div
margin: 0
_t2.sass
$c: blue !default
body
background: $c
main.sass
$c: black
#import '_t1.sass'
#import '_t2.sass'
CSS result:
div {
margin: 0;
}
body {
background: black;
}
It is black as intended.
My suggestion is :-
1) If you want black background then you simply do like this
// main.sass
#import "_another_import.sass";
#import "_import.sass";
// _import.sass
$variable: black;
body{
background-color: $variable !important;
}
But my suggestion is that your file structure like this
#import "_variable"; /*Define Variable in separate file & in that file declare $variable*/
#import "_another_import.sass";
#import "_import.sass";
body{
background-color: $variable !important;
}
I think you are misunderstanding what !default does. It is saying if variable is not assigned, use this value.
You can assign to variables if they aren’t already assigned by adding the !default flag to the end of the value. This means that if the variable has already been assigned to, it won’t be re-assigned, but if it doesn’t have a value yet, it will be given one.
I'm trying to dynamically change some field color when it has changed due to some processing.
CUBA documentation explains how to do it statically through web theme extension (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html), but not dynamically. Although it is possible in Vaadin (https://vaadin.com/wiki/-/wiki/Main/Dynamically%20injecting%20CSS) on which platform web gui is built upon.
I suppose that if I use the Vaadin way of injecting CSS it will work (which I will try) but I will then have Vaadin specific code, which I'm trying to avoid.
Is there a CUBA way of doing so I'm missing ?
Edit:
I'm trying to have any field of a form to change background color when it has changed from its initial value. As per CUBA documentation (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html) I need to :
- create a SCSS mixin with background color
- inject the field in the editor class in order to have access to it
- react to a field change event and then define the style name of the field
I did create the SCSS mixin, but two issues I have :
1) I would like to retrieve the field instance dynamically instead of injecting it (keep code clean and light)
2) I would like to avoid defining the background color statically so that the color could be parameterized at runtime
For 1) I tried to injected the fieldGroup and used getFieldComponent(), then applied the style with setStyleName on it when it is changed. It worked but I would prefer to define this behavior for every field that is an input field.
For 2) apart from using Vaadin specific feature of injecting CSS (and tighing my code to Vaadin (and so leading me away of generic interface) I do not see how to do
Hope it's more clear
You cannot set truly dynamic color (any RGBA) from code to field but you can create many predefined colors for your field:
#import "../halo/halo";
#mixin halo-ext {
#include halo;
.v-textfield.color-red {
background: red;
}
.v-textfield.color-blue {
background: blue;
}
.v-textfield.color-green {
background: green;
}
}
I do not recommend using styles injected from code (as Vaadin Page does) since it is a mixing of logic and presentation. Instead you can create all predefined styles (30-50 styles should be enough) and assign it depending on some conditions using setStyleName method:
public class ExtAppMainWindow extends AppMainWindow {
#Inject
private TextField textField;
private int steps = 0;
public void changeColor() {
if (steps % 2 == 0) {
textField.setStyleName("color-red");
} else {
textField.setStyleName("color-blue");
}
steps++;
}
}
If you want to apply the logic of color change for all TextFields inside of FieldGroup you can iterate FieldGroup fields in the following way:
for (FieldGroup.FieldConfig fc : fieldGroup.getFields()) {
Component fieldComponent = fieldGroup.getFieldComponent(fc);
if (fieldComponent instanceof TextField) {
TextField textField = (TextField) fieldComponent;
textField.addValueChangeListener(e ->
textField.setStyleName("color-red")
);
}
}
I'm not able to set the background color for the textfield in GXT. I have used
textfield.setStyleName("backgroung-color:red;")
textfield.setStylePrimaryName("backgroung-color:red;")
But it is not working in IE. How can i do this ?
The function "setStyleName()" is not working as you expect, it sets the component class name. You can create a style class with name for example 'field-bgColor' in your css file like:
.field-bgColor {
background-color: red;
}
after that, you would use it like following:
textfield.setStyleName("field-bgColor");
Or you can use "setStyleAttribute()" function like:
textfield.setStyleAttribute("backgroundColor", "red");
Hope it works for you :)