vue-select
vue-select copied to clipboard
Values longer than field itself breaks UI
https://codepen.io/anon/pen/QYxxOr
This can probably be fixed by applying these styles to that container:
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
That is also a borderline-unreasonable width for a dropdown with country values in it :)
I fixed re-writing flex-wrap for the container
.v-select .vs__selected-options {
flex-wrap: nowrap;
}
it works ok for me.
This can probably be fixed by applying these styles to that container:
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
That is also a borderline-unreasonable width for a dropdown with country values in it :)
Her is what is rendering in our application:
When I implement this fix the selected text that overflows looks good, but overflow: hidden;
prevents the drop down box from rendering outside of the bounds of the container.
I fixed re-writing flex-wrap for the container
.v-select .vs__selected-options { flex-wrap: nowrap; }
it works ok for me.
This just breaks up a long value word wrapping every word causing the text to be out of bounds of the box.
We've been facing this problem for months, and mostly we've either put up with some of the ugliness of it, or we've adjusted the size of the select box to accommodate. However, this particular use case it would not be appropriate for either of those options.
I've also tried narrowing down the scss down to the text are tag with the following and still the overflow: none;
continues to break the drop down box.
.ept_v-select-oem, .dropdown-toggle, .vs__selected-options, .selected-tag {
text-overflow: clip;
white-space: nowrap;
flex-wrap: nowrap;
overflow: none;
}
Here is the Vue html with the v-select container. The class on the container div is where I'm applying styles. I've tried applying them to the v-select as well, and using various other scss stylings in attempt to overwrite the v-select css has not garnered sufficient results.
<div class="ept_v-select-oem">
<label for="oem">{{ getContentItem("OEM") }}:</label>
<v-select
id="oem"
v-model="oem"
:options="oemListOptions.Items"
name="oem"
:select-on-tab="true"
class="form-control"
@search="searchOems"
/>
</div>
I ran into this same issue this evening, and adding the following CSS helped:
.vs__selected-options {
flex-wrap: nowrap;
max-width: calc(100% - 25px); /* change this to `- 40px` if you're supporting a `clearable` field; I was not */
}
.vs__selected {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
overflow: hidden;
}
@aaronransley. The fix is pretty decent. But not ideal. There is still the element .vs__search
making the text narrower than it could be in the field when selected.
@aaronransley. The fix is pretty decent. But not ideal. There is still the element
.vs__search
making the text narrower than it could be in the field when selected.
We shifted to creating our own CSS styles and applying them to vanilla HTML 5 inputs. FWIW.
@aaronransley. The fix is pretty decent. But not ideal. There is still the element
.vs__search
making the text narrower than it could be in the field when selected.
@ipa1981 I noticed this as well, but couldn't figure out a way to target the appropriate combinations of classes to hide the .vs__search
field when not needed. It seems to be used for the placeholder label, as well as when the dropdown is open, but I didn't dig too deep.
@sagalbot Is there an official recommendation on how to work around these low-width dropdown edge cases?
Got caught by that today. Any fixes that do work in the latest version?
I’ve tried all the suggestions here and can’t make this work. My content is loading in a sidebar (an Outlook add-in), so the width is small and out of my control. A solution would be much appreciated!
I managed to have this:
.vs__selected-options {
flex-wrap: nowrap;
max-width: calc(100% - 41px);
}
.vs__selected {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
overflow: hidden;
}
.vs__search {
position: absolute;
}
.vs--open .vs__search {
position: static;
}
.vs__dropdown-option {
white-space: normal;
}
This fix the long text for closed vue-selects, fix long text in options during the search (they now break line).
@sobrinho Good enough. However it has some problem with "jumping" element height (look below). It does not dynamically respect "clearance" button like in @aaronransley example also.
Moreover all our examples break vue-select in multiple mode.
It would be amazing if @sagalbot would somehow recommend how to perfectly resolve this.
Yeah, I only have a single-mode here, so I didn't try to fix it at all.
The best would be a fix in the project, I will try in the next days and open a PR.
Any update on this?
It's still the big problem to use vue-select in our project. So sad...
Its a massive problem still. We use this a lot and after hacking tons of CSS it still doesn't work properly.
This should be a priority fix as it breaks the UI, apart from that the component is spot on.
Also having this problem with a timezone field.
Moreover all our examples break vue-select in multiple mode.
It would be amazing if @sagalbot would somehow recommend how to perfectly resolve this.
Most of the time we can easily figure out what the ellipsis stands for in single mode. But it's recommeded not to omit overflowed options in multiple mode. It's better to leave the multiple mode alone: narrow the css selector to '.vs--single .vs__selected-options' and '.vs--single .vs__selected-options'.
I haven't done much testing, I'm admittedly not a CSS guru per se, and this solution is a bit hackish, but I think it's going to do the trick in my scenario:
.v-select:not(.vs--open) .vs__dropdown-toggle .vs__selected-options .vs__selected + input {
position: absolute;
}
The + is the sibling selector and .vs__selected only exists when something is selected and excluding .vs--open will display it whenever the dropdown is open. The regular placeholder and everything show up when nothing is selected, you can type in the field normally when something is selected, and the input element still exists and is part of the regular tab order... but it won't affect the geometry of the element.
Not the most beautiful thing in the world, but many of the long names we deal with would be similar or exactly the same with only the first few characters revealed.
If someone sees a big caveat to this approach that I'm missing, I'd be happy to hear it. Maybe there's another element under .vs__selected-options in some situations that could make the input and .vs__selected element no longer direct siblings, or something?
The solution that works for me is this (For single select)
.v-select {
&:not(.vs--open) {
.vs__selected + .vs__search {
height: 0;
margin: 0;
}
}
.vs__selected-options {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
The solution that works for me is this (For single select)
.v-select { &:not(.vs--open) { .vs__selected + .vs__search { height: 0; margin: 0; } } .vs__selected-options { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } }
This Works For Single Option Thanks @yoongti :D
Solution which worked for me, for single select, inspired by @yoongti
.vs--single {
&:not(.vs--open) .vs__selected + .vs__search {
// force this to not use any space
// we still need it to be rendered for the focus
width: 0;
padding: 0;
margin: 0;
border: none;
height: 0;
}
.vs__selected-options {
// do not allow growing
width: 0;
}
.vs__selected {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
overflow: hidden;
}
}
All the above solutions are great, however, they don't take the deselect button into consideration. Which I think should not be lost/truncated.
In case of a multiple select where your selected options leave the container like in this example:
Truncating is great and at 1st glance does the job:
However, looking at this example the deselect button is lost. I've made a "fix" not a "solution" to maintain the deselect button, using position absolute and giving the container a padding-right in order to "reserve" this space for the deselect button.
.vs__selected {
position: relative;
display: block;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
overflow: hidden;
padding-right: 20px;
.vs__deselect {
position: absolute;
right: 0;
margin: 4px 2px 0 2px;
padding: 0 0.25em;
}
}
Hope this helps others.
Solution which worked for me, for single select, inspired by @yoongti
.vs--single { &:not(.vs--open) .vs__selected + .vs__search { // force this to not use any space // we still need it to be rendered for the focus width: 0; padding: 0; margin: 0; border: none; height: 0; } .vs__selected-options { // do not allow growing width: 0; } .vs__selected { display: block; white-space: nowrap; text-overflow: ellipsis; max-width: 100%; overflow: hidden; } }
This no longer works for vue-select v4 (with Vue 3) when no option is selected since the vs__selected
span exists:
After clicking the clear button, however, it goes back to normal:
Solution which worked for me, for single select, inspired by @yoongti
.vs--single { &:not(.vs--open) .vs__selected + .vs__search { // force this to not use any space // we still need it to be rendered for the focus width: 0; padding: 0; margin: 0; border: none; height: 0; } .vs__selected-options { // do not allow growing width: 0; } .vs__selected { display: block; white-space: nowrap; text-overflow: ellipsis; max-width: 100%; overflow: hidden; } }
This no longer works for vue-select v4 (with Vue 3) when no option is selected since the
vs__selected
span exists:After clicking the clear button, however, it goes back to normal:
Ah nvm it was that I was using an empty string instead of null
for the initial value which meant that it assumed that something was selected. Convert the modelValue
to null when mounted to fix:
mounted() {
if (!this.modelValue) {
this.$emit('update:modelValue', null)
}
},
For anyone else who lands here and above doesn't work, you have to also make sure you're also not scoping your css:
<style>
Works, <style scoped>
Doesn't work
Whilst not perfect could a title attribute on each option help? When you hover the full title is displayed as a tooltip. Doesn’t help touch screen devices but would probably solve the issue for my usage.
@aaronransley solution has fixed my issues. Am using a single select and wanted the overflown text to be hidden behind an ellipsis as seen in the shot below. I am using vue 2x and Laravel 7x, thanks Aaron. However, i agree the project needs to get a long term solution that can move us away from these hacks
https://codepen.io/anon/pen/QYxxOr
I've fixed this issue by adding this CSS properties:
.multiselect__single {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}