How to set light and dark modes with SCSS variables - variables

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) {
/* ... */
}
}

Related

Ability to disable text input in package "vue-search-select" - "basic-select" component

I want to disable text input in the "basic-select" component, from the "vue-search-select" package
because there are already ready-made styles for it, and I would not want to create a separate customized select
is it possible? Tell me please
I guess there is no explicit API to disable text input because this package is going to make a "searchable" select component. The text input can be hidden using CSS, however.
.search {
display: none;
}
/* or even better */
.ui.search.dropdown > input.search {
display: none;
}
However, you should be careful about the selector you choose. Depending on your project, it might have some side effects. It might be better to add a custom class to the component and use it as follows:
.my-custom-class .ui.search.dropdown > input.search {
display: none;
}

How to change font-family in Vuetify?

The default Vuetify font family is Roboto and I would like to change this. I found other solutions that changes the font family globally. I don't want to change it globally, I only want to change it for a specific element. How to do this?
<template>
<v-container>
<div class="text-h4">Text family I want to change</div>
<div class="text-h6">Text family I dont want to change/give another font family</div>
</v-container>
</template>
Update
Vuetify declares the font on .v-application and unfortunately also declare the font as !important on .v-application .text-hN. I can suggest you some ideas to modify your font:
If you want to change every text-h4: You can override the style of text-h4 by modifying its default ($headings then
'h4') https://vuetifyjs.com/en/features/sass-variables/#example-variable-file
If you want to keep default text-h4: You can remove the text-h4 class and use your own class custom-header with copied rules of text-h4 plus your font-family rule. You won't need higher specificity, nor to use !important.
Something like:
.custom-header {
font-size: 2.125rem !important; /* from .text-h4 */
line-height: 2.5rem; /* from .text-h4 */
letter-spacing: .0073529412em !important; /* from .text-h4 */
font-weight: 400; /* from .text-h4 */
font-family: YOUR_FONT_FAMILY, Roboto, sans-serif;
}
Previous answer
Give your element another class:
<div class="text-h4 anotherClassForExample">Text family I want to change</div>
Override the font-family of this new class in your css.
I was in a similar position before, I had some basic css knowledge and started using frameworks. I strongly recommend you to master CSS before using a UI framework. Starting by using a framework looks faster, shinier and easier but in the long term it is not. You will be blocked a lot and maybe in the future you will change to another one or even want to not use any.

Change background color of ion-page element only, not descendent elements, in Ionic Vue

I have an Ionic Vue3 app. I'd like to change the background color of the whole page. I'm new to Ionic but I believe the way this has to be done (due to the use of Web Components/Shadow DOM) is to modify the --ion-background-color CSS custom property rather than trying to set the value of the normal CSS property, so this works:
.ion-page {
--ion-background-color: red;
}
...but this doesn't:
.ion-page {
background-color: red;
}
Fine, so I do the former, but the problem now is that all elements within the page (everything inside the <ion-page></ion-page> element which use that same custom property value now inherit the same background color.
Does anyone know how to scope the change of background colour of the ion-page element such that it doesn't cascade through descendent elements? Thanks :)
The solution here was to use local CSS custom property --background rather than the global property --ion-background-color. So the following works:
.ion-page {
--background: red;
}
I didn't previously realise there were different sets of CSS variables for different scopes.

Sass: Overriding default variables of imported stylesheets

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.

Sass, color schemes with bootstrap

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);}
}