Vue3 - How to override styles after importing node_modules css file? - css

I have a standard Vue3 app using the library https://github.com/ismail9k/vue3-carousel.
In my App.vue file, I have the following, which is required to use the library:
<style>
#import "~vue3-carousel/dist/carousel.css";
</style>
Since I don't want to use the library's default colors, I'm trying to override some styles.
The library defines some colors on :root, such as:
--vc-clr-primary: #333333;
--vc-pgn-background-color: var(--vc-clr-primary);
Then, the style that I want to ultimately override is:
.carousel__pagination-button {
...
background-color: var(--vc-pgn-background-color);
}
So, I assume that I want to override either of the variables, or the class itself. In my Component.vue file, I have the following:
<style scoped>
.carousel__pagination-button {
background-color: #999999 !important;
}
</style>
But that doesn't do anything.
I don't care where I override these colors, because I'll use the same colors throughout the website, but I can't figure out how to get them to override no matter where or how I attempt to override them.
What am I doing wrong?

This worked:
App.vue
...
<style>
#app {
--vc-pgn-background-color: #mycolor;
}
#import "~vue3-carousel/dist/carousel.css";
</style>

Related

how to call Sass variable in a Vue file

There is a variables.scss file in a project which defines a variable and assigns it a color like this:$contrast: #edebe4The current use of the $contrast variable is to set other variables within the variables.scss file.
Now there is a specific .vue file that's used to render data to the browser and it contains this line of code in its template:<div style="background-color: #edebe4">
When I change that line to<div style="background-color: $contrast">the desired background color disappears from that element.
Is there a way to get that element to recognize the $contrast variable so that whenever the value of $contrast is changed that change flows through automatically to this element?
You can make scss variables available globally (in each component). Just add this to vue.config.js:
css: {
loaderOptions: {
scss: {
additionalData: `#import "~#/variables.scss";`
}
}
}
More info here
Just import variables.scss into your .vue
...
<style lang="scss">
#import "variables.scss"
</style>
This worked -
in variables.scss file added
.contrast-background {
background-color: $contrast;
}
in .vue file changed element to this
<div class="contrast-background">
Amendment -
Here is the final solution that was implemented, which was made possible by #Finn's post -
Changes to .vue file:
added this
<style lang="scss" scoped>
#import "#/layout/design/variables.scss";
.contrast-background {
background-color: $contrast;
}
</style>
and changed element to this
<div class="contrast-background">
This approach avoids changes to the variables.scss file.

Does Blazor Web Assembly work with CSS variables in CSS Isolation files?

Does CSS variables work in a Blazor component with CSS islolation files ?
When my component named Test.razor has no CSS isolation file and has the style set:
<h1 class="mh1">Test</h1>
<style>
:root {
--mblue:#0000ff;
}
.mh1{
color:var(--mblue);
}
</style>
Test is indeed blue.
However if I put the styles in a isolation file name Test.razor.css it does not work.
:root {
--mblue: #0000ff;
}
.mh1 {
color: var(--mblue);
}
The component Test resides in the index page:
#page "/"
<Test></Test>
What am I doing wrong?
The answer is yes, but not so sure that you can use :root in a css isolation file (the class is no longer called :root in a css isolation file -- it gets a random suffix with css isolation).
My approach has been as follows:
Use a wrapper element to provide a context to assign the css variables to.
Then use the variable in the class you assign to the relevant element.
Test.razor
<div class="test-wrapper">
<h1 class="mh1">Text</h1>
</div>
Test.razor.css
.test-wrapper {
--mblue: #0000ff;
}
.mh1 {
color: var(--mblue);
}

Using theme color in global theme mixin with ng-deep

I am using the style guidelines specified at https://material.angular.io/guide/theming-your-components
My component has a mat-form-field where I want to change the border color. If I put the ng-deep style in component.scss file, it gets applied aliright, like below:
:host ::ng-deep {
mat-form-field.active-field .mat-form-field {
&-flex {
border: 2px solid red;
}
}
}
Now, I want to keep the border color dynamic and dependent on theme. I have a mixin defined in my-component-lib.theme.scss, which gets called from a global theme file of the application. I tried to put the same style inside that mixin as:
#mixin my-component-lib-theme($theme) {
$primary: map-get($theme, primary);
.component-container ::ng-deep {
mat-form-field.active-field .mat-form-field {
&-flex {
border: 2px solid lighten(mat-color($primary), 30);
}
}
}
}
But it is not working. I have some other styles in the mixin which does not use ng-deep, and those styles are working fine. So, it seems the issue here is with ::ng-deep in global theme mixin. How can I solve this?
The ::ng-deep selector is an angular-specific pseudo-class, which tells the Angular-Compiler, that the following CSS shall be applied to Sub-Components as well. This selector will not end up in the browser, as the browser wouldn't know it!
Your global theme file is probably included directly in your html like this <link rel="stylesheet" type="text/css" href="path/to/global/theme.css"> and doesn't know anything about angular (even though it's probably SASS/SCSS-compiled). Just use plain old CSS here (or SASS/SCSS if you're using the default Angular CLI). You may simply omit the ::ng-deep selector here, as your global theme is applied globally anyway.

Nesting SCSS Rules in VueJS Modules

How can I handle nested SCSS rules, which expand on a base style, when dealing with the CSS Modules to import styles to the local component?
In my case, I have the following two SCSS files:
icon.scss
.my-icon {
// base styles for an icon
}
button.scss
.my-button {
...
.my-icon {
// special styles when an icon is in a button
}
}
Which I then import into their respective components:
MyIcon.vue
<template><i class="my-icon" /></template>
<style lang="scss" module>
#import '/path/to/icon.scss'
</style>
MyButton.vue
<template><button class="my-button"><slot /></button></template>
<style lang="scss" module>
#import '/path/to/button.scss'
</style>
The trouble is that the nested .my-icon class, in 'button.scss', generates a different hash ('._2XJ5') than the root .my-icon class, in 'icon.scss' (._2UFd). So, when I attempt to embed an icon into a button I get an output that looks like this:
<button class="._3S2w"><i class="._2UFd" /></button>
Which is correct, but the "special styles" for an icon in a button are not applied, because that class was generated as a different hash.
How do I make sure the hash value for '.my-icon' always comes out the same?
Somewhere, hidden deep in the Vue loader, the documentation talks briefly about how you can escape the scoped styling. The solution is to use a /deep/ selector, which is preprocessed by scss to give everything behind it no hash. There is something similar in normal css, but it is somewhat unrelated.
Say we have our my-button component and want to style my-icon classes inside it, we can do the following:
<template>
<div>
<slot></slot>
</div>
</template>
<style lang="scss" scoped>
/deep/ .my-icon {
background: red;
}
</style>
The following should generate something like the following. It is still scoped within your component, but .my-icon does not have to be part of your component. In this case, it could be inside the slot for example.
[data-v-f3f3eg9] .my-icon {
background: red;
}

vuejs multiple themes with scoped css in single file vue components

So let's assume we have a variables scss file like the following
$darken-percentage: 15%;
$primary-color: #2aaae1;
$dim-primary-color: darken($primary-color, $darken-percentage);
$complementary-color: #faaf48;
$dim-complementary-color: darken($complementary-color, $darken-percentage);
$background-color: #1d1f29;
$middleground-color: #313444;
$dim-middleground-color: darken($middleground-color, $darken-percentage);
$light-middleground-color: lighten($middleground-color, $darken-percentage);
In the main.js we could use #import 'variables.scss'
what if I have two themes and I want to change on user action I could have 2 variables files and conditionally import either based on user actions but what about single file vue components
like
<style scoped lang="scss">
#import '../../theme/_variables.scss';
.bm-upload{
background: $primary-color;
}
</style>
Then the import will not work so is there anyway for me to have global variables files and use it in other files without re importing it
The easiest is to import both style files and change a parent element's class. The browser will immediately apply the styles when the class changes.
You can, for example, change the body's class with classList and have all styles depend on that.
created(){
let body = document.getElementsByTagName('body')[0];
body.classList.add("theme1");
},
methods: {
changeTheme(){
let body = document.getElementsByTagName('body')[0];
body.classList.remove("theme1");
body.classList.add("theme2");
}
}
Style should inherit from the theme class name, like this:
.theme1 {
.exampleClass {
padding: 0;
}
}

Resources