I am trying to give an element in my page a custom colour but all attempts are foiled by the Vuetify enforcing the important! on the component themes. I have followed the docs and tried:
v-list-item.selection(class="red--text")
and
v-list-item.selection(color="red")
then got desperate and tried
.selection {
color: red
}
and
.theme--light.v-list-item {
color: red
}
But the theme color just overrules everything by applying:
.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {
color: rgba(0, 0, 0, 0.87) !important;
}
What do?
You can overwrite it by adding the same rule in your App.vue:
.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {
color: red !important;
}
Or you can increase specificity by adding your own class to that element:
<div class="custom-list-item"></div>
...
.custom-list-item {
color: red !important;
}
Or you can specifically change color of all elements inside it, if it works for you:
.theme--light.v-list-item * {
color: red !important;
}
One might work (but not a good practice at all):
.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled).selection {
color: red !important;
}
// it's more than Vuetify's style the `.selection` specificity
Edit:
The answer I gave above will not work if you use scoped style
As working around myself, and have read a comment here. I don't think change Vuetify's style in a Vuetify component is easy. Instead, by using a Vuetify's component, you should predefine the colors you'll ever use, and then you could use those colors in the components you want.
To workaround without configuring Vuetify, then you can:
Combine inline style + !important
<v-list-item style="color: red !important">Content</v-list-item>
Don't use Vuetify's component, use vanilla html (for this component) instead
Related
I've been trying to change the background color of the popover body but it's not changing the color. If I remove scoped from styles then it works but when I use scoped and use deep selector, the color doesn't apply.
This is my code
<template>
<div>
<button
:id="callToAction"
>click me
</button>
<b-popover
:target="callToAction"
triggers="click blur"
custom-class="my-popover-class"
>
<div>Edit Me</div>
</b-popover>
</div>
</template>
<style scoped>
*>>>.my-popover-class {
background: black !important;
color: white !important;
}
*>>>.my-popover-class .popover-body {
color: white !important;
background: black !important;
}
</style>
I am familiar with this issue because I use Bootstrap-vue for almost all of my projects.
If I have to override any of the bootstrap components, I just simply remove the scoped from style. If you need to use scoped and also want to override bootstrap components then you should select its wrapper selector and nest it.
For the first selector, you shouldn't need a deep selector, as the class is added to the root element of the popover, which has the data-v-**** attribute from the scoped tag.
The second one you'll need one, but you need to place it after .my-popover-class. That way your selector will be rendered as .my-popover-class[data-v-****] .popover-body, which should work.
<style scoped>
.my-popover-class {
background: black !important;
color: white !important;
}
.my-popover-class >>> .popover-body {
color: white !important;
background: black !important;
}
</style>
Example on codesandbox
I am building an in-app walkthrough with Vuetify. And I need to be able to define the position of many dialogs on the same page. I am able to custom position one dialog with this CSS overriding the default:
>>> .v-dialog {
position: absolute !important;
bottom: 0px !important;
right: 45px !important;
}
And I've tried to use custom classes, with the same css, but they won't work. I'm having to redefine the built in class, and so it will end up placing ALL the dialogs in the same spot which isn't what I want.
I have a sidebar and a content inside a bootstrap row and I want to animate the toggle of the sidebar and to expand seamlessly the content container, I'm applying those transition classes:
.slide-fade-enter {
transform: translateX(100%);
position: relative;
}
.slide-fade-leave, .slide-fade-leave-to {
transform: translateX(-100%);
position: absolute;
}
but it flickers when expanding, you can see it here:
https://jsfiddle.net/kd6xpa32/16/
How can I prevent this?
Looks like you're doing some dirty stuff with flex and absolute positioning. I'd find a way to leave the sidebar as always absolutely (or relatively) positioned and figure out another way to collapse+expand it. The switch between absolute and relative is causing the rendering issue.
Background
We are currently using vue-quill-editor vue-quill-editor to integrate a text editor into a Vue.js app.
As we are using Font Awesome in the app, I have replaced each default toolbar icon with the Font Awesome equivalent.
main.js
import VueQuillEditor from 'vue-quill-editor';
import Quill from 'quill';
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import '#/assets/scss/main.scss';
const icons = Quill.import('ui/icons');
icons['bold'] = '<i class="fa fa-bold" aria-hidden="true"></i>';
icons['italic'] = '<i class="fa fa-italic" aria-hidden="true"></i>';
The only icon that I have not been able to change in this way is the picker/dropdown icon, as it is not in icons.js.
Question
What is the best way to replace the default picker/dropdown icon with a Font Awesome equivalent ( e.g., <i class="fa fa-chevron-down" aria-hidden="true"></i>)?
Thanks!
Thanks for the above solution, Patel.
As it happens, I came up with a simpler solution that does not require creating a custom select option.
I just removed the default svg and added the new icon using :after:
.ql-picker-label {
svg {
width: 0px !important;
}
}
.ql-header,
.ql-size {
.ql-picker-label:after {
color: $black !important;
content: '\f078';
font-family: 'FontAwesome';
position: absolute;
top: 1px !important;
right: 0;
}
}
It seems to work pretty well and will, of course, apply to all such elements.
You can't change drop-down directly but yah you can add custom select option and apply style on it.
Codepen - https://codepen.io/Pratik__007/pen/QWbyWoE
I am using Vuetify and Electron to make an app to help me with certain tasks at my job. I have disable the browserWindow frame and made my header the draggable area with a button to close the window. I am using the electron vuetify template
vue init vuetifyjs/electron
My problem is the scrollbar reaches all the way to the top but I would like it below my fixed header.
I have tried playing with overflow properties on the html, body, app div, and content div tags but i have not been successful.
How would I accomplish this?
This is purely a CSS question really as you can see this behaviour in the browser too with similar layouts. The easiest way to fix this is using a flex layout:
HTML:
<div class="container">
<div class="titlebar"></div>
<div class="content">
<h1>So much content we scroll</h1>
<h1>So much content we scroll</h1>
<!-- etc -->
</div>
</div>
CSS:
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.titlebar {
background-color: blue;
height: 35px;
flex-shrink: 0;
}
.content {
flex-grow: 1;
overflow-x: auto;
}
Check out this out in this CodePen
I'd like to offer a Vuetify specific answer for this question, this should apply whether or not Electron is involved.
Vuetify's default styles make this a bit more difficult than a simple CSS solution can give you, especially when the layout gets more complex.
For this example I'm using the complex layout from Vuetify's pre-defined themes here
Vuetify ships with an overflow-y: scroll on the html element so the first step is adding an override for this.
html {
overflow: hidden;
}
This will get rid of the bar on the right side that spans the whole height of the app.
Next you will want to set your v-content area as the scrollable area. There are a few gotchas to watch out for when you're setting this area:
Display flex is already declared
Vuetify sets padding in the style attribute so you'll need to override depending on your case
You'll need a margin the height of your header(only matters if you're changing header height from 64px)
You'll need to remove the header height from the height of the content container using calc(Same as above)
If you have a nav drawer on the right side you'll need to bind a class to take care of this.
My CSS for v-content looks like this, you will need an important to override the padding since it is set by Vuetify through style binding:
main.v-content {
width: 100vw;
height: calc(100vh - 64px);
flex-direction: column;
overflow: scroll;
margin-top: 64px;
padding-top: 0 !important;
}
I also have a class bound to the state of the temporary right drawer on the v-content tag in the template, this makes sure that the scroll bar doesn't disappear underneath the right nav drawer when it's open:
<v-content :class="{ draweropen: drawerRight }">
And the CSS for that bound class, once again you'll need an important to remove the default right padding Vuetify puts on v-content when the drawer is open:
.draweropen {
width: calc(100vw - 300px) !important;
padding-right: 0 !important;
}
You can optionally set the flex-direction to column-reverse if your content is bottom loaded like a chat which is what I'm doing in this CodePen Example
I built a little component that wraps the v-main and moves the scrollbar to the main container instead of the default (the entire html).
Simply replace v-main with this and you're done.
<template>
<v-main class="my-main">
<div class="my-main__scroll-container">
<slot />
</div>
</v-main>
</template>
<script>
export default {
mounted: function() {
let elHtml = document.getElementsByTagName('html')[0]
elHtml.style.overflowY = 'hidden'
},
destroyed: function() {
let elHtml = document.getElementsByTagName('html')[0]
elHtml.style.overflowY = null
},
}
</script>
<style>
.my-main
height: 100vh
.my-main__scroll-container
height: 100%
overflow: auto
</style>