vue-select icon indicating copy to clipboard operation
vue-select copied to clipboard

Values longer than field itself breaks UI

Open ipa1981 opened this issue 5 years ago • 28 comments

image

https://codepen.io/anon/pen/QYxxOr

ipa1981 avatar Feb 12 '19 18:02 ipa1981

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 :)

agm1984 avatar Mar 31 '19 18:03 agm1984

I fixed re-writing flex-wrap for the container

.v-select .vs__selected-options {
    flex-wrap: nowrap;
}

it works ok for me.

wmarcos avatar Jun 12 '19 15:06 wmarcos

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: image

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. image

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. image

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>

theGrower avatar Apr 17 '20 17:04 theGrower

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 avatar Jul 06 '20 07:07 aaronransley

@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.

image

ipa1981 avatar Jul 07 '20 14:07 ipa1981

@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.

image

We shifted to creating our own CSS styles and applying them to vanilla HTML 5 inputs. FWIW.

theGrower avatar Jul 07 '20 14:07 theGrower

@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.

image

@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?

aaronransley avatar Jul 07 '20 17:07 aaronransley

Got caught by that today. Any fixes that do work in the latest version?

sobrinho avatar Jul 07 '20 19:07 sobrinho

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!

mwickens avatar Jul 07 '20 22:07 mwickens

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 avatar Jul 07 '20 22:07 sobrinho

@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.

Peek 2020-07-08 10-22

Moreover all our examples break vue-select in multiple mode.

image

It would be amazing if @sagalbot would somehow recommend how to perfectly resolve this.

ipa1981 avatar Jul 08 '20 07:07 ipa1981

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.

sobrinho avatar Jul 08 '20 12:07 sobrinho

Any update on this?

XNL073 avatar Dec 14 '20 15:12 XNL073

It's still the big problem to use vue-select in our project. So sad...

TrumanRu avatar Mar 01 '21 09:03 TrumanRu

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.

tonykaralis avatar Mar 17 '21 09:03 tonykaralis

Also having this problem with a timezone field.

jeff-wood-readyup avatar Mar 24 '21 18:03 jeff-wood-readyup

Moreover all our examples break vue-select in multiple mode.

image

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'.

abellong avatar May 28 '21 03:05 abellong

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.

Screen Shot 2021-06-08 at 1 52 08 PM

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?

ChefAndy avatar Jun 08 '21 18:06 ChefAndy

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;
    }
  }

felixfirefighter avatar Jul 04 '21 09:07 felixfirefighter

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

consciousnessdev avatar Aug 25 '21 07:08 consciousnessdev

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;
  }
}

image

edcoreweb avatar Sep 21 '21 17:09 edcoreweb

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: image

Truncating is great and at 1st glance does the job: image

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;
    }
}

image

Hope this helps others.

tomvanvegchel avatar Feb 01 '22 10:02 tomvanvegchel

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;
  }
}

image

This no longer works for vue-select v4 (with Vue 3) when no option is selected since the vs__selected span exists: image

After clicking the clear button, however, it goes back to normal: image

matthewknill avatar Apr 28 '22 00:04 matthewknill

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;
  }
}

image

This no longer works for vue-select v4 (with Vue 3) when no option is selected since the vs__selected span exists: image

After clicking the clear button, however, it goes back to normal: image

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)
    }
},

matthewknill avatar Apr 28 '22 22:04 matthewknill

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

Credit to this post

rohstar avatar Jun 29 '22 07:06 rohstar

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.

RicLeP avatar Jul 19 '22 15:07 RicLeP

@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

image

ebaguma avatar Mar 18 '23 04:03 ebaguma

image

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;
}

YRlp98 avatar Oct 11 '23 09:10 YRlp98