SHARE
Facebook X Pinterest WhatsApp

Customizing Multi-select Lists with CSS

Nov 24, 2021

Build a Web Form with HTML – Part 7

In this series on Web Forms, we’ve been learning how to create and style common form controls. In the last installment, we learned how to customize the standard <select> element. As described there, selects come in a second flavor, which allows a user to select more than one option. It appears as a list, without a drop-down component:

Multi-Select CSS tutorial

 

This installment will cover the creation and customizing of multi-select lists as well as how to disable <select> elements.

Before we move on, however, you may want to refresh your memory by revisiting the previous articles in this series:

Creating a Multiple Select List in CSS

From an HTML perspective, all you have to do to turn a standard <select> element into on that allows a user to select more than one option is to add the multiple attribute. For customization purposes, we’ll wrap the <select> within a <div> that includes a class called select-multiple:

<label for="multi-select">Multiple Select</label>
<div class="select select-multiple">
  <select id="multi-select" multiple>
    <option value="MIaM">Mouse In A Maze</option>
    <option value="PL">Private Life</option>
    <option value="SA">Suspended Animation</option>
    <option value="NQ">No Quarter</option>
    <option value="11:11">11:11 Ultimate Edition</option>
    <option value="UV">Ultraviolence</option>
    <option value="TC">The Core (with outro solo)</option>
    <option value="TK">Telekinetic Killer</option>
    <option value="ALL">All of the above</option>
    <option value="NONE">None of the above</option>
  </select>
  <span class="focus"></span>
</div>

Here is our song list with no styling whatsoever:

Multi Select List Example CSS

 

General Select Styling in CSS

All of the styles that we employed previously to customize the standard <select> element are still applicable here. For reference, here are those styles using Sassy CSS (SCSS):

:root {
  --select-border: #393939;
  --select-focus: #101484;
  --select-arrow: var(--select-border);
}

select {
  // styles reset, including removing the default dropdown arrow
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-color: transparent;
  border: none;
  padding: 0 1em 0 0;
  margin: 0;
  width: 100%;
  font-family: inherit;
  font-size: inherit;
  cursor: inherit;
  line-height: inherit;

  // Stack above custom arrow
  z-index: 1;

  // Remove focus outline
  outline: none;
}

.select {
  display: grid;
  grid-template-areas: "select";
  align-items: center;
  position: relative;

  select,
  &::after {
    grid-area: select;
  }

  min-width: 15ch;
  max-width: 30ch;
  border: 1px solid var(--select-border);
  border-radius: 0.25em;
  padding: 0.25em 0.5em;
  font-size: 1.25rem;
  cursor: pointer;
  line-height: 1.1;

  // Optional styles
  // remove for transparency
  background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);

  // Custom arrow
  &::after {
    content: "";
    justify-self: end;
    width: 0.8em;
    height: 0.5em;
    background-color: var(--select-arrow);
    clip-path: polygon(100% 0%, 0 0%, 50% 100%);
  }
}

We can see their effects on a multi-select below.

Multi Select CSS styling

 

Overall it looks quite good. The only issue is that the selected options don’t extend all the way to the vertical scroll bar.

So, let’s fix that now by setting the padding-right in a new rule that specifically targets multiple selects:

select[multiple] {
  padding-right: 0;
  height: 7rem;
}

The height determines how many items are visible in the list at any one time without scrolling. Safari will not show partial options, while Firefox, Chrome and Microsoft Edge do. You can see a partial option in Edge here:

CSS Styling tutorial

 

Setting the Focus Border

Having removed the default <select> element using the CSS appearance attribute, we now have to set the focus border ourselves. As we did last time, we’ll employ a CSS variable for the color:

select:focus + .focus {
  position: absolute;
  top: -1px;
  left: -1px;
  right: -1px;
  bottom: -1px;
  border: 2px solid var(--select-focus);
  border-radius: inherit;
}

Now, tabbing to the multi-select list shows this:

Multi Select Border Focus CSS

 

There is also a border around the first option (not added by us) so that the user can navigate through the items using the UP and DOWN arrow keys.

Disabling Selects

The handling of disabled selects must also fall upon our shoulders. To do that, we’ll add the select-disabled class to the <div> wrapper as well as the disabled attribute on the <select> itself. For completeness, both the multiple and standard <select> are shown below:

<!-- Multi-select -->
<div class="select select-disabled select-multiple">
  <select id="multi-select-disabled" multiple disabled>
    <!-- options -->
  </select>
</div>

<!-- Standard Select -->
<div class="select select-disabled">
  <select id="standard-select-disabled" disabled>
    <!-- options -->
  </select>
</div>  

Using our .select-disabled class, we can alter the select’s appearance to give it that “greyed out” look:

.select-disabled {
  cursor: not-allowed;
  background-color: #eee;
  background-image: linear-gradient(to top, #ddd, #eee 33%);
}

When one hovers the cursor over the disabled select, the it turns into a “not-allowed” cursor, which is a red circle with a line through it, sort of like the Ghost Busters logo.

Behind the scenes, the disabled attribute that we added to the <select> tag makes the control unresponsive to all user interactions.

Disabled Select CSS Example

 

You’ll find the demo for this tutorial on codepen.io.

Conclusion

In this installment of the Build a Web Form with HTML series, we went through the process of creating and customizing a multi-select list and learned how to disable <select> elements. In the next and final article of the series we’ll change gears by integrating JavaScript into an HTML form to make it more interactive.

Recommended for you...

Importing Custom Less Styles at Run-time in Angular
Rob Gravelle
Jun 14, 2022
Setting CSS Values from Less Variables in Angular
Rob Gravelle
Jun 4, 2022
Color Manipulation with JavaScript
Rob Gravelle
May 21, 2022
An Introduction to CSS-in-JS
Rob Gravelle
May 14, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.