Bootstrap-vue Tab style - vuejs2

I'm having trouble overriding bootstrap styles in my single file component when using bootstrap-vue
My file looks like this:
<template>
<b-tabs pills vertical>
<b-tab title="This title" title-item-class="mytab" acitve>
Some tab
</b-tab>
<b-tab title="This title 2" title-item-class="mytab">
Some other tab
</b-tab>
</b-tabs>
</template>
<script>
export default {}
</script>
<style lang="less" scoped>
.nav-pills .mytab .nav-link:not(.active) {
background-color: red !important;
}
.nav-pills .mytab .nav-link {
background-color: blue !important;
}
.tab-content > .tab-pane {
border: 1px solid;
border-left: 0px none;
}
</style>
I can inspect my component and I can see that the "mytab" class is being added to the li parent divs with nav-item classname but the css isn't showing up.
It works here: https://jsfiddle.net/3xwmm1qt/43/ but I'm pretty sure it's because the css is being loaded after the page renders. I'm not 100% about that.
Updated I also tried removing the 'scoped' attribute from the style tag and the css still would work. It still doesn't even show up when I inspect the div. I can still see the classname, but in the Rules tab (using FF) there's no styling for my custom classname.

Yeah the difference between the jsfiddle and your code is that you've written scoped CSS (less):
Here's how you fix it, Remove the scoped from style:
<style lang="less">
.nav-pills .mytab .nav-link:not(.active) {
background-color: red !important;
}
.nav-pills .mytab .nav-link {
background-color: blue !important;
}
.tab-content > .tab-pane {
border: 1px solid;
border-left: 0px none;
}
</style>
Scoped means that the css code will only work in this element and vue will try to do it only for the classes attached to the elements which have the class you tried to override while not being scoped means that it'll do it for the entire document hence will override bootstrap's css.

Related

Problems with scoped styles and deep styling in vue 3

Im having a lot of problems triying to style a child from parent in vue3.
In this case, i create a generic button with some css properties, and i try to customize this button from other component
Parent
<template>
<OwnButton
class="accept-button"
#ownButtonClicked="emit('accept')"
>
<slot>
ACCEPT
</slot>
</OwnButton>
</template>
<script setup>
import OwnButton from 'path/to/own-button.vue';
const emit = defineEmits(['accept']);
</script>
<style scoped>
.accept-button :deep(.own-button)
{
background-color : #4CAF50 !important;
outline-color : green !important;
}
.accept-button :deep(.own-button:hover)
{
background-color: green !important;
}
</style>
Child
<template>
<button
class="own-button"
type="button"
#click="emit('ownButtonClicked')"
v-on:keyup.enter="emit('ownButtonClicked')"
>
<slot>
</slot>
</button>
</template>
<script setup>
const emit = defineEmits
([
'ownButtonClicked'
]);
</script>
<style scoped>
.own-button
{
background-color : azure;
outline-color : lightblue;
color : black;
margin : 2px;
padding : 5px;
border-radius : 15px;
border : 0;
box-shadow : 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
outline-style : solid;
min-width : 100px;
max-width : 150px;
}
.own-button:hover
{
cursor: pointer;
}
</style>
I tried everything I could think of, including using :deep(button) in parent
This is a design limitation of Vue 3 when dealing with multi-root nodes
I wrote about this in my article Scoped styles and multi-root nodes don't work well together.
Understanding the issue
In Vue 3 we can finally have more than "one root node" components. That is great, but there is a design limitation when doing that. Imagine we have a child component:
<template>
<p class="my-p">First p</p>
<p class="my-p">Second p</p>
</template>
And a parent component:
<template>
<h1>My awesome component</h1>
<MyChildComponent />
</template>
<style scoped>
// There is no way to style the p tags of MyChildComponent
.my-p { color: red; }
:deep(.my-p) { color: red; }
</style>
There is no way from the scoped styling of the multi-root parent component to style the child component's p tags.
So in short, a multi-root component, can't target multi-root child component's styles with scoped styles.
Solutions
👉 💡 The best way to fix that would be to wrap the parent or child component (or both) so we have only one root element.
But if you absolutely need both to have multi-root nodes, you can:
Use a non-scoped style
<style>
.my-p { color: red; }
</style>
Use CSS Modules
<template>
<h1>My awesome component</h1>
<MyChildComponent :class="$style.trick" />
</template>
<style module>
.trick {
color: red;
}
</style>
Since we are specifying a class here, then the multi-root child component has to explicitly specify the attribute fallthrough behavior.
If you want my opinion, unless you absolutely need a multi-root node component, go with a single root node and don't deal with this design limitation at all.
I think it is related to where you apply the main class.
Try to put a wrapper around like that:
<template>
<div class="accept-button">
<OwnButton
#ownButtonClicked="emit('accept')"
>
<slot>
ACCEPT
</slot>
</OwnButton>
</div>
</template>
<script setup>
import OwnButton from './Comp.vue';
const emit = defineEmits(['accept']);
</script>
<style scoped>
.accept-button :deep(.own-button)
{
background-color : yellow !important;
outline-color : green !important;
}
.accept-button :deep(.own-button:hover)
{
background-color: green !important;
}
</style>
Here is the example above.

Vuetify: changing min-height of v-application--wrap

I am using a vuetify component as a widget on a page along with another content after the widget. However, I have too much free space between the widget and the rest of the page. The vuetify app takes too much height and I can't figure out how to remove it.
Here's how it look in the browser.
I have tried to override the css of App.vue in the following way but it doesn't work. Any suggestions?
<style scoped>
[data-vuetify] {
overflow-y: hidden;
}
[data-vuetify] .v-application--wrap {
min-height: 0vh !important;
}
</style>
Here's how App.vue looks like:
<template>
<div data-vuetify>
<v-app id="app">
<router-view></router-view>
</v-app>
</div>
</template>
<style scoped>
section {
margin: 10px 0;
}
[data-vuetify] {
overflow-y: hidden;
}
[data-vuetify] .v-application--wrap {
min-height: 0vh !important;
}
</style>
Here is the solution that worked for me.
<style scoped lang="scss">
::v-deep .v-application--wrap {
min-height: fit-content;
}
</style>
I have had the same problem and I have solved it as follows:
<style>
.v-application--wrap {
min-height: 0vh !important;
}
</style>
In App.vue
Also, I have built it as a library using vue-cli
I'm new to Vue and Vuetify.
Try unsetting it via CSS in your App.vue file:
<style>
.v-application--wrap {
min-height: unset;
}
</style>
It should unset the default rule "min-height: 100vh;".
For me, I removed <v-app> from the component and added it to the enclosing page (I'm using Nuxt) which removed the extra space from the component.

How to apply style to buttons within div in a component?

I am trying to make a component with buttons inside a div, I am having issues, because the styles are not applying on the buttons, I guess I should not use slot here. Can someone guide me?
Component
<template>
<div :class="[$style.btnGroup]" v-bind="$attrs">
<slot :class="$style[variant]">/>
</div>
</template>
How I use this
<ButtonGroup variant="warning">
<button>Test</button>
<button>Test</button>
<button>Test</button>
</ButtonGroup>
I use css module
<style module>
.btnGroup button {
position: relative;
border: none;
font-weight: 400;
border-radius: 0.25rem;
cursor: pointer;
font-size: 1rem;
padding: 0.5rem 1rem;
transition: 0.1s;
}
.primary{
background: var(--primary-bg);
border: 1px solid var(--primary-bg);
color: white;
}
.warning {
background: var(--warning-bg);
border: 1px solid var(--warning-bg);
font-size: 1rem;
padding: 0.5rem 1rem;
transition: 0.1s;
color: black;
}
etc. for each variant I have different style.
You are applying the class on the button group not the buttons that are inside, to solve this instead of binding the class to the slot bind another variable and use that variable binding on each button or you can solve it through css thats why i suggested you show us the css give a class to the buttongroup the way you are doing and in css do as so:
<slot class="buttongroupclass">/>
.buttongroupclass button{
//the css you want to apply
}

Use CSS classes in Vue based on breakpoints

I have tried using a vuetify class based on breakpoint it worked
<v-app :class="{'yellow': !$vuetify.breakpoint.xs}">
I have a class named pagemargin in a vue file
But when I use this class it is not working, as in the following case
<v-app :class="{'pagemargin': !$vuetify.breakpoint.xs}">
why is it not working?
<style >
.pagemargin{
margin-right: 100px;
margin-left: 100px;
color: red;
}
</style>
Add !important to your styles. Vuetify adds its default style to the whole v-app so you need to override it.
.pagemargin{
margin-right: 100px !important;
margin-left: 100px !important;
color: red !important;
}
Using !important might work, but in long term as your application gets bigger, it could be costly. You should instead, solve this by providing a CSS that has a higher specificity than that of Vuetify. I provide you with an example:
<template>
<div class="my-div">
<v-btn :class="{'my-padding': !$vuetify.breakpoint.xs}" tile outlined color="success">
View
</v-btn>
</div>
</template>
<style>
/* this wont work */
.my-div .my-padding {
padding-right: 200px;
padding-left: 200px;
}
/* this works */
.my-div .v-btn.my-padding {
padding-right: 200px;
padding-left: 200px;
}
</style>
<style scoped>
/* this also works */
.my-div .my-padding {
padding-right: 200px;
padding-left: 200px;
}
</style>
You can read more about specificity here.

buefy input not changing border style color

I wanted to change the style of b-input buefy but when I try changing the design it doesn't work.
Here is my code.
<b-field>
<b-input
placeholder="Username"
size="is-medium"
></b-input>
</b-field>
<style>
input.input.is-medium {
border: 1px solid red;
}
</style>
If you want to change all your buttons, take a look at Bulma's variables.
Buefy uses Bulma CSS
https://bulma.io/documentation/elements/button/#variables
Here, you will want to change $button-border-color
Late answer.
The selector seems correct, so I'm not sure why it doesn't work for you. Your example works in my environment (Buefy 0.9.4, Vue 2.6.10).
You might try a less specific selector:
input {
border: 1px solid red;
}
Or... (cringe) use the important flag:
input.input.is-medium {
border: 1px solid red !important;
}
To customize just a single input, try assigning a ref attribute to the <b-input> and then use JS to update the style. Note that <b-input> creates a <div> that wraps the <input>, so we have to go hunting for it using $el and querySelector.
Buefy HTML
<b-input
ref="myInput"
placeholder="Username"
size="is-medium"
></b-input>
VueJS
mounted() {
this.$refs.myInput.$el.querySelector('input').style.border = "1px solid red";
},