i'm looking for ideas on how to completely repaint a website. We use vue with nuxt and sass with sass variables and bootstrap. I need to change the complete colors on the web after logging in, ideally just to change the sass variables file ... somehow. In main.scss all scss are imported and main.scss is imported in nuxt app.js. Any ideas?
EDIT
the correct solution is to use the css variables as follows
:root {
--color-primary: limegreen;
}
.application {
color: var(--color-primary);
}
.application.dark {
--color-primary: green;
}
after changing the class, the color changes, but now i get an error this one
Custom property ignored: not scoped to the top-level :root element
I tried to use it in main.js and directly in the component but still have the same problem. Any idea?
You can not dynamically change sass variables in javascript. To do that you need define your variables in css root for example:
:root {
--main-color: blue;
}
And then you can manipulate it in you login method or action wherever you send the request. Like this:
document.documentElement.style.setProperty('--main-color', 'red');
I always do it like this:
I go to my /layouts folder to default.vue. Depending on your project you might use something different then default.vue
Then i declare my CSS vars in the <style> tag like:
:root {
--main-color: #317EEB;
}
This is global available without SASS or any preprocessors.
document.documentElement.style.setProperty('--main-color', 'red');
You can do it from anywhere you want. Just be sure this gets executed on the client side
if (process.client) {
document.documentElement.style.setProperty('--main-color', 'red');
}
function changeColor(variable, color) {
document.documentElement.style.setProperty(variable, color);
}
button.onclick = function() {
changeColor("--main-color", "red");
}
:root {
--main-color: #317EEB;
}
body {
background: var(--main-color);
}
<button id="button">click me</button>
Whenever you change the CSS variable the colors updates everywhere
Related
This is a reactjs project, Te amperzand syntax is working fine in Javascript file but not in css.
How to write hover class in css file?
If you want to write in same class. You should use Sass/Scss.
Save the css file with .scss extension. It is a precprocessor for better syntax.
Refer this sandbox:
https://stackblitz.com/edit/react-uwktzj?file=src%2FApp.js
You must write it this way
.baseStyle {
/* base styles goes here*/
}
.baseStyle:hover {
/* hover styles goes here */
}
If you wish to attain what you intend you must use scss.
Then it will be like
.class {
margin:20px;
&:hover {
color:yellow;
}
}
Reference
Using Scss in React
I was going to change this scss variable from a root variable like this
:root {
--primary-custom : yellow;
--primary-hover-custom : blue;
}
$primary: var(--primary-custom);
$primary-hover: var(--primary-hover-custom);
but it returns this error:
Argument `$color` of `darken($color, $amount)` must be a color
What is the best approach to do this, I want to use this --primary-custom so I could change it dynamically with javascript like this:
const root = document.documentElement;
root.style.setProperty("--primary-custom", lightColor);
You can’t. Information doesn’t flow in that direction.
SASS is compiled to CSS (usually at build time) and then the resulting CSS is sent to the browser.
You can’t pass CSS variables back to SASS because it is too late and probably on the wrong computer.
——-
I’d probably approach this problem by using classes instead of CSS variables and having the colour schemes predefined in the SASS.
#each could help by looping over the colour schemes.
I can't understand where is darken() function in your example but here is example how manipulate color on a page:
You can use default color for your css variable.
$primary: yellow;
.text-primary {
color: var(--primary, $primary)
}
So now browser try to find css variable named --primary and if it doesn't exist the default color will be used.
Then if you want to change default --primary color — just create pseudo-class :root with that variable and append it to any page with javascript.
:root {
--primary: green;
}
I'm working on implementing different themes across my website. I've refactored my main stylesheet to feature variables, and have three other "theme" stylesheets that define those variables at the :root level. The final HTML then links to two stylesheets: The main stylesheet and one of the three theme stylesheets, which are switched on button click by changing the link's href attribute. Somehow, only some of the variables are working.
/* dark.css (theme stylesheet only containing the custom properties) */
/* Only --background works */
:root {
--background: #000000;
--seperator: rgba(1,1,1,0.12);
--text: #FFFFFF;
--block-border: #404040;
--block-shadow: #000000;
--block-background: #151017;
}
/* All properties work except for --comment */
code {
--keyword: #F72057;
--type: #FF9519;
--call: #FF5700;
--property: #FF5700;
--number: #F72057;
--string: #F72057;
--comment: #FFFFFF;
--dot-access: #FF5700;
--preprocessing: #646485;
}
When I then go into the inspector, everything seems to be alright. I can see the proper inheritance, and I can even click on the variable where it's used and see the intended color.
Some examples of how the variables are used:
/* styles.css (main stylesheet) */
body {
...
background: var(--background);
color: var(--text);
}
pre code .comment {
color: var(--comment);
opacity: 0.4;
}
Other approaches
I've tried several other approaches, all of which led to the same result (only some variables working).
Instead of linking to another stylesheet, directly change the variables with javascript on the HTML tag
Instead of linking to multiple stylesheets, having three separate main stylesheets
Changing a custom attribute in the HTML tag and defining all variables like [theme="dark"] {...} in one main stylesheet
As #Pushkin and #Temany Afif have pointed out, there were strange characters all over my code. A quick project-wide find and replace solved the problem.
Is it possible to add a classname to a CSS variable or is there some other way to set it up so that I don't have to manipulate each individual variable directly via javascript? I'd like to keep all my styles in CSS and simply turn on relevant classes with JS. For example, If something like this was possible in CSS:
:root.white{ --bgcol:#FFF; --col:#000; }
:root.black{ --bgcol:#000; --col:#FFF; }
Then I could then just toggle the .black or .white class from javascript to trigger all vars to change. What's the best approach for this type of setup?
That's frankly the best (as in most idiomatic) approach — the use of class names, if not altogether separate stylesheets (as has been tradition for many, many years), to theme entire layouts via custom properties. It's the most "fundamentally CSS" approach with JavaScript merely being the glue that makes the theme switching work. You really can't do much better than that.
For those unaware what :root means and wondering where exactly the class names are being applied, it's the html element (the parent of body). So there is nothing special going on here — you're simply switching class names on the html element. It just happens that global custom properties are conventionally defined for the document root element since it's at the top level of the inheritance chain.
If you have any theme-agnostic custom properties, as well as style properties (i.e. not custom properties) that apply to the root element, keep them in their own unqualified :root rule, separate from your themed custom properties, so they won't be affected by theme switching. Here's an example:
const root = document.documentElement;
// Default theme - should assign declaratively in markup, not JS
// For a classless default theme, move its custom properties to unqualified :root
// Again, keep it separate from the other :root rule that contains non-theme props
// Remember, the cascade is your friend, not the enemy
root.classList.add('white');
document.querySelector('button').addEventListener('click', function() {
root.classList.toggle('white');
root.classList.toggle('black');
});
:root {
--spacing: 1rem;
color: var(--col);
background-color: var(--bgcol);
}
:root.white {
--bgcol: #FFF;
--col: #000;
}
:root.black {
--bgcol: #000;
--col: #FFF;
}
p {
margin: var(--spacing);
border: thin dashed;
padding: var(--spacing);
}
<button>Switch themes</button>
<p>Hello world!
Using :root selector is identical to using html, except its specifity is higher, thus there is no issues in using this approach.
For example:
:root {
--bg: red;
}
:root.blue {
--bg: blue;
}
// ...
div {
background: var(--bg);
}
Later, you should just change html's class and variables will change.
You can see an example in this fiddle.
So I have two components... a Navbar component, and an AboutPage component.
They are both in the same directory, 'App'
App
-- Navbar --> Navbar.css, Navbar.js
-- AboutPage --> Aboutpage.css, Aboutpage.js
So as you can see, they have two separate stylesheets.
In the JS pages the correct CSS file is being imported as well.
When I do a style like this for example:
Navbar Component
p { background: red }
^^ this style also applies to the p's in the Aboutpage. I even tried to give the P in Aboutpage its on id and style it that way and it still failed.
That's the expected behaviour.
No matter which file you specify a rule like p { background: red }, it's going to be applied to all DOM.
Specifying and id attribute to won't work either. The above rule is general enough to apply to all <p>s.
If you want to specify css files for each component, you should also create component specific css classes. Like the following example.
import React from 'react';
import './DottedBox.css';
const DottedBox = () => (
<div className="DottedBox">
<p className="DottedBox_content">Get started with CSS styling</p>
</div>
);
export default DottedBox;
and its css file:
.DottedBox {
margin: 40px;
border: 5px dotted pink;
}
.DottedBox_content {
font-size: 15px;
text-align: center;
}
If you want different ways of defining css for React, this resource adds 3 more ways of doing so, in addition to the above way.
You can also use css modules. They scope your CSS locally and are awesome
Scoping styles to a component requires WebComponents which relies on several newer browser features, particularly shadowRoot "shadownDOM" which supports this separation directly. These are most easily used with lit-element and/or Polymer 3.
Sometimes we need a global CSS which could affect another component even if we use module import, I didn't find anything to answer that in the official documentation, so my workaround is to use something like the following code in the component itself, and, it works fine :)
<style>
{
`
#page {
padding:0;
margin-top:0;
margin-bottom: 0;
margin-left: 0;
margin-right:0;
}
#media print {
#page {
size: 80mm 21cm;
}
}
`
}
</style>