HTML erbjuder ett naturligt sätt att skapa en valruta med stöd för att välja flera objekt med attributet multiple på select-element, men renderingen av detta är inte särskilt kompakt eller snygg, och det finns inte mycket du kan göra när det gäller stil med alternativ i en valruta heller. Jag kunde inte hitta någon anpassad design som passade den stil jag letade efter så det slutade med att jag gjorde min egen. Den fullständiga koden finns på min GitHub här tillsammans med ett matchande sökfält.
Detta är byggt från grunden på grund av svårigheter att ändra beteendet och stilen hos en normal select. Den normalt synliga delen av select är en enkel knapp. Rullgardinsmenyn är en div som döljs av Bootstrap-verktygsklassen d-none, med avrundning och skuggning tillämpad via Bootstrap-verktygsklasserna shadow och rounded. Alternativen är enkla kryssrutor med etiketter. Dessa skulle kunna ersättas med radioknappar om du vill ha en matchande enkel valruta.
Här är den slutliga HTML-koden för knappen och menyn
<div> <button onclick="dropDown(event);" class="menu-btn" type="button"> Menu 1 ⌵ </button> <div class="d-none shadow rounded menu"> <span class="d-block menu-option"><label><input type="checkbox"> Option 1</label></span> <span class="d-block menu-option"><label><input type="checkbox"> Option 2</label></span> <span class="d-block menu-option"><label><input type="checkbox"> Option 3</label></span> </div></div>
Jag ville att menyknappen skulle vara avrundad och ganska liten, så jag stylade den i enlighet med detta (du kan förstås styla den som du vill, det påverkar inte funktionen alls):
.menu-btn { border-radius: 48px; border: 0.5px solid lightgrey; font-size: 0.9em; padding: 2px 10px; background-color: white;}
För själva menyn lade jag till lite utfyllnad så att texten inte skulle springa upp mot menyns överkant och lite marginal så att den inte överlappade knappen (båda är helt frivilliga). Jag lade också till ett högt z-index (så att den visas över andra saker), en bakgrundsfärg (standard är transparent vilket ser dumt ut i det här sammanhanget) och satte positionen till absolut så att den inte trycker ner andra saker på sidan.
.menu { padding-top: 10px; z-index: 200; margin-top: 4px; background-color: white; position: absolute;}
För menyalternativen lade jag till lite utfyllnad för att separera dem.
.menu-option { padding: 6px 20px 6px;}
Vi behöver ett sätt att upptäcka när klick görs utanför rullgardinsmenyn, så att den kan avfärdas genom att man klickar utanför den som en vanlig selectbox. Jag har gjort detta genom att skapa en div som täcker hela skärmen med ett lägre z-index än menyn. Detta gör att vi kan upptäcka alla klick utanför menyn
<div class="d-none" onclick="hide(event)"></div>
#overlay { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 100;}
För att få detta att fungera behöver vi JavaScript-funktioner för att få menyerna och överlagringen att visas och försvinna.
Denna funktion tar bort d-none-klasserna från menyn och overlay och aktiverar dem. I stället för att hantera detta via ID tar den helt enkelt det andra elementet i målets (knappens) överordnade element och antar att det är menyn. Detta är anledningen till att menyn och knappen är omslutna av en annars tom div.
function dropDown(event) { event.target.parentElement.children.classList.remove("d-none"); document.getElementById("overlay").classList.remove("d-none");}
Denna funktion lägger till klassen d-none till överlägget och alla element med klassen menu, vilket döljer dem.
function hide(event) { var items = document.getElementsByClassName('menu'); for (let i = 0; i < items.length; i++) { items.classList.add("d-none"); } document.getElementById("overlay").classList.add("d-none");}
Om du tyckte det här var användbart kanske du också gillar min matchande design för sökfältet.