I want to apply custom CSS and override some default Vuetify colors. For example, success button can be easily overridden:
.success-button {
background-color: $sb--color-success !important;
}
But is there a way to do the same without using !important? I tried both:
body .success-button {
background-color: $sb--color-success;
}
button .success-button {
background-color: $sb--color-success;
}
How to do it without !important?
You can try something along this lines
// src/index.js
// Libraries
import Vue from 'vue'
import Vuetify from 'vuetify'
// Helpers
import colors from 'vuetify/es5/util/colors'
Vue.use(Vuetify, {
theme: {
primary: colors.red.darken1, // #E53935
secondary: colors.red.lighten4, // #FFCDD2
accent: colors.indigo.base // #3F51B5
}
})
Or something like this
<h1 class="subheading grey--text">DASHBOARD</h1>
Related
I've set up a project using Vue 3.2.33 and Vite 2.9.5
When I try to access any global variable or mixin from within any vue component, I get an undefined error. This problem doesn't occur in scss files.
The import itself seems working correctly because any css rules in it are working.
vite.config.ts:
import { fileURLToPath, URL } from 'url';
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: '#use "#/styles/variables";',
},
},
},
});
src/styles/_variables.scss:
// breakpoints
$breakpoints: (
"sm": 576px,
"md": 768px,
"lg": 992px,
"xl": 1200px,
"xxl": 1400px,
);
#mixin test {
border: 3px solid red;
}
Example use:
<style scoped lang="scss">
#use 'sass:map';
.container {
max-width: 100%;
width: 100%;
margin: 0 auto;
#include test; // <- undefined
&--fluid {
max-width: 100%;
width: 100%;
}
}
$widths: (
'sm': 540px,
'md': 720px,
'lg': 960px,
'xl': 1140px,
'xxl': 1320px,
);
#each $breakpoint, $width in $widths {
#media (min-width: map.get($breakpoints, $breakpoint)) { // <- $breakpoints undefined
.container {
max-width: $width;
}
}
}
</style>
use
#import
in your vite config instead of
#use
vite.config.ts:
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: '#import "./src/styles/variables.scss";',
},
},
},
});
keep in mind that you cannot import the same file variables.scss again in your main.ts file otherwise, you will get this error
[sass] This file is already being loaded.
by the way, you can also import the scss file in every single component manually as you mentioned but that would be really tedious so using a global import in preprocessorOptions in vite.config.ts is a much better option for files used globally like a variables.scss file.
I've managed to "fix" the issue. Turns out, when I replace all #use rules for file imports, the sass code is imported correctly and works. But this produces a new problem as the #import rules cannot be placed before #use, so I had to remove the additionalData key from config and include the imports manually.
Below was the old question, I realize the issue is not with the custom properties, but rather I have a component like the below, and 'active-class' is not being applied.
I tried to change the prop name to activeClass, doesn't seem to be working
<VListGroup
key={item.text}
class='drawer-item'
active-class='drawer-active-item'
>
I'm working on a new project using Vue, and trying to convert some old components (.vue) files to be using render functions and typescript (.tsx), and trying to separate the style contained in the <style/> blocks into a separate .less file.
While the template syntax, v-if and all can be converted quite easily, however I'm stuck on the part where if my style contains customProperties, https://vuetifyjs.com/en/features/theme/#custom-properties]]
specifically --v-primary-base, as the below
I have the below
.drawer-active-item {
color: white;
&::before {
background-color: var(--v-primary-base);
opacity: 1;
}
&:hover::before {
opacity: 0.8;
}
&::after {
background-color: var(--v-primary-base);
opacity: 1;
}
&:hover::after {
background-color: var(--v-primary-base);
opacity: 0.8;
}
}
Is there a way to access these custom css variables from the .less file? I've been googling things like 'access customProperties in less file` and things related, but I feel like perhaps I'm not asking the right question, or looking at the right resource for what I'm trying to achieve, pointers would be great, thank you.
I have a theme config that currently looks like the below, just for some context.
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import colors from 'vuetify/lib/util/colors';
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'md',
},
theme: {
options: {
customProperties: true,
},
themes: {
light: {
primary: colors.blue.darken3,
},
dark: {
primary: colors.blue.darken3,
anchor: colors.blue.base,
},
},
},
});
I want to parse markdown to html and use syntax highlighting.
My SFC is as follows:
<template>
<div v-html="html"></div>
</template>
<script>
import marked from 'marked'
import hljs from 'highlightjs';
export default {
name:"Article",
props:['md'],
computed:{
html(){
return marked(this.md)
}
},
created: function () {
marked.setOptions({
langPrefix: '',
highlight: function(code, lang) {
return hljs.highlightAuto(code, [lang]).value
}
})
},
}
</script>
<style src='highlightjs/styles/github-gist.css'></style>
The resulting code blocks are look like this:
This is Vuetify's style.
https://vuetifyjs.com/en/styles/content/#code
I want to disable or override it.
The following code does not work for code blocks:
<style scoped>
.v-application code {
background-color: unset !important;
color: unset !important;
box-shadow: unset !important;
}
.myclass {
color:red !important;
}
</style>
Result:
Vuetify has the following CSS specified for the code tags:
.v-application code {
background-color: #f5f5f5;
color: #bd4147;
box-shadow: 0 2px 1px -1px rgba(0,0,0,.2),
0 1px 1px 0 rgba(0,0,0,.14),
0 1px 3px 0 rgba(0,0,0,.12);
}
You can see this if you open developer tools and inspect a code tag on their website.
Either override those values to your own, or just set them all to unset or unset !important. For example:
.v-application code {
all: unset;
color: #eee
}
/* Or with increased specificity */
.v-application code.code--custom {
all: unset;
color: #eee
}
Actualy the style override you suffer from wouldn't be a problem if you just import your HighlightJS CSS directly after Vuetify in your main.js.
//main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import '<your_path>/highlight.min.css'
Consider also using a Vue Directive for global usage.
//main.js
Vue.directive('highlightjs', {
deep: true,
bind: function(el, binding) {
// highlight all targets
let targets = el.querySelectorAll('code')
targets.forEach((target) => {
// override this in case of binding
if (binding.value) {
target.textContent = binding.value
}
hljs.highlightBlock(target)
})
},
})
Then you can simply use it like this:
<pre v-highlightjs>
<code class="javascript">
// your code goes here //
</code>
</pre>
I made a JSFIDDLE for this, which is a modified version of a vue HighlightJS example by Chris Hager.
https://jsfiddle.net/b8jontzr/2/
I'm starting with polymer 3 and i'm working on this tutorial https://www.polymer-project.org/1.0/start/first-element/step-5, so basically i have the component js file as follows
icon-toggle.js
import { PolymerElement, html } from '#polymer/polymer/polymer-element.js';
import '#polymer/iron-icon/iron-icon.js';
class IconToggle extends PolymerElement {
static get template() {
return html`
<style>
/* shadow DOM styles go here */
:host {
display: inline-block;
--icon-toggle-color: lightgrey;
--icon-toggle-outline-color: black;
--icon-toggle-pressed-color: red;
}
iron-icon {
fill: var(--icon-toggle-color, rgba(0,0,0,0));
stroke: var(--icon-toggle-outline-color, currentcolor);
cursor: pointer;
}
:host([pressed]) iron-icon {
fill: var(--icon-toggle-pressed-color, currentcolor);
}
</style>
<!-- shadow DOM goes here -->
<iron-icon icon="[[toggleIcon]]"></iron-icon>
`;
}
static get properties() {
return {
pressed: {
type: Boolean,
value: false,
notify: true,
reflectToAttribute: true
},
toggleIcon: {
type: String
}
};
}
constructor() {
super();
this.addEventListener('click', this.toggle.bind(this));
}
toggle() {
this.pressed = !this.pressed;
}
}
customElements.define('icon-toggle', IconToggle);
Now I'm wondering how to import this and use it in an angular 5 app.
Generate a new Angular app.
ng new with-polymer
From within with-polymer create a directory to store the web components in.
mkdir src/app/components
Copy your polymer component code to src/app/components/icon-toggle.js
Install the polymer dependencies.
npm install #polymer/iron-icon #polymer/polymer
Update src/app/app.module.ts to import CUSTOM_ELEMENTS_SCHEMA and tell NgModule that custom elements will be in use.
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '#angular/core';
#NgModule({
...
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
Import icon-toggle in src/app/app.module.ts.
import './components/icon-toggle';
Add an icon-toggle to src/app/app.component.html.
<icon-toggle toggle-icon="star"></icon-toggle>
Start up the dev server.
npm start
Note that you will probably want to include some web component polyfills.
In my index.js file I have manually override the Vuetify theme object with my company's color:
Vue.use(Vuetify, {
theme: {
primary: '#377ef9',
secondary: '#1b3e70',
accent: '#ff643d',
error: '#ff643d'
...
}
Now, I can use these colors from my templates like so:
<my-text-field name="input text"
label="text"
value="text text text text..."
type="text"
color="primary">
</my-text-field>
What I'm after is using the primary or any other variable in the theme object defined above, inside my template style:
<script>
import { VTextField } from 'vuetify'
export default {
extends: VTextField
}
</script>
<style scoped lang="stylus">
label
color: <seconday color> <-- this is what I'm after
color: #1b3e70 <-- this works, but not quite good enough for me
</style>
I can easily just write the hex value of my colors in the style section, but I don't want to repeat myself, and would rather use my theme object so it will also be easier for my to easily change the colors everywhere, and avoid typos which will lead to mistakes in the colors definitions.
Edit (2018/10/11)
Since version 1.2. we can enable CSS variables
NOTE: allegedly it won't work in IE (Edge should work), and possibly some Safari versions?
From docs (see Custom Properties)
Enabling customProperties will also generate a css variable for each
theme color, which you can then use in your components'
blocks.
Vue.use(Vuetify, {
options: {
customProperties: true
}
})
<style scoped>
.something {
color: var(--v-primary-base)
background-color: var(--v-accent-lighten2)
}
</style>
For custom values e.g.
yourcustomvariablename: '#607D8B'
use --v-yourcustomvariablename-base (so base is default).
Original answer:
There is a Feature Request on github: Access theme colors in stylus files
#KaelWD (one of devs) wrote:
This is something you'll have to implement yourself. I've tried doing
something similar before but it doesn't really work on a framework
level.
Issue is labeled wontfix
Edit (2018/10/11)
Also see this updated thread:
https://github.com/vuetifyjs/vuetify/issues/827 (Feature request: Native css variables)
There is a way to go around this by utilizing :style attributes. It can be used to set custom CSS properties reactively.
Add a computed property:
computed: {
cssProps () {
return {
'--secondary-color': this.$vuetify.theme.secondary
}
}
Bind style to cssProps:
<div id="app" :style="cssProps">
Then, in your style:
<style scoped>
label
color: var(--secondary-color);
</style>
Adapted from this discussion: https://github.com/vuejs/vue/issues/7346
For anyone stumbling over this from Vuetify V2 onwards, you can do the following to get access to the SCSS colour variables.
// Import the Vuetify styles somewhere global
#import '~vuetify/src/styles/styles.sass';
// Now in your components you can access the colour variables using map-get
div {
background: map-get($grey, lighten-4);
}
All the colours can be found in /node_modules/vuetify/styles/settings/_colors.scss.
From above answers, if you want to include all vuetify colors, put this code in App.vue template
<v-app :style="cssProps">
App.vue script
computed: {
cssProps () {
var themeColors = {}
Object.keys(this.$vuetify.theme.themes.light).forEach((color) => {
themeColors[`--v-${color}`] = this.$vuetify.theme.themes.light[color]
})
return themeColors
}
}
Let say if you have this color in vuetify.js
export default new Vuetify({
treeShake: true,
theme: {
themes: {
light: {
darkRed: "#CD3300",
}
}
}
})
Then, in any component:
<style scoped>
.label {
color: var(--v-darkRed);
}
</style>
Maybe I am late the most efficient way to do is as mentioned in the docs https://vuetifyjs.com/en/features/theme/#custom-properties
I will provide a working example for the same.
you need only three changes to be done for this to get working.
Mention the option which does the magic and your theme color
export default new Vuetify({
theme: {
options: {
customProperties: true
},
themes: {
light: {
primary: "#3DCFD3",
secondary: "#171b34",
accent: "3D87E4"
}
}
}
});
Mention the class name in the tag where you want your theme to get applied
<h4 class="blue-header">Yash Oswal</h4>
CSS to apply your theme.
<style lang="scss">
.blue-header {
color: var(--v-primary-base);
}
</style>
For vutify 3+:
inside vuetify.js file declare theme color variable colors:{green:'#00ff00'}
// src/plugins/vuetify.js
import { createApp } from 'vue'
import { createVuetify } from 'vuetify'
export default createVuetify({
theme: {
defaultTheme: 'myCustomTheme',
themes: {
myCustomTheme: {
dark: false,
colors: {
..., // We have omitted the standard color properties here to emphasize the custom one that we've added
green: '#00ff00'
}
}
}
}
})
inside .vue component file use rgb(var(--v-theme-green)):
<template>
<div class="custom-class">background color with appropriate text color contrast</div>
</template>
<style>
.custom-class {
background: rgb(var(--v-theme-green))
}
</style>
Example of switching theme (helpfull link):
<v-app :dark="setTheme"
:style="{background: $vuetify.theme.themes[theme].background}"
>
JS:
computed: {
setTheme() {
this.$vuetify.theme.dark = this.goDark;
}
},
data() {
return {
goDark: false
}
}