vue-select
vue-select copied to clipboard
How to apply css to dropdown list when the prop appendToBody is true
How can I apply some css to change background of the dropdown list, when I'm using the prop appendToBody, the div is at the end of the body, there is some way to add a class or replace the ID?
I'm trying to applying some dark style...
<v-select class="select-x" taggable v-model="value" append-to-body :options="options"></v-select>
Can you please give me an idea to solve this @sagalbot
The .vs__dropdown-menu
class is still applied, you can target that for your css 👍🏻
@sagalbot is there a way to add a unique class or ID?
I think the problem is that when setting a class (like it is described here), this class is not applied to .vs__dropdown-menu
in the body. So there is no way to style this individually for one rendered component.
I also would like to be able to add a dynamic class to the dropdown menu. I have multiple dropdown menu styles set in my wrapper component, and I need appendToBody
, but it breaks my custom styles.
edit: My current workaround is to read the VueSelect component uid
on mount, and inject global styles with vue-styled-components
targetting the id of .vs__dropdown-menu
which is #vs1__listbox
for example, if the uid
is 1
. Work-in-progress example:
onMounted(() => {
if (vueSelect.value !== null) {
const uid = vueSelect.value.$data.uid
let menuSpecificStyles = ''
if (isMenu.value) {
menuSpecificStyles = `
border: 0;
background-color: ${colors.grey.default};
border-radius: 0 0 0.2rem 0.2rem;
padding: 0;
left: auto;
right: 0.1rem;
top: calc(100% + 0.1rem);
width: auto;
min-width: auto;
.vs__dropdown-option {
border-color: ${colors.grey[553]};
color: ${colors.white};
text-align: right;
background-color: ${colors.grey.default};
margin: 0 1.2rem 0 0.5rem;
padding-left: 2.8rem !important;
&:hover {
color: ${colors.grey[790]};
}
}
`
}
injectGlobal`
#vs${uid}__listbox {
.vs__dropdown-option--highlight {
background: ${themeColor};
}
${menuSpecificStyles}
}
`
}
})
edit: I should note that the solutions below that add a classname are better, but in my case I need styled components to enable use of a dynamic theme color.
@sagalbot Why is this issue closed? Is it mean you do not understand a problem, or you won't to fix it? Custom class applied for dropdown will do the job. Now there is no way to style specific dropdown which is append to body without custom ugly JS like:
mounted() {
let style = document.createElement('style');
style.innerText = `#vs${this.$refs.select.$data.uid}__listbox{"some rules"}`;
document.querySelector('body').appendChild(style);
},
My workaround is as follows, and prevents me from having to inject global CSS.
mounted() {
this.$refs.select.$on("open", async () => {
await this.$nextTick();
await this.$nextTick();
this.$refs.select?._vnode.children.forEach(({ elm }) => {
if (elm instanceof HTMLElement && elm.tagName === "UL") {
elm.classList.add(this.remoteClassName);
}
});
});
}
It'd be nice to have prop for a custom class-name though, so that we don't have to do hacks like this. The changes I want to do in this scenario are not changes I want to apply to all dropdowns.
One more workaround is to use calculatePosition with Propper.js, the dropdown menu element can be edited when adjusting the position.
<v-select :options="countries" append-to-body :calculate-position="withPopper" />
methods: {
withPopper (dropdownList, component, {width}) {
dropdownList.classList.add("style-chooser");
// ... adjust the position
}
}
<style>
.style-chooser.vs__dropdown-menu {
background: #dfe5fb;
border: none;
color: #394066;
text-transform: lowercase;
font-variant: small-caps;
}
</style>
@SchmidtDawid I didn't fully understand the scope of the issue.
@alantea thanks for posting your solution! It's almost perfect, but it leaves you in charge of implementing the positioning yourself. Let me know what you think of the API in #1341. @EricRabil & @uturnr, would this API work for you as well?
<v-select @dropdown:appending="({ el }) => el.classList.add('style-chooser')" />
Looks great. Thank you!
@sagalbot , it looks great.
@sagalbot Looks good to me!
@sagalbot, what do you think about dropdown-class
property?
@sagalbot, what do you think about
dropdown-class
property?
This would probably be better because classes dynamically added with classList
will be removed on rerender.