
CSS Country Selector Dropdown With Flags
Published
20 hand-coded CSS custom select dropdown templates for checkout, dashboards, and SaaS forms — country selector with flag chips, currency picker with USD / EUR / GBP symbols, credit card type selector with Visa / Mastercard / Amex marks, three-tier pricing plan switcher, user avatar profile menu, minimalist language switcher with native + English names, B2B workspace switcher with team badges, dark-mode theme selector (Light / Dark / System), multi-select tag dropdown with removable chips, status filter with In Progress / Completed pills, date-range picker with Last 7 Days presets, product sorting filter, dropdown with option subtext, font-family preview picker, file-type media uploader with PDF / CSV / PNG icons, color swatch picker, Tailwind-style utility select, slide/fade transition dropdown, floating-label form select, and a glassmorphism dark-UI dropdown with backdrop blur. Every widget ships role="listbox", aria-expanded, arrow-key navigation, Enter/Space commit, Escape close, and focus return — the WAI-ARIA combobox pattern for accessible custom selects. Scoped under .cs-NN for no-collision pasting, prefers-reduced-motion guarded on every open/close animation, framework-agnostic (Tailwind arbitrary values + React / Vue / Next mappings documented per demo).
Related16 CSS Floating Label Inputs22 CSS Dropdown Menu Designs20 CSS Popovers

Published

Published

Published

Published
Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published
element — usually a trigger paired with a role="listbox" panel of role="option" items. Developers customize the native because browsers historically restricted what CSS could style: the option list, the highlight color, the padding, the icons — all locked. The workarounds (like replacing with radios or complex trees) broke keyboard access, screen readers, and form submission. This gallery ships 20 accessible hand-coded custom-select patterns that keep the WCAG 2.1 combobox contract intact: role="combobox" on the trigger, role="listbox" on the panel, role="option" on each item, aria-expanded + aria-controls + aria-activedescendant for state, and full keyboard navigation (Arrow / Enter / Space / Escape / Home / End) with focus return to the trigger on close. Every demo also degrades to a static, readable layout when JavaScript is disabled — no document.body state, no framework lock-in, no third-party library.How do I pick the right custom select pattern for my use case (checkout, dashboard, SaaS form, or a specialized picker)?
Match the pattern to the content and audience. E-commerce and payment checkouts ship Demo 01 Country Selector Dropdown With Flags (gradient-drawn flag chips + country name, keyboard arrow navigation — the Stripe / Shopify / Airbnb shipping-address convention). Fintech checkout and pricing use Demo 02 Currency Picker Dropdown With Symbols (USD / EUR / GBP with tabular-num symbol alignment) and Demo 03 Credit Card Type Selector (Visa / Mastercard / Amex marks embedded in the trigger — the PCI-DSS payment surface). Product pricing pages ship Demo 04 Pricing Plan Switcher Dropdown (three-tier Starter / Pro / Enterprise with feature callouts, the SaaS-pricing decoy effect). SaaS product navbars use Demo 05 User Avatar Profile Dropdown Menu (circular avatar trigger + Settings / Sign out, the GitHub / Vercel / Linear pattern) and Demo 07 Account Workspace Switcher Dropdown (team badges, add-workspace footer — the Notion / Linear / Slack B2B convention). Global product headers use Demo 06 Minimalist Language Switcher Dropdown (globe icon + native + English names) and Demo 08 Dark Mode Theme Selector Dropdown (Light / Dark / System with sun / moon / monitor icons). CRM and data-table surfaces use Demo 09 Multi-Select Tag Dropdown With Chips (removable pill chips in the trigger — the Jira / Linear / Airtable filter pattern), Demo 10 Status Filter Badge Dropdown (colored pills — In Progress amber, Completed green — the Linear / GitHub Projects register), Demo 11 Date Range Time Period Picker Dropdown (Last 7 Days / Month to Date / Custom Range — the Google Analytics / Stripe Sigma / Amplitude pattern), and Demo 12 Product Sorting Filter Dropdown (Price Low to High / Newest — the retail sort convention). Rich-content forms use Demo 13 Dropdown With Subtext And Descriptions (two-line options — the Notion / Coda command palette), Demo 14 Font Family Preview Picker (options render in their own family — web-editor pattern), Demo 15 File Type Media Uploader Dropdown (PDF / CSV / PNG icons in the trigger), and Demo 16 Color Swatch Picker Dropdown (real colored circles next to the label). Design-forward SaaS ships Demo 17 Tailwind Style Utility First Select, Demo 18 Animated Slide Fade Dropdown Transition (@starting-style + discrete-property transitions), Demo 19 Floating Label Select Dropdown Field (Material-style label that lifts on focus), and Demo 20 Glassmorphism Dark UI Dropdown (backdrop-filter blur for modern dark-themed dashboards).How do I make a custom select fully keyboard accessible (WCAG 2.1 combobox pattern)?
The WAI-ARIA Authoring Practices Guide combobox pattern is the contract every demo in this gallery ships against. Structural requirements: (1) The trigger is a real — never a — with role="combobox", aria-haspopup="listbox", aria-expanded="true"|"false" reflecting open state, and aria-controls pointing to the panel's id. (2) The panel is role="listbox" with tabindex="-1" so it never captures focus (focus stays on the trigger for screen-reader flow). (3) Each option is role="option" with a unique id and aria-selected reflecting the current pick. (4) The trigger carries aria-activedescendant pointing to the currently highlighted option's id — this is how screen readers announce arrow-key navigation without moving DOM focus. Keyboard behavior: (a) ArrowDown / ArrowUp on the trigger opens the panel and moves the highlight; (b) Enter or Space commits the highlighted option and closes; (c) Escape closes without committing and returns focus to the trigger; (d) Home / End jump to first / last option; (e) typeahead (single-letter key press) jumps to the next option starting with that letter — the pattern native ships. Focus management: on close, focus MUST return to the trigger (not the document body, not the panel that just disappeared) — otherwise screen-reader users lose their place. Every demo in this gallery implements this contract with ~40 lines of vanilla JavaScript per demo — no library required. WCAG 2.1 SC 2.1.1 (Keyboard), 2.1.2 (No Keyboard Trap), 2.4.3 (Focus Order), 2.4.7 (Focus Visible), 4.1.2 (Name, Role, Value) all pass by construction. prefers-reduced-motion: reduce guards every open / close animation.Should I style the native <select> with appearance: base-select, or build a custom listbox?
As of 2026, appearance: base-select (paired with the ::picker(select) pseudo-element) lets you style the native popup with CSS — including fonts, backgrounds, radii, icons, and custom option layout. Chrome 130+ and Edge 130+ ship it; Firefox and Safari do not yet. That means for tier-1 developer traffic, ~65-70% of users get the modern styled native select and ~30-35% (Safari + Firefox) get the browser default. If your design is subtle and the native fallback is acceptable, appearance: base-select behind an @supports block is the cheapest, most accessible, and most future-proof path — you get keyboard / screen-reader / form-submit / mobile-touch behavior for free from the browser. But if your design NEEDS custom option layout (flag chips, avatar rows, multi-line subtext, chips-in-trigger, colored pills, live-search) that the native cannot render even under base-select — or if you need Safari and Firefox parity today — build a custom role="combobox" + role="listbox" widget with the ARIA pattern described above. This gallery's 20 demos all ship the custom-listbox pattern precisely because they render rich per-option content that the native cannot: flag gradients, currency symbols, brand marks, avatars, colored status pills, workspace badges, font-family previews. Each demo's gotchas field flags the specific pieces that would break under a pure appearance: base-select approach so you can choose per-form which path fits.Are these CSS custom selects free to use, and do they work in React, Vue, Svelte, or Next.js?
Yes on both. Every demo is MIT licensed — free for personal and commercial projects, no attribution required. Every widget is plain HTML + CSS + vanilla JavaScript with no build step, no dependencies, no framework lock-in. Drop the HTML into a React component's JSX (React's className instead of class, and remember to move the vanilla JS into a useEffect with a cleanup that removes the event listeners on unmount), a Vue single-file component's template (the vanilla JS moves into onMounted + onBeforeUnmount), a Svelte component (use onMount for the vanilla JS), or an Astro island (client:load or client:visible directive). For React Server Components / Next.js App Router: the custom select is a client component (interactive) — mark the file with "use client" and the vanilla JS moves into useEffect. Every demo's JavaScript uses the browser's native addEventListener and document.querySelector — no imports, no globals. The vanilla implementations use document.addEventListener('click', ...) for outside-click-to-close — in React StrictMode's development double-mount this runs twice; the widget still works but if you want cleanliness use a single useEffect with a proper cleanup return. Every demo's ARIA + keyboard contract is compatible with React 18 concurrent mode, Vue 3 v-model bindings, and Svelte 5 reactive stores — bind the select's committed value from your framework state, not the DOM. Frameworks with strict CSP (script-src 'self' without 'unsafe-inline') will block inline onclick; none of these demos use inline handlers so CSP is satisfied by default.Which CSS custom select ships the best pattern for a Stripe-style e-commerce checkout country picker?
Demo 01 Country Selector Dropdown With Flags is the pattern shipping-checkout flows converged on. The full recipe (as coded in this collection): a trigger displaying the currently-selected country's flag chip + name + a chevron; a role="listbox" panel absolutely positioned below the trigger with max-height: 320px and overflow-y: auto so 195+ countries scroll cleanly; each option is a role="option" with a decorative flag (built from stacked linear-gradient backgrounds — no image assets, no external SVG requests, no Content-Security-Policy issue), the country name, and the ISO-3166 alpha-2 code. Full ARIA + keyboard as documented in the WAI-ARIA Combobox pattern (this is critical for Stripe / Shopify / Airbnb-scale traffic where 15-30% of shipping-address users are on assistive tech, per WebAIM screen-reader survey). Payment-card-industry compliance implications: DO NOT ship the country picker on the same DOM subtree as the credit-card fields if you use Stripe Elements or any tokenizing SDK — the SDK expects to control the card-number iframe and any parent DOM mutation can trigger re-render loops. Instead, put the country picker in a separate above the payment fieldset. GDPR / EU cookie-consent implications: the country picker MUST NOT be used as a proxy for user consent to targeted advertising — the visitor selecting "Germany" does not equal opting-in to cookies for EU personalization. Keep the picker as a shipping-address field only; solicit consent via a separate mechanism (cookie banner, checkbox). Autocomplete attribute: add autocomplete="country-name" on the trigger button element (browsers will not autofill a custom-listbox widget the way they autofill a native , so pre-fill the trigger from the user's saved address book on page load if you have it — read PublicKeyCredential metadata or your own user profile). US-specific: if you also ship a state-of-shipping dropdown (Demo 07's B2B workspace pattern is a good template — swap the workspace icon for a US state flag), watch for California's Consumer Privacy Act — you may need to display a CCPA opt-out link when California is selected.Which CSS custom select pattern works best for CRM and project-management filter dropdowns (Linear, Jira, Notion)?
Demo 09 Multi-Select Tag Dropdown With Chips and Demo 10 Status Filter Badge Dropdown Select are the two patterns Linear, Jira, Airtable, and Notion converged on for filter surfaces. Demo 09 (multi-select tag) ships the pattern for filtering tickets, tasks, or records by multiple tags simultaneously: the trigger displays currently-selected tags as removable chips (each chip has an inline × button that removes only that tag without closing the panel), the panel shows all available tags with checkboxes, and typing filters the panel down to matching tags. Full ARIA: the trigger is role="combobox" with aria-expanded and aria-multiselectable="true", each panel item is role="option" with aria-selected reflecting the checkbox state, and each in-trigger chip is a with aria-label="Remove tag: Marketing" for screen-reader clarity. The chip-in-trigger pattern is what makes this widget genuinely usable at scale — visitors see all selected filters at a glance without opening the panel. Demo 10 (status filter badge) ships the pattern for single-select workflow-status filters: In Progress (amber pill), Completed (green pill), Blocked (red pill), Backlog (slate pill). Each status is a role="option" with aria-selected and a colored background pill matching the semantic status color. Both patterns respect prefers-reduced-motion: reduce and both use keyboard nav (Arrow / Enter / Space / Escape / Home / End). CRM-specific technical notes: (1) When binding to a live-query filter (e.g., updating a URL query string as tags are added or removed), debounce the state-write by ~300ms to avoid history-API thrash; (2) When the tag list is larger than ~50 items, add a search input inside the panel (Demo 13 Dropdown With Subtext ships the panel-search pattern) — the flat-scroll list becomes unusable above 50 options; (3) For real-time collaborative filter surfaces (multiple users applying filters simultaneously — the Linear / Notion multiplayer case), broadcast the filter state as a discrete event, not a snapshot, so the CRDT reconciler can merge conflicts cleanly.How do I ship a language switcher dropdown for a legal, healthcare, or multi-jurisdiction compliance website?
Demo 06 Minimalist Language Switcher Dropdown ships the base pattern — a globe icon trigger + panel of language options with both native and English names (e.g., "Deutsch (German)", "Français (French)", "日本語 (Japanese)"). For legal, healthcare, insurance, or multi-jurisdiction compliance sites the pattern requires additional care beyond the base ARIA contract. Rendering the language name in its OWN script (Deutsch in Latin script, 日本語 in kanji, العربية in Arabic script) is a WCAG 3.1.2 (Language of Parts) requirement — screen readers switch pronunciation engines based on the lang attribute, so each option MUST carry lang="de" / lang="ja" / lang="ar" matching its script. Right-to-left languages (Arabic, Hebrew, Persian, Urdu) additionally need dir="rtl" on the option element AND on the element after commit — otherwise punctuation and numerals render mirrored. Jurisdictional compliance implications: (1) Legal firms operating in California, New York, Texas, and Florida (ABA Model Rule 7.1) must include the languages of the jurisdictions they serve; if you display Spanish for a Los Angeles legal practice you must ensure the Spanish-language content itself is attorney-reviewed, not machine-translated (per ABA Formal Opinion 493 on unauthorized practice of law across languages). (2) Healthcare providers subject to HIPAA and the ACA Section 1557 anti-discrimination rule must offer a language switcher for the 15 most-common non-English languages spoken in their service area — the current CMS list is Spanish, Traditional and Simplified Chinese, Vietnamese, Korean, Tagalog, Russian, Arabic, French, German, Haitian Creole, Portuguese, Polish, Italian, and Japanese. (3) EU sites subject to GDPR must render privacy policy and cookie consent in each supported language — the language switcher must NOT auto-apply based on IP geolocation without explicit user action (Article 21 right to object). (4) Financial services subject to Reg B (Equal Credit Opportunity Act) must disclose in the applicant's chosen language when that language is one of the 5 most-common alternate languages in the market. Autocomplete attribute: autocomplete="language" on the trigger, and persist the selection to a first-party cookie with Secure; SameSite=Lax — do NOT store in localStorage where a subdomain XSS can leak it, and do NOT store in a third-party cookie where the visitor's browser will block it in 2026-forward Chrome tracking-prevention.Related collections

15 CSS 3D Tilt Hover Cards
15 mouse-aware 3D tilt hover cards — e-commerce product spotlight, glassmorphism parallax team card, interactive pricing tier, holographic NFT collectible, pop-out mascot, dark tech grid with border glow, media player album art, blog article preview, cyberpunk neon glow, dashboard KPI widget, minimalist real estate, flip-to-back tilt, mobile app showcase, course learning card, and a Pure CSS touch-friendly tilt. Vanilla JS writes --rx/--ry/--mx/--my; all rendering stays in CSS on the GPU.

24 CSS Animated Cards
24 hand-coded CSS animated card patterns organised by what triggers the motion, not by card style. Scroll and entrance triggers: staggered grid reveals, @starting-style mount-in, scroll-driven scale and fade on animation-timeline: view(), View Transitions API card-to-detail morphs, blur-to-sharp lazy image loading, and FLIP re-layout when a filter changes. State-change triggers: add-to-cart success morph, like and save particle burst, expand and collapse to intrinsic height with calc-size(), swipe-to-dismiss on Pointer Events, and skeleton-to-loaded crossfade. Data-driven triggers: count-up KPI metrics, SVG sparkline draw-on-enter, and progress ring fill on load. Ambient idle loops: breathing glow, floating drift, animated gradient mesh backgrounds, conic rotating borders, auto-cycling testimonial decks, and live status pulses. Plus four hover patterns where the effect is the topic itself: cursor spotlight, holographic foil glare, corner ribbon slide, and horizontal accordion expand. Every card is scoped under a .ac-NN prefix for no-collision pasting, guards prefers-reduced-motion, animates compositor-only properties, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

22 CSS Avatars
22 hand-coded CSS avatars for chat apps, team dashboards, comment threads, account menus, and social profiles. Covers circular and squircle shapes, gradient and conic story rings, hexagon clip-path crops, online status dots, notification count badges, verified checkmarks, stacked facepiles with plus-N overflow, initials fallbacks for users without photos, broken-image recovery, avatar pickers, and a size scale system where the ring, badge, and status dot all scale from a single custom property.