How do I make a select option wrap when it exceeds the max width?
Asked Answered
C

6

10

For example, I have something like this:

With the following HTML code, I set the max width of the entire dropdown to be 80%, which I expect to affect each of the options.

I want to have it so that long options wrap around at the max point:

Where the red lines indicate what is considered "one option", and thus when I hover over it, everything in between the red lines should be selected

<select name=countries style="width:100%;max-width:30%;">
    <option value=gs selected="selected">All</option>
    <option value=gs>This is fine</option>
    <option value=gs>This message should wrap because it is very long</option>
    <optgroup label="Title">
        <option value="optcheck">Option groups are long, so they should wrap too</option>
    </optgroup>
</select>

https://jsfiddle.net/pxl70474/x7w85fnm/

Cornerstone answered 19/11, 2018 at 3:0 Comment(1)
Not sure if you can modify the styles of the option tag as it's presented native to the platform. Have a look here: #3355479Tezel
F
3

If you are using bootstrap you can use the bootstrap selectpicker class with the data-content attribute.

 <select class="selectpicker form-control" data-live-search="true" 
     id="subject_teacher_drop_down">
   <option data-content="English" title="English">English</option>
   <option data-content="Methodology of social..."  title="Methodology of social science 
     with special reference to economics">
     Methodology of social science with special reference to economics
   </option>
 </select>
Figural answered 19/11, 2018 at 12:53 Comment(1)
data-live-search="true" attaribute will not work after using thisReduction
C
4

To make word wrap, try this css to extend height of container to make enough space to wrap text.

option {
    max-width: 100%;
    overflow: hidden;
    word-wrap: normal !important;
    white-space: normal;
}
Coreycorf answered 27/5, 2021 at 13:7 Comment(1)
Thanks, it helped a lot in fixing BS dropdown length issue.Accessible
L
3

You could try rewriting it like this. I pulled this out of W3Schools. This simply writes the select menu for a responsive view. You could apply it for your site as it does wrap the text. Or figure out some other way to apply it to your site.

var x, i, j, selElmnt, a, b, c;
/*look for any elements with the class "custom-select":*/
x = document.getElementsByClassName("custom-select");
for (i = 0; i < x.length; i++) {
  selElmnt = x[i].getElementsByTagName("select")[0];
  /*for each element, create a new DIV that will act as the selected item:*/
  a = document.createElement("DIV");
  a.setAttribute("class", "select-selected");
  a.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML;
  x[i].appendChild(a);
  /*for each element, create a new DIV that will contain the option list:*/
  b = document.createElement("DIV");
  b.setAttribute("class", "select-items select-hide");
  for (j = 0; j < selElmnt.length; j++) {
    /*for each option in the original select element,
    create a new DIV that will act as an option item:*/
    c = document.createElement("DIV");
    c.innerHTML = selElmnt.options[j].innerHTML;
    c.addEventListener("click", function(e) {
        /*when an item is clicked, update the original select box,
        and the selected item:*/
        var y, i, k, s, h;
        s = this.parentNode.parentNode.getElementsByTagName("select")[0];
        h = this.parentNode.previousSibling;
        for (i = 0; i < s.length; i++) {
          if (s.options[i].innerHTML == this.innerHTML) {
            s.selectedIndex = i;
            h.innerHTML = this.innerHTML;
            y = this.parentNode.getElementsByClassName("same-as-selected");
            for (k = 0; k < y.length; k++) {
              y[k].removeAttribute("class");
            }
            this.setAttribute("class", "same-as-selected");
            break;
          }
        }
        h.click();
    });
    b.appendChild(c);
  }
  x[i].appendChild(b);
  a.addEventListener("click", function(e) {
      /*when the select box is clicked, close any other select boxes,
      and open/close the current select box:*/
      e.stopPropagation();
      closeAllSelect(this);
      this.nextSibling.classList.toggle("select-hide");
      this.classList.toggle("select-arrow-active");
    });
}
function closeAllSelect(elmnt) {
  /*a function that will close all select boxes in the document,
  except the current select box:*/
  var x, y, i, arrNo = [];
  x = document.getElementsByClassName("select-items");
  y = document.getElementsByClassName("select-selected");
  for (i = 0; i < y.length; i++) {
    if (elmnt == y[i]) {
      arrNo.push(i)
    } else {
      y[i].classList.remove("select-arrow-active");
    }
  }
  for (i = 0; i < x.length; i++) {
    if (arrNo.indexOf(i)) {
      x[i].classList.add("select-hide");
    }
  }
}
/*if the user clicks anywhere outside the select box,
then close all select boxes:*/
document.addEventListener("click", closeAllSelect);
/*the container must be positioned relative:*/
.custom-select {
  position: relative;
  font-family: Arial;
}
.custom-select select {
  display: none; /*hide original SELECT element:*/
}
.select-selected {
  background-color: DodgerBlue;
}
/*style the arrow inside the select element:*/
.select-selected:after {
  position: absolute;
  content: "";
  top: 14px;
  right: 10px;
  width: 0;
  height: 0;
  border: 6px solid transparent;
  border-color: #fff transparent transparent transparent;
}
/*point the arrow upwards when the select box is open (active):*/
.select-selected.select-arrow-active:after {
  border-color: transparent transparent #fff transparent;
  top: 7px;
}
/*style the items (options), including the selected item:*/
.select-items div,.select-selected {
  color: #ffffff;
  padding: 8px 16px;
  border: 1px solid transparent;
  border-color: transparent transparent rgba(0, 0, 0, 0.1) transparent;
  cursor: pointer;
  user-select: none;
}
/*style items (options):*/
.select-items {
  position: absolute;
  background-color: DodgerBlue;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 99;
}
/*hide the items when the select box is closed:*/
.select-hide {
  display: none;
}
.select-items div:hover, .same-as-selected {
  background-color: rgba(0, 0, 0, 0.1);
}
<div class="custom-select" style="width:500px;">
  <select>
    <option value="0">HTML5</option>
    <option value="1">Option groups are long, so they should wrap too</option>
    <optgroup label="Title">
      <option value="optcheck">Hypertext Markup Language, a standardized system for tagging text files to achieve font, color, graphic, and hyperlink effects on World Wide Web pages.</option>    
    </optgroup>
  </select>
</div>
Lenin answered 19/11, 2018 at 5:41 Comment(3)
While this is not a simple solution, it does exactly what I needed it to do. No bugs or issues at all! It's responsive and has accommodated text options of all lengths.Householder
As a follow on, is there anyway to copy data attributes from the "original" options to the 'select-selected' and hidden 'select-items' divs? Using jquery, I need to access the data attribute when the option is chosen and the divs don't have the data attributes supplied to the original <option>.Householder
Hello, why the Group title does not appear in this custom select?Diaconicon
F
3

If you are using bootstrap you can use the bootstrap selectpicker class with the data-content attribute.

 <select class="selectpicker form-control" data-live-search="true" 
     id="subject_teacher_drop_down">
   <option data-content="English" title="English">English</option>
   <option data-content="Methodology of social..."  title="Methodology of social science 
     with special reference to economics">
     Methodology of social science with special reference to economics
   </option>
 </select>
Figural answered 19/11, 2018 at 12:53 Comment(1)
data-live-search="true" attaribute will not work after using thisReduction
B
1

This simple change worked for me.

option {
     white-space: break-spaces;
}
Broaden answered 22/11, 2021 at 17:38 Comment(0)
P
0

Expanding on Pulin's answer

To get this to work in Firefox, I needed to target the :before pseudoelement:

option:before {
  white-space: break-spaces;
}

This let my multi-select options take up more than one line of text!

Popovich answered 5/7, 2022 at 23:17 Comment(0)
J
0

Having been unable to use other suggestions successfully, I went with the react-select component. Obviously, only useful if you are using React, but it's a very decent/attractive and easy solution if you are.

Jacquijacquie answered 23/8, 2023 at 16:35 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.