Select/Dropdown Generator
Design styled select dropdown components
Style Presets
Dropdown Options
Size & Dimensions
Colors
Dropdown Menu
Border & Shape
Arrow
Effects
Live Preview
Click dropdown to test interaction
States Preview
Default
Focused
Selected
Disabled
Generated CSS
.custom-select-wrapper {
position: relative;
width: 280px;
font-family: system-ui, -apple-system, sans-serif;
}
.custom-select {
width: 100%;
height: 44px;
padding: 0 44px 0 16px;
font-size: 16px;
color: #374151;
background-color: #ffffff;
border: 1px solid #d1d5db;
border-radius: 8px;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236b7280'%3E%3Cpath fill-rule='evenodd' d='M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z' clip-rule='evenodd'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 13px center;
background-size: 18px;
transition: all 0.2s ease;
outline: none;
}
.custom-select:hover {
background-color: #f3f4f6;
border-color: #3b82f6;
}
.custom-select:focus {
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}
.custom-select:disabled {
background-color: #f9fafb;
color: #9ca3af;
cursor: not-allowed;
opacity: 0.7;
}
/* For Firefox */
.custom-select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #374151;
}
/* Hide default arrow in IE */
.custom-select::-ms-expand {
display: none;
}
/* Dropdown options (native) */
.custom-select option {
padding: 12px;
background-color: #ffffff;
color: #374151;
}
.custom-select option:checked {
background-color: #dbeafe;
}
/* Placeholder styling */
.custom-select option[value=""] {
color: #9ca3af;
}
/* === Custom Dropdown (JS-based) === */
.custom-dropdown {
position: relative;
width: 280px;
font-family: system-ui, -apple-system, sans-serif;
}
.custom-dropdown-trigger {
width: 100%;
height: 44px;
padding: 0 44px 0 16px;
font-size: 16px;
color: #374151;
background-color: #ffffff;
border: 1px solid #d1d5db;
border-radius: 8px;
cursor: pointer;
text-align: left;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236b7280'%3E%3Cpath fill-rule='evenodd' d='M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z' clip-rule='evenodd'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 13px center;
background-size: 18px;
transition: all 0.2s ease;
outline: none;
}
.custom-dropdown-trigger:hover {
background-color: #f3f4f6;
}
.custom-dropdown-trigger:focus,
.custom-dropdown.open .custom-dropdown-trigger {
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}
.custom-dropdown.open .custom-dropdown-trigger {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236b7280'%3E%3Cpath fill-rule='evenodd' d='M5.293 12.707a1 1 0 011.414 0L10 10.586l3.293 3.293a1 1 0 111.414 1.414l4-4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z' clip-rule='evenodd'/%3E%3C/svg%3E");
}
.custom-dropdown-menu {
position: absolute;
top: calc(100% + 4px);
left: 0;
width: 100%;
max-height: 200px;
overflow-y: auto;
background-color: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 8px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
z-index: 1000;
opacity: 0;
transform: translateY(-8px);
visibility: hidden;
transition: all 0.2s ease;
}
.custom-dropdown.open .custom-dropdown-menu {
opacity: 1;
transform: translateY(0);
visibility: visible;
}
.custom-dropdown-option {
padding: 12px 16px;
font-size: 16px;
color: #374151;
cursor: pointer;
transition: background-color 0.2s ease;
}
.custom-dropdown-option:first-child {
border-radius: 7px 7px 0 0;
}
.custom-dropdown-option:last-child {
border-radius: 0 0 7px 7px;
}
.custom-dropdown-option:hover {
background-color: #eff6ff;
}
.custom-dropdown-option.selected {
background-color: #dbeafe;
font-weight: 500;
}
.custom-dropdown-option:focus {
outline: none;
background-color: #eff6ff;
}HTML
<!-- Native Select (Simple, Accessible) -->
<div class="custom-select-wrapper">
<select class="custom-select">
<option value="">Select an option</option>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</select>
</div>
<!-- Custom Dropdown (Full Styling Control) -->
<div class="custom-dropdown" id="myDropdown">
<button
class="custom-dropdown-trigger"
type="button"
aria-haspopup="listbox"
aria-expanded="false"
>
Select an option
</button>
<div class="custom-dropdown-menu" role="listbox">
<div class="custom-dropdown-option" role="option" data-value="option1">Option 1</div>
<div class="custom-dropdown-option" role="option" data-value="option2">Option 2</div>
<div class="custom-dropdown-option" role="option" data-value="option3">Option 3</div>
</div>
</div>JavaScript (for Custom Dropdown)
// Custom Dropdown JavaScript
document.addEventListener('DOMContentLoaded', () => {
const dropdown = document.getElementById('myDropdown');
const trigger = dropdown.querySelector('.custom-dropdown-trigger');
const menu = dropdown.querySelector('.custom-dropdown-menu');
const options = dropdown.querySelectorAll('.custom-dropdown-option');
let selectedValue = '';
let selectedLabel = 'Select an option';
// Toggle dropdown
trigger.addEventListener('click', () => {
const isOpen = dropdown.classList.contains('open');
dropdown.classList.toggle('open');
trigger.setAttribute('aria-expanded', !isOpen);
});
// Handle option selection
options.forEach(option => {
option.addEventListener('click', () => {
// Update selected state
options.forEach(opt => opt.classList.remove('selected'));
option.classList.add('selected');
// Update values
selectedValue = option.dataset.value;
selectedLabel = option.textContent;
trigger.textContent = selectedLabel;
// Close dropdown
dropdown.classList.remove('open');
trigger.setAttribute('aria-expanded', 'false');
// Dispatch change event
dropdown.dispatchEvent(new CustomEvent('change', {
detail: { value: selectedValue, label: selectedLabel }
}));
});
// Keyboard navigation
option.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
option.click();
}
});
});
// Close on outside click
document.addEventListener('click', (e) => {
if (!dropdown.contains(e.target)) {
dropdown.classList.remove('open');
trigger.setAttribute('aria-expanded', 'false');
}
});
// Keyboard navigation for trigger
trigger.addEventListener('keydown', (e) => {
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
e.preventDefault();
if (!dropdown.classList.contains('open')) {
dropdown.classList.add('open');
trigger.setAttribute('aria-expanded', 'true');
}
const firstOption = menu.querySelector('.custom-dropdown-option');
if (firstOption) firstOption.focus();
}
if (e.key === 'Escape') {
dropdown.classList.remove('open');
trigger.setAttribute('aria-expanded', 'false');
}
});
});Usage & Accessibility
Two Approaches
- Native Select: Best for accessibility, works without JavaScript, limited styling options
- Custom Dropdown: Full styling control, requires JavaScript, needs ARIA attributes for accessibility
Accessibility Tips
- Use
aria-haspopup="listbox"on the trigger button - Toggle
aria-expandedwhen dropdown opens/closes - Use
role="listbox"on the menu androle="option"on items - Support keyboard navigation (Arrow keys, Enter, Escape)
- Ensure sufficient color contrast (4.5:1 minimum)
- Provide visible focus indicators
Best Practices
- Keep the dropdown list reasonably short (consider search for 10+ items)
- Provide a clear placeholder or default option
- Close dropdown when clicking outside
- Show the selected item clearly in the trigger
Need Custom Form Components?
Brix340 specializes in creating accessible, beautiful form designs that enhance user experience.
Get Professional Help