Color Picker
Color pickers let users select, explore, and copy color values. This guide covers production-ready patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap — from the native <input type="color"> to custom swatch grids, HSL sliders, palette generators, and gradient builders.
info
The native <input type="color"> opens the browser's built-in color picker, returns a hex value, and works with zero JavaScript. Use pseudo-elements to style the swatch.
| 1 | <div class="native-demo"> |
| 2 | <div class="nd-field"> |
| 3 | <label for="color-native"> |
| 4 | Pick a color |
| 5 | </label> |
| 6 | <div class="nd-row"> |
| 7 | <input type="color" id="color-native" value="#00FF41" class="color-input"/> |
| 8 | <span class="nd-value" id="nd-val"> |
| 9 | #00FF41 |
| 10 | </span> |
| 11 | </div> |
| 12 | </div> |
| 13 | </div> |
| 1 | .native-demo { |
| 2 | display:flex; |
| 3 | flex-direction:column; |
| 4 | gap:16px; |
| 5 | padding:32px; |
| 6 | align-items:center; |
| 7 | font-family:system-ui, |
| 8 | sans-serif |
| 9 | } |
| 10 | .nd-field { |
| 11 | display:flex; |
| 12 | flex-direction:column; |
| 13 | gap:6px; |
| 14 | max-width:280px; |
| 15 | width:100% |
| 16 | } |
| 17 | .nd-field label { |
| 18 | font-size:12px; |
| 19 | font-weight:600; |
| 20 | color:#E0E0E0 |
| 21 | } |
| 22 | .nd-row { |
| 23 | display:flex; |
| 24 | align-items:center; |
| 25 | gap:12px |
| 26 | } |
| 27 | .color-input { |
| 28 | width:48px; |
| 29 | height:36px; |
| 30 | border:2px solid #2A2A3E; |
| 31 | border-radius:8px; |
| 32 | cursor:pointer; |
| 33 | background:transparent; |
| 34 | padding:2px |
| 35 | } |
| 36 | .color-input::-webkit-color-swatch-wrapper { |
| 37 | padding:0 |
| 38 | } |
| 39 | .color-input::-webkit-color-swatch { |
| 40 | border:none; |
| 41 | border-radius:4px |
| 42 | } |
| 43 | .color-input::-moz-color-swatch { |
| 44 | border:none; |
| 45 | border-radius:4px |
| 46 | } |
| 47 | .nd-value { |
| 48 | font-size:13px; |
| 49 | color:#00FF41; |
| 50 | font-weight:600; |
| 51 | font-family:monospace; |
| 52 | font-variant-numeric:tabular-nums |
| 53 | } |
| 1 | const input=document.getElementById('color-native');const val=document.getElementById('nd-val');input.addEventListener('input',()=>val.textContent=input.value.toUpperCase()) |
| 1 | <div class="flex flex-col items-center p-8 bg-[#0A0A0A] font-sans"> |
| 2 | <div class="flex flex-col gap-1.5 w-full max-w-[280px]"> |
| 3 | <label for="tw-native" class="text-xs font-semibold text-[#E0E0E0]"> |
| 4 | Pick a color |
| 5 | </label> |
| 6 | <div class="flex items-center gap-3"> |
| 7 | <input type="color" id="tw-native" value="#00FF41" class="w-12 h-9 p-0.5 bg-transparent border-2 border-[#2A2A3E] rounded-lg cursor-pointer"/> |
| 8 | <span id="tw-native-val" class="text-[13px] font-semibold text-[#00FF41] font-mono tabular-nums"> |
| 9 | #00FF41 |
| 10 | </span> |
| 11 | </div> |
| 12 | </div> |
| 13 | </div> |
| 1 | <div class="d-flex justify-content-center p-4"> |
| 2 | <div class="d-flex flex-column gap-2" style="max-width:280px;width:100%"> |
| 3 | <label for="bs-native" class="form-label text-[#E0E0E0] small fw-semibold mb-0"> |
| 4 | Pick a color |
| 5 | </label> |
| 6 | <div class="d-flex align-items-center gap-3"> |
| 7 | <input type="color" id="bs-native" value="#00FF41" class="form-control form-control-color p-1" style="width:48px;height:36px;background:transparent;border-color:#2A2A3E;border-radius:8px"/> |
| 8 | <span id="bs-native-val" class="font-monospace fw-semibold" style="font-size:13px;color:#00FF41"> |
| 9 | #00FF41 |
| 10 | </span> |
| 11 | </div> |
| 12 | </div> |
| 13 | </div> |
A preset grid of color swatches for quick selection. The active choice is highlighted with a ring. Ideal for theme pickers and curated palettes.
| 1 | <div class="swatch-demo"> |
| 2 | <div class="sd-header"> |
| 3 | <span class="sd-title"> |
| 4 | Theme Color |
| 5 | </span> |
| 6 | <span class="sd-hex" id="sd-hex"> |
| 7 | #00FF41 |
| 8 | </span> |
| 9 | </div> |
| 10 | <div class="swatch-grid" id="swatch-grid"> |
| 11 | <button class="swatch active" data-color="#00FF41" style="background:#00FF41" aria-label="Green"> |
| 12 | </button> |
| 13 | <button class="swatch" data-color="#3B82F6" style="background:#3B82F6" aria-label="Blue"> |
| 14 | </button> |
| 15 | <button class="swatch" data-color="#EF4444" style="background:#EF4444" aria-label="Red"> |
| 16 | </button> |
| 17 | <button class="swatch" data-color="#F59E0B" style="background:#F59E0B" aria-label="Amber"> |
| 18 | </button> |
| 19 | <button class="swatch" data-color="#8B5CF6" style="background:#8B5CF6" aria-label="Purple"> |
| 20 | </button> |
| 21 | <button class="swatch" data-color="#EC4899" style="background:#EC4899" aria-label="Pink"> |
| 22 | </button> |
| 23 | <button class="swatch" data-color="#14B8A6" style="background:#14B8A6" aria-label="Teal"> |
| 24 | </button> |
| 25 | <button class="swatch" data-color="#F97316" style="background:#F97316" aria-label="Orange"> |
| 26 | </button> |
| 27 | <button class="swatch" data-color="#E0E0E0" style="background:#E0E0E0" aria-label="Light"> |
| 28 | </button> |
| 29 | <button class="swatch" data-color="#808080" style="background:#808080" aria-label="Gray"> |
| 30 | </button> |
| 31 | <button class="swatch" data-color="#444444" style="background:#444444" aria-label="Dark"> |
| 32 | </button> |
| 33 | <button class="swatch" data-color="#000000" style="background:#000000;border:1px solid #333" aria-label="Black"> |
| 34 | </button> |
| 35 | </div> |
| 36 | </div> |
| 1 | .swatch-demo { |
| 2 | max-width:340px; |
| 3 | margin:16px auto; |
| 4 | padding:16px 20px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:10px; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .sd-header { |
| 12 | display:flex; |
| 13 | justify-content:space-between; |
| 14 | align-items:center; |
| 15 | margin-bottom:14px |
| 16 | } |
| 17 | .sd-title { |
| 18 | font-size:12px; |
| 19 | font-weight:600; |
| 20 | color:#E0E0E0 |
| 21 | } |
| 22 | .sd-hex { |
| 23 | font-size:12px; |
| 24 | color:#00FF41; |
| 25 | font-weight:600; |
| 26 | font-family:monospace |
| 27 | } |
| 28 | .swatch-grid { |
| 29 | display:grid; |
| 30 | grid-template-columns:repeat(6, |
| 31 | 1fr); |
| 32 | gap:8px |
| 33 | } |
| 34 | .swatch { |
| 35 | width:100%; |
| 36 | aspect-ratio:1; |
| 37 | border-radius:8px; |
| 38 | border:2px solid transparent; |
| 39 | cursor:pointer; |
| 40 | transition:all .2s; |
| 41 | padding:0 |
| 42 | } |
| 43 | .swatch:hover { |
| 44 | transform:scale(1.1) |
| 45 | } |
| 46 | .swatch.active { |
| 47 | border-color:#E0E0E0; |
| 48 | box-shadow:0 0 12px rgba(255, |
| 49 | 255, |
| 50 | 255, |
| 51 | .15); |
| 52 | transform:scale(1.05) |
| 53 | } |
| 1 | const hex=document.getElementById('sd-hex');document.getElementById('swatch-grid').addEventListener('click',e=>{const s=e.target.closest('.swatch');if(!s)return;document.querySelectorAll('.swatch').forEach(x=>x.classList.remove('active'));s.classList.add('active');hex.textContent=s.dataset.color}) |
| 1 | <div class="max-w-[340px] mx-auto p-4 bg-[#111] border border-[#222] rounded-xl font-sans"> |
| 2 | <div class="flex justify-between items-center mb-3.5"> |
| 3 | <span class="text-xs font-semibold text-[#E0E0E0]"> |
| 4 | Theme Color |
| 5 | </span> |
| 6 | <span id="tw-sd-hex" class="text-xs font-semibold text-[#00FF41] font-mono"> |
| 7 | #00FF41 |
| 8 | </span> |
| 9 | </div> |
| 10 | <div id="tw-swatch-grid" class="grid grid-cols-6 gap-2"> |
| 11 | <button class="w-full aspect-square rounded-lg border-2 border-[#E0E0E0] shadow-[0_0_12px_rgba(255,255,255,0.15)] scale-105 transition-transform" data-color="#00FF41" style="background:#00FF41" aria-label="Green"> |
| 12 | </button> |
| 13 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#3B82F6" style="background:#3B82F6" aria-label="Blue"> |
| 14 | </button> |
| 15 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#EF4444" style="background:#EF4444" aria-label="Red"> |
| 16 | </button> |
| 17 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#F59E0B" style="background:#F59E0B" aria-label="Amber"> |
| 18 | </button> |
| 19 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#8B5CF6" style="background:#8B5CF6" aria-label="Purple"> |
| 20 | </button> |
| 21 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#EC4899" style="background:#EC4899" aria-label="Pink"> |
| 22 | </button> |
| 23 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#14B8A6" style="background:#14B8A6" aria-label="Teal"> |
| 24 | </button> |
| 25 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#F97316" style="background:#F97316" aria-label="Orange"> |
| 26 | </button> |
| 27 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#E0E0E0" style="background:#E0E0E0" aria-label="Light"> |
| 28 | </button> |
| 29 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#808080" style="background:#808080" aria-label="Gray"> |
| 30 | </button> |
| 31 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#444444" style="background:#444444" aria-label="Dark"> |
| 32 | </button> |
| 33 | <button class="w-full aspect-square rounded-lg border-2 border-transparent hover:scale-110 transition-transform" data-color="#000000" style="background:#000000;border:1px solid #333" aria-label="Black"> |
| 34 | </button> |
| 35 | </div> |
| 36 | </div> |
| 1 | <div class="mx-auto p-4 rounded" style="max-width:340px;background:#111;border:1px solid #222"> |
| 2 | <div class="d-flex justify-content-between align-items-center mb-3"> |
| 3 | <span class="small fw-semibold" style="color:#E0E0E0"> |
| 4 | Theme Color |
| 5 | </span> |
| 6 | <span id="bs-sd-hex" class="font-monospace fw-semibold" style="font-size:12px;color:#00FF41"> |
| 7 | #00FF41 |
| 8 | </span> |
| 9 | </div> |
| 10 | <div id="bs-swatch-grid" class="d-grid gap-2" style="grid-template-columns:repeat(6,1fr)"> |
| 11 | <button class="btn p-0 rounded active-swatch" data-color="#00FF41" style="aspect-ratio:1;background:#00FF41;border:2px solid #E0E0E0;box-shadow:0 0 12px rgba(255,255,255,.15)" aria-label="Green"> |
| 12 | </button> |
| 13 | <button class="btn p-0 rounded" data-color="#3B82F6" style="aspect-ratio:1;background:#3B82F6;border:2px solid transparent" aria-label="Blue"> |
| 14 | </button> |
| 15 | <button class="btn p-0 rounded" data-color="#EF4444" style="aspect-ratio:1;background:#EF4444;border:2px solid transparent" aria-label="Red"> |
| 16 | </button> |
| 17 | <button class="btn p-0 rounded" data-color="#F59E0B" style="aspect-ratio:1;background:#F59E0B;border:2px solid transparent" aria-label="Amber"> |
| 18 | </button> |
| 19 | <button class="btn p-0 rounded" data-color="#8B5CF6" style="aspect-ratio:1;background:#8B5CF6;border:2px solid transparent" aria-label="Purple"> |
| 20 | </button> |
| 21 | <button class="btn p-0 rounded" data-color="#EC4899" style="aspect-ratio:1;background:#EC4899;border:2px solid transparent" aria-label="Pink"> |
| 22 | </button> |
| 23 | <button class="btn p-0 rounded" data-color="#14B8A6" style="aspect-ratio:1;background:#14B8A6;border:2px solid transparent" aria-label="Teal"> |
| 24 | </button> |
| 25 | <button class="btn p-0 rounded" data-color="#F97316" style="aspect-ratio:1;background:#F97316;border:2px solid transparent" aria-label="Orange"> |
| 26 | </button> |
| 27 | <button class="btn p-0 rounded" data-color="#E0E0E0" style="aspect-ratio:1;background:#E0E0E0;border:2px solid transparent" aria-label="Light"> |
| 28 | </button> |
| 29 | <button class="btn p-0 rounded" data-color="#808080" style="aspect-ratio:1;background:#808080;border:2px solid transparent" aria-label="Gray"> |
| 30 | </button> |
| 31 | <button class="btn p-0 rounded" data-color="#444444" style="aspect-ratio:1;background:#444444;border:2px solid transparent" aria-label="Dark"> |
| 32 | </button> |
| 33 | <button class="btn p-0 rounded" data-color="#000000" style="aspect-ratio:1;background:#000000;border:1px solid #333" aria-label="Black"> |
| 34 | </button> |
| 35 | </div> |
| 36 | </div> |
Compact, default, and large swatch sizes adapt the same color grid to different contexts — form sidebars, toolbars, and full-width theme panels.
| 1 | <div class="size-demo"> |
| 2 | <div class="size-row"> |
| 3 | <span class="size-label"> |
| 4 | Small |
| 5 | </span> |
| 6 | <div class="size-grid small"> |
| 7 | <button class="swatch" style="background:#00FF41" aria-label="Green"> |
| 8 | </button> |
| 9 | <button class="swatch" style="background:#3B82F6" aria-label="Blue"> |
| 10 | </button> |
| 11 | <button class="swatch" style="background:#EF4444" aria-label="Red"> |
| 12 | </button> |
| 13 | <button class="swatch" style="background:#F59E0B" aria-label="Amber"> |
| 14 | </button> |
| 15 | </div> |
| 16 | </div> |
| 17 | <div class="size-row"> |
| 18 | <span class="size-label"> |
| 19 | Default |
| 20 | </span> |
| 21 | <div class="size-grid"> |
| 22 | <button class="swatch" style="background:#00FF41" aria-label="Green"> |
| 23 | </button> |
| 24 | <button class="swatch" style="background:#3B82F6" aria-label="Blue"> |
| 25 | </button> |
| 26 | <button class="swatch" style="background:#EF4444" aria-label="Red"> |
| 27 | </button> |
| 28 | <button class="swatch" style="background:#F59E0B" aria-label="Amber"> |
| 29 | </button> |
| 30 | </div> |
| 31 | </div> |
| 32 | <div class="size-row"> |
| 33 | <span class="size-label"> |
| 34 | Large |
| 35 | </span> |
| 36 | <div class="size-grid large"> |
| 37 | <button class="swatch" style="background:#00FF41" aria-label="Green"> |
| 38 | </button> |
| 39 | <button class="swatch" style="background:#3B82F6" aria-label="Blue"> |
| 40 | </button> |
| 41 | <button class="swatch" style="background:#EF4444" aria-label="Red"> |
| 42 | </button> |
| 43 | <button class="swatch" style="background:#F59E0B" aria-label="Amber"> |
| 44 | </button> |
| 45 | </div> |
| 46 | </div> |
| 47 | </div> |
| 1 | .size-demo { |
| 2 | display:flex; |
| 3 | flex-direction:column; |
| 4 | gap:18px; |
| 5 | padding:24px 32px; |
| 6 | font-family:system-ui, |
| 7 | sans-serif |
| 8 | } |
| 9 | .size-row { |
| 10 | display:flex; |
| 11 | align-items:center; |
| 12 | gap:16px |
| 13 | } |
| 14 | .size-label { |
| 15 | width:56px; |
| 16 | font-size:11px; |
| 17 | color:#808080; |
| 18 | font-weight:500; |
| 19 | text-transform:uppercase; |
| 20 | letter-spacing:.5px |
| 21 | } |
| 22 | .size-grid { |
| 23 | display:flex; |
| 24 | gap:10px |
| 25 | } |
| 26 | .size-grid.small { |
| 27 | gap:6px |
| 28 | } |
| 29 | .size-grid.small .swatch { |
| 30 | width:20px; |
| 31 | height:20px; |
| 32 | border-radius:4px |
| 33 | } |
| 34 | .size-grid.large { |
| 35 | gap:14px |
| 36 | } |
| 37 | .size-grid.large .swatch { |
| 38 | width:40px; |
| 39 | height:40px; |
| 40 | border-radius:10px |
| 41 | } |
| 42 | .swatch { |
| 43 | width:28px; |
| 44 | height:28px; |
| 45 | border-radius:8px; |
| 46 | border:2px solid transparent; |
| 47 | cursor:pointer; |
| 48 | transition:transform .2s; |
| 49 | padding:0 |
| 50 | } |
| 51 | .swatch:hover { |
| 52 | transform:scale(1.1) |
| 53 | } |
| 54 | .swatch.active { |
| 55 | border-color:#E0E0E0; |
| 56 | box-shadow:0 0 12px rgba(255, |
| 57 | 255, |
| 58 | 255, |
| 59 | .15) |
| 60 | } |
| 1 | document.querySelectorAll('.size-demo').forEach(d=>{d.querySelectorAll('.swatch').forEach(s=>{s.addEventListener('click',()=>{s.closest('.size-grid').querySelectorAll('.swatch').forEach(x=>x.classList.remove('active'));s.classList.add('active')})})}) |
| 1 | <div class="flex flex-col gap-4 p-6 bg-[#0A0A0A] font-sans"> |
| 2 | <div class="flex items-center gap-4"> |
| 3 | <span class="w-14 text-[11px] font-medium text-[#808080] uppercase tracking-wider"> |
| 4 | Small |
| 5 | </span> |
| 6 | <div class="flex gap-1.5"> |
| 7 | <button class="w-5 h-5 rounded border-2 border-transparent hover:scale-110 transition-transform" style="background:#00FF41" aria-label="Green"> |
| 8 | </button> |
| 9 | <button class="w-5 h-5 rounded border-2 border-transparent hover:scale-110 transition-transform" style="background:#3B82F6" aria-label="Blue"> |
| 10 | </button> |
| 11 | <button class="w-5 h-5 rounded border-2 border-transparent hover:scale-110 transition-transform" style="background:#EF4444" aria-label="Red"> |
| 12 | </button> |
| 13 | <button class="w-5 h-5 rounded border-2 border-transparent hover:scale-110 transition-transform" style="background:#F59E0B" aria-label="Amber"> |
| 14 | </button> |
| 15 | </div> |
| 16 | </div> |
| 17 | <div class="flex items-center gap-4"> |
| 18 | <span class="w-14 text-[11px] font-medium text-[#808080] uppercase tracking-wider"> |
| 19 | Default |
| 20 | </span> |
| 21 | <div class="flex gap-2.5"> |
| 22 | <button class="w-7 h-7 rounded-lg border-2 border-transparent hover:scale-110 transition-transform" style="background:#00FF41" aria-label="Green"> |
| 23 | </button> |
| 24 | <button class="w-7 h-7 rounded-lg border-2 border-transparent hover:scale-110 transition-transform" style="background:#3B82F6" aria-label="Blue"> |
| 25 | </button> |
| 26 | <button class="w-7 h-7 rounded-lg border-2 border-transparent hover:scale-110 transition-transform" style="background:#EF4444" aria-label="Red"> |
| 27 | </button> |
| 28 | <button class="w-7 h-7 rounded-lg border-2 border-transparent hover:scale-110 transition-transform" style="background:#F59E0B" aria-label="Amber"> |
| 29 | </button> |
| 30 | </div> |
| 31 | </div> |
| 32 | <div class="flex items-center gap-4"> |
| 33 | <span class="w-14 text-[11px] font-medium text-[#808080] uppercase tracking-wider"> |
| 34 | Large |
| 35 | </span> |
| 36 | <div class="flex gap-3.5"> |
| 37 | <button class="w-10 h-10 rounded-[10px] border-2 border-transparent hover:scale-110 transition-transform" style="background:#00FF41" aria-label="Green"> |
| 38 | </button> |
| 39 | <button class="w-10 h-10 rounded-[10px] border-2 border-transparent hover:scale-110 transition-transform" style="background:#3B82F6" aria-label="Blue"> |
| 40 | </button> |
| 41 | <button class="w-10 h-10 rounded-[10px] border-2 border-transparent hover:scale-110 transition-transform" style="background:#EF4444" aria-label="Red"> |
| 42 | </button> |
| 43 | <button class="w-10 h-10 rounded-[10px] border-2 border-transparent hover:scale-110 transition-transform" style="background:#F59E0B" aria-label="Amber"> |
| 44 | </button> |
| 45 | </div> |
| 46 | </div> |
| 47 | </div> |
| 1 | <div class="d-flex flex-column gap-4 p-4"> |
| 2 | <div class="d-flex align-items-center gap-4"> |
| 3 | <span class="text-uppercase" style="width:56px;font-size:11px;color:#808080"> |
| 4 | Small |
| 5 | </span> |
| 6 | <div class="d-flex gap-1"> |
| 7 | <button class="btn p-0" style="width:20px;height:20px;border-radius:4px;background:#00FF41;border:2px solid transparent" aria-label="Green"> |
| 8 | </button> |
| 9 | <button class="btn p-0" style="width:20px;height:20px;border-radius:4px;background:#3B82F6;border:2px solid transparent" aria-label="Blue"> |
| 10 | </button> |
| 11 | <button class="btn p-0" style="width:20px;height:20px;border-radius:4px;background:#EF4444;border:2px solid transparent" aria-label="Red"> |
| 12 | </button> |
| 13 | <button class="btn p-0" style="width:20px;height:20px;border-radius:4px;background:#F59E0B;border:2px solid transparent" aria-label="Amber"> |
| 14 | </button> |
| 15 | </div> |
| 16 | </div> |
| 17 | <div class="d-flex align-items-center gap-4"> |
| 18 | <span class="text-uppercase" style="width:56px;font-size:11px;color:#808080"> |
| 19 | Default |
| 20 | </span> |
| 21 | <div class="d-flex gap-2"> |
| 22 | <button class="btn p-0" style="width:28px;height:28px;border-radius:8px;background:#00FF41;border:2px solid transparent" aria-label="Green"> |
| 23 | </button> |
| 24 | <button class="btn p-0" style="width:28px;height:28px;border-radius:8px;background:#3B82F6;border:2px solid transparent" aria-label="Blue"> |
| 25 | </button> |
| 26 | <button class="btn p-0" style="width:28px;height:28px;border-radius:8px;background:#EF4444;border:2px solid transparent" aria-label="Red"> |
| 27 | </button> |
| 28 | <button class="btn p-0" style="width:28px;height:28px;border-radius:8px;background:#F59E0B;border:2px solid transparent" aria-label="Amber"> |
| 29 | </button> |
| 30 | </div> |
| 31 | </div> |
| 32 | <div class="d-flex align-items-center gap-4"> |
| 33 | <span class="text-uppercase" style="width:56px;font-size:11px;color:#808080"> |
| 34 | Large |
| 35 | </span> |
| 36 | <div class="d-flex gap-3"> |
| 37 | <button class="btn p-0" style="width:40px;height:40px;border-radius:10px;background:#00FF41;border:2px solid transparent" aria-label="Green"> |
| 38 | </button> |
| 39 | <button class="btn p-0" style="width:40px;height:40px;border-radius:10px;background:#3B82F6;border:2px solid transparent" aria-label="Blue"> |
| 40 | </button> |
| 41 | <button class="btn p-0" style="width:40px;height:40px;border-radius:10px;background:#EF4444;border:2px solid transparent" aria-label="Red"> |
| 42 | </button> |
| 43 | <button class="btn p-0" style="width:40px;height:40px;border-radius:10px;background:#F59E0B;border:2px solid transparent" aria-label="Amber"> |
| 44 | </button> |
| 45 | </div> |
| 46 | </div> |
| 47 | </div> |
Manual color entry with hex and RGB fields. Changes in any field update all others and the live preview. Supports #RRGGBB and shorthand #RGB formats.
| 1 | <div class="hex-rgb-demo"> |
| 2 | <div class="hr-preview" id="hr-preview" style="background:#00FF41"> |
| 3 | </div> |
| 4 | <div class="hr-fields"> |
| 5 | <div class="hr-group"> |
| 6 | <label> |
| 7 | HEX |
| 8 | </label> |
| 9 | <input type="text" class="hr-input hex" id="hr-hex" value="#00FF41" maxlength="7"/> |
| 10 | </div> |
| 11 | <div class="hr-group"> |
| 12 | <label> |
| 13 | R |
| 14 | </label> |
| 15 | <input type="number" class="hr-input rgb" id="hr-r" min="0" max="255" value="0"/> |
| 16 | </div> |
| 17 | <div class="hr-group"> |
| 18 | <label> |
| 19 | G |
| 20 | </label> |
| 21 | <input type="number" class="hr-input rgb" id="hr-g" min="0" max="255" value="255"/> |
| 22 | </div> |
| 23 | <div class="hr-group"> |
| 24 | <label> |
| 25 | B |
| 26 | </label> |
| 27 | <input type="number" class="hr-input rgb" id="hr-b" min="0" max="255" value="65"/> |
| 28 | </div> |
| 29 | </div> |
| 30 | <div class="hr-output"> |
| 31 | <span class="hr-label"> |
| 32 | CSS: |
| 33 | </span> |
| 34 | <code id="hr-css"> |
| 35 | rgb(0, 255, 65) |
| 36 | </code> |
| 37 | </div> |
| 38 | </div> |
| 1 | .hex-rgb-demo { |
| 2 | max-width:360px; |
| 3 | margin:16px auto; |
| 4 | padding:16px 20px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:10px; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .hr-preview { |
| 12 | width:100%; |
| 13 | height:48px; |
| 14 | border-radius:8px; |
| 15 | margin-bottom:14px; |
| 16 | border:1px solid rgba(255, |
| 17 | 255, |
| 18 | 255, |
| 19 | .05); |
| 20 | transition:background .15s ease |
| 21 | } |
| 22 | .hr-fields { |
| 23 | display:flex; |
| 24 | gap:8px; |
| 25 | margin-bottom:12px |
| 26 | } |
| 27 | .hr-group { |
| 28 | flex:1; |
| 29 | display:flex; |
| 30 | flex-direction:column; |
| 31 | gap:4px |
| 32 | } |
| 33 | .hr-group:first-child { |
| 34 | flex:2 |
| 35 | } |
| 36 | .hr-group label { |
| 37 | font-size:9px; |
| 38 | color:#666; |
| 39 | text-transform:uppercase; |
| 40 | letter-spacing:.5px |
| 41 | } |
| 42 | .hr-input { |
| 43 | padding:8px; |
| 44 | border-radius:6px; |
| 45 | border:1px solid #2A2A3E; |
| 46 | background:#0A0A0A; |
| 47 | color:#E0E0E0; |
| 48 | font-size:12px; |
| 49 | font-family:monospace; |
| 50 | outline:none; |
| 51 | text-align:center |
| 52 | } |
| 53 | .hr-input:focus { |
| 54 | border-color:#00FF41 |
| 55 | } |
| 56 | .hr-input.hex { |
| 57 | text-align:left; |
| 58 | padding-left:10px |
| 59 | } |
| 60 | .hr-output { |
| 61 | display:flex; |
| 62 | align-items:center; |
| 63 | gap:8px; |
| 64 | padding:8px 10px; |
| 65 | background:#0A0A0A; |
| 66 | border-radius:6px; |
| 67 | border:1px solid #222 |
| 68 | } |
| 69 | .hr-label { |
| 70 | font-size:10px; |
| 71 | color:#666 |
| 72 | } |
| 73 | .hr-output code { |
| 74 | font-size:11px; |
| 75 | color:#00FF41; |
| 76 | font-family:monospace |
| 77 | } |
| 1 | const hexIn=document.getElementById('hr-hex');const rIn=document.getElementById('hr-r');const gIn=document.getElementById('hr-g');const bIn=document.getElementById('hr-b');const preview=document.getElementById('hr-preview');const cssOut=document.getElementById('hr-css');function hexToRgb(h){h=h.replace('#','');if(h.length===3)h=h[0]+h[0]+h[1]+h[1]+h[2]+h[2];return{r:parseInt(h.substring(0,2),16),g:parseInt(h.substring(2,4),16),b:parseInt(h.substring(4,6),16)}}function rgbToHex(r,g,b){return '#'+[r,g,b].map(x=>Math.max(0,Math.min(255,x)).toString(16).padStart(2,'0')).join('')}function update(r,g,b){preview.style.background='rgb('+r+','+g+','+b+')';cssOut.textContent='rgb('+r+', '+g+', '+b+')';hexIn.value=rgbToHex(r,g,b).toUpperCase();rIn.value=r;gIn.value=g;bIn.value=b}hexIn.addEventListener('input',()=>{try{const c=hexToRgb(hexIn.value);update(c.r,c.g,c.b)}catch(e){}});[rIn,gIn,bIn].forEach(inp=>inp.addEventListener('input',()=>update(parseInt(rIn.value)||0,parseInt(gIn.value)||0,parseInt(bIn.value)||0))) |
| 1 | <div class="max-w-[360px] mx-auto p-4 bg-[#111] border border-[#222] rounded-xl font-sans"> |
| 2 | <div id="tw-hr-preview" class="w-full h-12 rounded-lg mb-3.5 border border-white/5 transition-colors" style="background:#00FF41"> |
| 3 | </div> |
| 4 | <div class="flex gap-2 mb-3"> |
| 5 | <div class="flex-[2] flex flex-col gap-1"> |
| 6 | <label class="text-[9px] text-[#666] uppercase tracking-wider"> |
| 7 | HEX |
| 8 | </label> |
| 9 | <input type="text" id="tw-hr-hex" value="#00FF41" maxlength="7" class="px-2.5 py-2 rounded-md border border-[#2A2A3E] bg-[#0A0A0A] text-[#E0E0E0] text-xs font-mono outline-none focus:border-[#00FF41]"/> |
| 10 | </div> |
| 11 | <div class="flex-1 flex flex-col gap-1"> |
| 12 | <label class="text-[9px] text-[#666] uppercase tracking-wider"> |
| 13 | R |
| 14 | </label> |
| 15 | <input type="number" id="tw-hr-r" min="0" max="255" value="0" class="py-2 rounded-md border border-[#2A2A3E] bg-[#0A0A0A] text-[#E0E0E0] text-xs font-mono text-center outline-none focus:border-[#00FF41]"/> |
| 16 | </div> |
| 17 | <div class="flex-1 flex flex-col gap-1"> |
| 18 | <label class="text-[9px] text-[#666] uppercase tracking-wider"> |
| 19 | G |
| 20 | </label> |
| 21 | <input type="number" id="tw-hr-g" min="0" max="255" value="255" class="py-2 rounded-md border border-[#2A2A3E] bg-[#0A0A0A] text-[#E0E0E0] text-xs font-mono text-center outline-none focus:border-[#00FF41]"/> |
| 22 | </div> |
| 23 | <div class="flex-1 flex flex-col gap-1"> |
| 24 | <label class="text-[9px] text-[#666] uppercase tracking-wider"> |
| 25 | B |
| 26 | </label> |
| 27 | <input type="number" id="tw-hr-b" min="0" max="255" value="65" class="py-2 rounded-md border border-[#2A2A3E] bg-[#0A0A0A] text-[#E0E0E0] text-xs font-mono text-center outline-none focus:border-[#00FF41]"/> |
| 28 | </div> |
| 29 | </div> |
| 30 | <div class="flex items-center gap-2 px-2.5 py-2 bg-[#0A0A0A] rounded-md border border-[#222]"> |
| 31 | <span class="text-[10px] text-[#666]"> |
| 32 | CSS: |
| 33 | </span> |
| 34 | <code id="tw-hr-css" class="text-xs text-[#00FF41] font-mono"> |
| 35 | rgb(0, 255, 65) |
| 36 | </code> |
| 37 | </div> |
| 38 | </div> |
| 1 | <div class="mx-auto p-4 rounded" style="max-width:360px;background:#111;border:1px solid #222"> |
| 2 | <div id="bs-hr-preview" class="w-100 rounded" style="height:48px;background:#00FF41;margin-bottom:14px;border:1px solid rgba(255,255,255,.05)"> |
| 3 | </div> |
| 4 | <div class="row g-2 mb-3"> |
| 5 | <div class="col-4"> |
| 6 | <label class="form-label mb-1" style="font-size:9px;color:#666;text-transform:uppercase"> |
| 7 | HEX |
| 8 | </label> |
| 9 | <input type="text" id="bs-hr-hex" value="#00FF41" maxlength="7" class="form-control form-control-sm font-monospace" style="background:#0A0A0A;color:#E0E0E0;border-color:#2A2A3E"/> |
| 10 | </div> |
| 11 | <div class="col-2"> |
| 12 | <label class="form-label mb-1" style="font-size:9px;color:#666;text-transform:uppercase"> |
| 13 | R |
| 14 | </label> |
| 15 | <input type="number" id="bs-hr-r" min="0" max="255" value="0" class="form-control form-control-sm font-monospace text-center" style="background:#0A0A0A;color:#E0E0E0;border-color:#2A2A3E"/> |
| 16 | </div> |
| 17 | <div class="col-2"> |
| 18 | <label class="form-label mb-1" style="font-size:9px;color:#666;text-transform:uppercase"> |
| 19 | G |
| 20 | </label> |
| 21 | <input type="number" id="bs-hr-g" min="0" max="255" value="255" class="form-control form-control-sm font-monospace text-center" style="background:#0A0A0A;color:#E0E0E0;border-color:#2A2A3E"/> |
| 22 | </div> |
| 23 | <div class="col-2"> |
| 24 | <label class="form-label mb-1" style="font-size:9px;color:#666;text-transform:uppercase"> |
| 25 | B |
| 26 | </label> |
| 27 | <input type="number" id="bs-hr-b" min="0" max="255" value="65" class="form-control form-control-sm font-monospace text-center" style="background:#0A0A0A;color:#E0E0E0;border-color:#2A2A3E"/> |
| 28 | </div> |
| 29 | </div> |
| 30 | <div class="d-flex align-items-center gap-2 px-2 py-2 rounded" style="background:#0A0A0A;border:1px solid #222"> |
| 31 | <span style="font-size:10px;color:#666"> |
| 32 | CSS: |
| 33 | </span> |
| 34 | <code id="bs-hr-css" class="font-monospace" style="font-size:11px;color:#00FF41"> |
| 35 | rgb(0, 255, 65) |
| 36 | </code> |
| 37 | </div> |
| 38 | </div> |
An HSL picker with hue, saturation, and lightness sliders. Each track gradient updates dynamically as the hue changes.
| 1 | <div class="hsl-demo"> |
| 2 | <div class="hsl-preview" id="hsl-preview" style="background:hsl(140,100%,50%)"> |
| 3 | </div> |
| 4 | <div class="hsl-fields"> |
| 5 | <div class="hsl-group"> |
| 6 | <div class="hsl-header"> |
| 7 | <label> |
| 8 | Hue |
| 9 | </label> |
| 10 | <span class="hsl-val" id="hsl-h-val"> |
| 11 | 140° |
| 12 | </span> |
| 13 | </div> |
| 14 | <input type="range" class="hsl-slider hue" id="hsl-h" min="0" max="360" value="140"/> |
| 15 | </div> |
| 16 | <div class="hsl-group"> |
| 17 | <div class="hsl-header"> |
| 18 | <label> |
| 19 | Saturation |
| 20 | </label> |
| 21 | <span class="hsl-val" id="hsl-s-val"> |
| 22 | 100% |
| 23 | </span> |
| 24 | </div> |
| 25 | <input type="range" class="hsl-slider sat" id="hsl-s" min="0" max="100" value="100"/> |
| 26 | </div> |
| 27 | <div class="hsl-group"> |
| 28 | <div class="hsl-header"> |
| 29 | <label> |
| 30 | Lightness |
| 31 | </label> |
| 32 | <span class="hsl-val" id="hsl-l-val"> |
| 33 | 50% |
| 34 | </span> |
| 35 | </div> |
| 36 | <input type="range" class="hsl-slider light" id="hsl-l" min="0" max="100" value="50"/> |
| 37 | </div> |
| 38 | </div> |
| 39 | <div class="hsl-output"> |
| 40 | <code id="hsl-css"> |
| 41 | hsl(140, 100%, 50%) |
| 42 | </code> |
| 43 | <button class="hsl-copy" id="hsl-copy"> |
| 44 | Copy |
| 45 | </button> |
| 46 | </div> |
| 47 | </div> |
| 1 | .hsl-demo { |
| 2 | max-width:340px; |
| 3 | margin:16px auto; |
| 4 | padding:16px 20px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:10px; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .hsl-preview { |
| 12 | width:100%; |
| 13 | height:48px; |
| 14 | border-radius:8px; |
| 15 | margin-bottom:14px; |
| 16 | border:1px solid rgba(255, |
| 17 | 255, |
| 18 | 255, |
| 19 | .05); |
| 20 | transition:background .1s ease |
| 21 | } |
| 22 | .hsl-fields { |
| 23 | display:flex; |
| 24 | flex-direction:column; |
| 25 | gap:14px; |
| 26 | margin-bottom:14px |
| 27 | } |
| 28 | .hsl-group { |
| 29 | display:flex; |
| 30 | flex-direction:column; |
| 31 | gap:4px |
| 32 | } |
| 33 | .hsl-header { |
| 34 | display:flex; |
| 35 | justify-content:space-between; |
| 36 | align-items:center |
| 37 | } |
| 38 | .hsl-header label { |
| 39 | font-size:11px; |
| 40 | color:#808080; |
| 41 | font-weight:500 |
| 42 | } |
| 43 | .hsl-val { |
| 44 | font-size:11px; |
| 45 | color:#00FF41; |
| 46 | font-weight:600; |
| 47 | font-variant-numeric:tabular-nums |
| 48 | } |
| 49 | .hsl-slider { |
| 50 | width:100%; |
| 51 | height:8px; |
| 52 | border-radius:4px; |
| 53 | appearance:none; |
| 54 | outline:none; |
| 55 | cursor:pointer |
| 56 | } |
| 57 | .hsl-slider::-webkit-slider-thumb { |
| 58 | appearance:none; |
| 59 | width:16px; |
| 60 | height:16px; |
| 61 | border-radius:50%; |
| 62 | background:#E0E0E0; |
| 63 | cursor:pointer; |
| 64 | border:2px solid #0A0A0A; |
| 65 | box-shadow:0 0 6px rgba(0, |
| 66 | 0, |
| 67 | 0, |
| 68 | .4) |
| 69 | } |
| 70 | .hsl-slider::-moz-range-thumb { |
| 71 | width:16px; |
| 72 | height:16px; |
| 73 | border-radius:50%; |
| 74 | background:#E0E0E0; |
| 75 | cursor:pointer; |
| 76 | border:2px solid #0A0A0A |
| 77 | } |
| 78 | .hue { |
| 79 | background:linear-gradient(90deg, |
| 80 | hsl(0, |
| 81 | 100%, |
| 82 | 50%), |
| 83 | hsl(60, |
| 84 | 100%, |
| 85 | 50%), |
| 86 | hsl(120, |
| 87 | 100%, |
| 88 | 50%), |
| 89 | hsl(180, |
| 90 | 100%, |
| 91 | 50%), |
| 92 | hsl(240, |
| 93 | 100%, |
| 94 | 50%), |
| 95 | hsl(300, |
| 96 | 100%, |
| 97 | 50%), |
| 98 | hsl(360, |
| 99 | 100%, |
| 100 | 50%)) |
| 101 | } |
| 102 | .sat { |
| 103 | background:linear-gradient(90deg, |
| 104 | #808080, |
| 105 | #00FF41) |
| 106 | } |
| 107 | .light { |
| 108 | background:linear-gradient(90deg, |
| 109 | #000, |
| 110 | #808080, |
| 111 | #fff) |
| 112 | } |
| 113 | .hsl-output { |
| 114 | display:flex; |
| 115 | align-items:center; |
| 116 | gap:8px; |
| 117 | padding:8px 10px; |
| 118 | background:#0A0A0A; |
| 119 | border-radius:6px; |
| 120 | border:1px solid #222 |
| 121 | } |
| 122 | .hsl-output code { |
| 123 | font-size:11px; |
| 124 | color:#00FF41; |
| 125 | font-family:monospace; |
| 126 | flex:1 |
| 127 | } |
| 128 | .hsl-copy { |
| 129 | padding:4px 10px; |
| 130 | border-radius:4px; |
| 131 | font-size:10px; |
| 132 | font-weight:600; |
| 133 | background:transparent; |
| 134 | color:#808080; |
| 135 | border:1px solid #333; |
| 136 | cursor:pointer; |
| 137 | transition:all .2s; |
| 138 | font-family:system-ui, |
| 139 | sans-serif |
| 140 | } |
| 141 | .hsl-copy:hover { |
| 142 | color:#E0E0E0; |
| 143 | border-color:#555 |
| 144 | } |
| 145 | .hsl-copy.copied { |
| 146 | color:#00FF41; |
| 147 | border-color:#00FF41 |
| 148 | } |
| 1 | const h=document.getElementById('hsl-h');const s=document.getElementById('hsl-s');const l=document.getElementById('hsl-l');const preview=document.getElementById('hsl-preview');const cssOut=document.getElementById('hsl-css');const hVal=document.getElementById('hsl-h-val');const sVal=document.getElementById('hsl-s-val');const lVal=document.getElementById('hsl-l-val');function updateHSL(){const hv=h.value;const sv=s.value;const lv=l.value;const col='hsl('+hv+','+sv+'%,'+lv+'%)';preview.style.background=col;cssOut.textContent='hsl('+hv+', '+sv+'%, '+lv+'%)';hVal.textContent=hv+'°';sVal.textContent=sv+'%';lVal.textContent=lv+'%';const satGrad='linear-gradient(90deg,hsl('+hv+',0%,'+lv+'%),hsl('+hv+',100%,'+lv+'%))';s.style.background=satGrad;const lightGrad='linear-gradient(90deg,hsl('+hv+','+sv+'%,0%),hsl('+hv+','+sv+'%,50%),hsl('+hv+','+sv+'%,100%))';l.style.background=lightGrad}[h,s,l].forEach(el=>el.addEventListener('input',updateHSL));document.getElementById('hsl-copy').addEventListener('click',function(){navigator.clipboard.writeText(cssOut.textContent);this.textContent='Copied!';this.classList.add('copied');setTimeout(()=>{this.textContent='Copy';this.classList.remove('copied')},1500)}) |
| 1 | <div class="max-w-[340px] mx-auto p-4 bg-[#111] border border-[#222] rounded-xl font-sans"> |
| 2 | <div id="tw-hsl-preview" class="w-full h-12 rounded-lg mb-3.5 border border-white/5 transition-colors" style="background:hsl(140,100%,50%)"> |
| 3 | </div> |
| 4 | <div class="flex flex-col gap-3.5 mb-3.5"> |
| 5 | <div class="flex flex-col gap-1"> |
| 6 | <div class="flex justify-between items-center"> |
| 7 | <label class="text-[11px] font-medium text-[#808080]"> |
| 8 | Hue |
| 9 | </label> |
| 10 | <span id="tw-hsl-h-val" class="text-[11px] font-semibold text-[#00FF41] tabular-nums"> |
| 11 | 140° |
| 12 | </span> |
| 13 | </div> |
| 14 | <input type="range" id="tw-hsl-h" min="0" max="360" value="140" class="w-full h-2 rounded outline-none cursor-pointer appearance-none" style="background:linear-gradient(90deg,hsl(0,100%,50%),hsl(60,100%,50%),hsl(120,100%,50%),hsl(180,100%,50%),hsl(240,100%,50%),hsl(300,100%,50%),hsl(360,100%,50%))"/> |
| 15 | </div> |
| 16 | <div class="flex flex-col gap-1"> |
| 17 | <div class="flex justify-between items-center"> |
| 18 | <label class="text-[11px] font-medium text-[#808080]"> |
| 19 | Saturation |
| 20 | </label> |
| 21 | <span id="tw-hsl-s-val" class="text-[11px] font-semibold text-[#00FF41] tabular-nums"> |
| 22 | 100% |
| 23 | </span> |
| 24 | </div> |
| 25 | <input type="range" id="tw-hsl-s" min="0" max="100" value="100" class="w-full h-2 rounded outline-none cursor-pointer appearance-none" style="background:linear-gradient(90deg,#808080,#00FF41)"/> |
| 26 | </div> |
| 27 | <div class="flex flex-col gap-1"> |
| 28 | <div class="flex justify-between items-center"> |
| 29 | <label class="text-[11px] font-medium text-[#808080]"> |
| 30 | Lightness |
| 31 | </label> |
| 32 | <span id="tw-hsl-l-val" class="text-[11px] font-semibold text-[#00FF41] tabular-nums"> |
| 33 | 50% |
| 34 | </span> |
| 35 | </div> |
| 36 | <input type="range" id="tw-hsl-l" min="0" max="100" value="50" class="w-full h-2 rounded outline-none cursor-pointer appearance-none" style="background:linear-gradient(90deg,#000,#808080,#fff)"/> |
| 37 | </div> |
| 38 | </div> |
| 39 | <div class="flex items-center gap-2 px-2.5 py-2 bg-[#0A0A0A] rounded-md border border-[#222]"> |
| 40 | <code id="tw-hsl-css" class="text-xs text-[#00FF41] font-mono flex-1"> |
| 41 | hsl(140, 100%, 50%) |
| 42 | </code> |
| 43 | <button id="tw-hsl-copy" class="px-2.5 py-1 rounded text-[10px] font-semibold bg-transparent text-[#808080] border border-[#333] hover:text-[#E0E0E0] hover:border-[#555] transition-colors"> |
| 44 | Copy |
| 45 | </button> |
| 46 | </div> |
| 47 | </div> |
| 1 | <div class="mx-auto p-4 rounded" style="max-width:340px;background:#111;border:1px solid #222"> |
| 2 | <div id="bs-hsl-preview" class="w-100 rounded" style="height:48px;background:hsl(140,100%,50%);margin-bottom:14px;border:1px solid rgba(255,255,255,.05)"> |
| 3 | </div> |
| 4 | <div class="d-flex flex-column gap-3 mb-3"> |
| 5 | <div class="d-flex flex-column gap-1"> |
| 6 | <div class="d-flex justify-content-between"> |
| 7 | <label class="mb-0" style="font-size:11px;color:#808080"> |
| 8 | Hue |
| 9 | </label> |
| 10 | <span id="bs-hsl-h-val" class="font-monospace fw-semibold" style="font-size:11px;color:#00FF41"> |
| 11 | 140° |
| 12 | </span> |
| 13 | </div> |
| 14 | <input type="range" id="bs-hsl-h" min="0" max="360" value="140" class="form-range" style="background:linear-gradient(90deg,hsl(0,100%,50%),hsl(60,100%,50%),hsl(120,100%,50%),hsl(180,100%,50%),hsl(240,100%,50%),hsl(300,100%,50%),hsl(360,100%,50%));height:8px;border-radius:4px"/> |
| 15 | </div> |
| 16 | <div class="d-flex flex-column gap-1"> |
| 17 | <div class="d-flex justify-content-between"> |
| 18 | <label class="mb-0" style="font-size:11px;color:#808080"> |
| 19 | Saturation |
| 20 | </label> |
| 21 | <span id="bs-hsl-s-val" class="font-monospace fw-semibold" style="font-size:11px;color:#00FF41"> |
| 22 | 100% |
| 23 | </span> |
| 24 | </div> |
| 25 | <input type="range" id="bs-hsl-s" min="0" max="100" value="100" class="form-range" style="background:linear-gradient(90deg,#808080,#00FF41);height:8px;border-radius:4px"/> |
| 26 | </div> |
| 27 | <div class="d-flex flex-column gap-1"> |
| 28 | <div class="d-flex justify-content-between"> |
| 29 | <label class="mb-0" style="font-size:11px;color:#808080"> |
| 30 | Lightness |
| 31 | </label> |
| 32 | <span id="bs-hsl-l-val" class="font-monospace fw-semibold" style="font-size:11px;color:#00FF41"> |
| 33 | 50% |
| 34 | </span> |
| 35 | </div> |
| 36 | <input type="range" id="bs-hsl-l" min="0" max="100" value="50" class="form-range" style="background:linear-gradient(90deg,#000,#808080,#fff);height:8px;border-radius:4px"/> |
| 37 | </div> |
| 38 | </div> |
| 39 | <div class="d-flex align-items-center gap-2 px-2 py-2 rounded" style="background:#0A0A0A;border:1px solid #222"> |
| 40 | <code id="bs-hsl-css" class="font-monospace flex-grow-1" style="font-size:11px;color:#00FF41"> |
| 41 | hsl(140, 100%, 50%) |
| 42 | </code> |
| 43 | <button id="bs-hsl-copy" class="btn btn-sm" style="font-size:10px;font-weight:600;background:transparent;color:#808080;border:1px solid #333"> |
| 44 | Copy |
| 45 | </button> |
| 46 | </div> |
| 47 | </div> |
A base color input that generates a 5-shade palette by adjusting lightness. Click any shade to copy its hex value.
| 1 | <div class="palette-demo"> |
| 2 | <div class="pd-input"> |
| 3 | <label> |
| 4 | Base Color |
| 5 | </label> |
| 6 | <input type="color" value="#3B82F6" id="pal-color" class="pd-picker"/> |
| 7 | </div> |
| 8 | <div class="pd-shades" id="pd-shades"> |
| 9 | <div class="pd-shade" style="background:hsl(217,91%,60%)"> |
| 10 | <span class="pd-label"> |
| 11 | 500 |
| 12 | </span> |
| 13 | <span class="pd-hex"> |
| 14 | #3B82F6 |
| 15 | </span> |
| 16 | </div> |
| 17 | <div class="pd-shade" style="background:hsl(217,91%,40%)"> |
| 18 | <span class="pd-label"> |
| 19 | 600 |
| 20 | </span> |
| 21 | <span class="pd-hex"> |
| 22 | #2563EB |
| 23 | </span> |
| 24 | </div> |
| 25 | <div class="pd-shade" style="background:hsl(217,91%,30%)"> |
| 26 | <span class="pd-label"> |
| 27 | 700 |
| 28 | </span> |
| 29 | <span class="pd-hex"> |
| 30 | #1D4ED8 |
| 31 | </span> |
| 32 | </div> |
| 33 | <div class="pd-shade" style="background:hsl(217,91%,70%)"> |
| 34 | <span class="pd-label"> |
| 35 | 400 |
| 36 | </span> |
| 37 | <span class="pd-hex"> |
| 38 | #60A5FA |
| 39 | </span> |
| 40 | </div> |
| 41 | <div class="pd-shade" style="background:hsl(217,91%,85%)"> |
| 42 | <span class="pd-label"> |
| 43 | 200 |
| 44 | </span> |
| 45 | <span class="pd-hex"> |
| 46 | #BFDBFE |
| 47 | </span> |
| 48 | </div> |
| 49 | </div> |
| 50 | </div> |
| 1 | .palette-demo { |
| 2 | max-width:380px; |
| 3 | margin:16px auto; |
| 4 | padding:16px 20px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:10px; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .pd-input { |
| 12 | display:flex; |
| 13 | align-items:center; |
| 14 | gap:10px; |
| 15 | margin-bottom:14px |
| 16 | } |
| 17 | .pd-input label { |
| 18 | font-size:12px; |
| 19 | font-weight:600; |
| 20 | color:#E0E0E0 |
| 21 | } |
| 22 | .pd-picker { |
| 23 | width:32px; |
| 24 | height:28px; |
| 25 | border:2px solid #2A2A3E; |
| 26 | border-radius:6px; |
| 27 | cursor:pointer; |
| 28 | background:transparent; |
| 29 | padding:1px |
| 30 | } |
| 31 | .pd-picker::-webkit-color-swatch-wrapper { |
| 32 | padding:0 |
| 33 | } |
| 34 | .pd-picker::-webkit-color-swatch { |
| 35 | border:none; |
| 36 | border-radius:3px |
| 37 | } |
| 38 | .pd-shades { |
| 39 | display:flex; |
| 40 | gap:6px |
| 41 | } |
| 42 | .pd-shade { |
| 43 | flex:1; |
| 44 | height:56px; |
| 45 | border-radius:8px; |
| 46 | display:flex; |
| 47 | flex-direction:column; |
| 48 | align-items:center; |
| 49 | justify-content:center; |
| 50 | gap:2px; |
| 51 | cursor:pointer; |
| 52 | transition:transform .2s; |
| 53 | position:relative |
| 54 | } |
| 55 | .pd-shade:hover { |
| 56 | transform:scale(1.05) |
| 57 | } |
| 58 | .pd-label { |
| 59 | font-size:9px; |
| 60 | font-weight:700; |
| 61 | color:rgba(255, |
| 62 | 255, |
| 63 | 255, |
| 64 | .8); |
| 65 | text-shadow:0 1px 2px rgba(0, |
| 66 | 0, |
| 67 | 0, |
| 68 | .5) |
| 69 | } |
| 70 | .pd-hex { |
| 71 | font-size:8px; |
| 72 | color:rgba(255, |
| 73 | 255, |
| 74 | 255, |
| 75 | .6); |
| 76 | font-family:monospace; |
| 77 | text-shadow:0 1px 2px rgba(0, |
| 78 | 0, |
| 79 | 0, |
| 80 | .5) |
| 81 | } |
| 1 | function hexToHSL(H){let r=0,g=0,b=0;if(H.length===4){r=parseInt(H[1]+H[1],16);g=parseInt(H[2]+H[2],16);b=parseInt(H[3]+H[3],16)}else if(H.length===7){r=parseInt(H.slice(1,3),16);g=parseInt(H.slice(3,5),16);b=parseInt(H.slice(5,7),16)}r/=255;g/=255;b/=255;const max=Math.max(r,g,b),min=Math.min(r,g,b);let h=0,s=0,l=(max+min)/2;if(max!==min){const d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=((g-b)/d+(g<b?6:0))/6;break;case g:h=((b-r)/d+2)/6;break;case b:h=((r-g)/d+4)/6;break}}return{h:Math.round(h*360),s:Math.round(s*100),l:Math.round(l*100)}}function hslToHex(h,s,l){l/=100;const a=s*Math.min(l,1-l)/100;const f=n=>{const k=(n+h/30)%12;const c=l-a*Math.max(Math.min(k-3,9-k,1),-1);return Math.round(255*c).toString(16).padStart(2,'0')};return'#'+f(0)+f(8)+f(4)}document.getElementById('pal-color').addEventListener('input',function(){const hsl=hexToHSL(this.value);const names=[{n:'900',l:Math.max(hsl.l-35,5)},{n:'700',l:Math.max(hsl.l-20,10)},{n:'500',l:hsl.l},{n:'300',l:Math.min(hsl.l+20,90)},{n:'100',l:Math.min(hsl.l+35,95)}];names.sort((a,b)=>b.n-a.n);const grid=document.getElementById('pd-shades');grid.innerHTML='';names.forEach(s=>{const hex=hslToHex(hsl.h,hsl.s,s.l);const div=document.createElement('div');div.className='pd-shade';div.style.background='hsl('+hsl.h+','+hsl.s+'%,'+s.l+'%)';div.innerHTML='<span class="pd-label">'+s.n+'</span><span class="pd-hex">'+hex.toUpperCase()+'</span>';div.addEventListener('click',()=>{navigator.clipboard.writeText(hex.toUpperCase());div.style.outline='2px solid #fff';setTimeout(()=>div.style.outline='',800)});grid.appendChild(div)})}) |
| 1 | <div class="max-w-[380px] mx-auto p-4 bg-[#111] border border-[#222] rounded-xl font-sans"> |
| 2 | <div class="flex items-center gap-2.5 mb-3.5"> |
| 3 | <label class="text-xs font-semibold text-[#E0E0E0]"> |
| 4 | Base Color |
| 5 | </label> |
| 6 | <input type="color" id="tw-pal-color" value="#3B82F6" class="w-8 h-7 p-0.5 bg-transparent border-2 border-[#2A2A3E] rounded-md cursor-pointer"/> |
| 7 | </div> |
| 8 | <div id="tw-pd-shades" class="flex gap-1.5"> |
| 9 | <div class="flex-1 h-14 rounded-lg flex flex-col items-center justify-center gap-0.5 cursor-pointer hover:scale-105 transition-transform" style="background:#1E3A8A"> |
| 10 | <span class="text-[9px] font-bold text-white/80" style="text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 11 | 900 |
| 12 | </span> |
| 13 | <span class="text-[8px] font-mono text-white/60" style="text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 14 | #1E3A8A |
| 15 | </span> |
| 16 | </div> |
| 17 | <div class="flex-1 h-14 rounded-lg flex flex-col items-center justify-center gap-0.5 cursor-pointer hover:scale-105 transition-transform" style="background:#1D4ED8"> |
| 18 | <span class="text-[9px] font-bold text-white/80" style="text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 19 | 700 |
| 20 | </span> |
| 21 | <span class="text-[8px] font-mono text-white/60" style="text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 22 | #1D4ED8 |
| 23 | </span> |
| 24 | </div> |
| 25 | <div class="flex-1 h-14 rounded-lg flex flex-col items-center justify-center gap-0.5 cursor-pointer hover:scale-105 transition-transform" style="background:#3B82F6"> |
| 26 | <span class="text-[9px] font-bold text-white/80" style="text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 27 | 500 |
| 28 | </span> |
| 29 | <span class="text-[8px] font-mono text-white/60" style="text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 30 | #3B82F6 |
| 31 | </span> |
| 32 | </div> |
| 33 | <div class="flex-1 h-14 rounded-lg flex flex-col items-center justify-center gap-0.5 cursor-pointer hover:scale-105 transition-transform" style="background:#93C5FD"> |
| 34 | <span class="text-[9px] font-bold text-black/70" style="text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 35 | 300 |
| 36 | </span> |
| 37 | <span class="text-[8px] font-mono text-black/60" style="text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 38 | #93C5FD |
| 39 | </span> |
| 40 | </div> |
| 41 | <div class="flex-1 h-14 rounded-lg flex flex-col items-center justify-center gap-0.5 cursor-pointer hover:scale-105 transition-transform" style="background:#DBEAFE"> |
| 42 | <span class="text-[9px] font-bold text-black/70" style="text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 43 | 100 |
| 44 | </span> |
| 45 | <span class="text-[8px] font-mono text-black/60" style="text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 46 | #DBEAFE |
| 47 | </span> |
| 48 | </div> |
| 49 | </div> |
| 50 | </div> |
| 1 | <div class="mx-auto p-4 rounded" style="max-width:380px;background:#111;border:1px solid #222"> |
| 2 | <div class="d-flex align-items-center gap-2 mb-3"> |
| 3 | <label class="small fw-semibold mb-0" style="color:#E0E0E0"> |
| 4 | Base Color |
| 5 | </label> |
| 6 | <input type="color" id="bs-pal-color" value="#3B82F6" class="form-control form-control-color p-0" style="width:32px;height:28px;background:transparent;border-color:#2A2A3E;border-radius:6px"/> |
| 7 | </div> |
| 8 | <div id="bs-pd-shades" class="d-flex gap-1"> |
| 9 | <div class="flex-fill rounded d-flex flex-column align-items-center justify-content-center" style="height:56px;background:#1E3A8A;cursor:pointer"> |
| 10 | <span class="fw-bold" style="font-size:9px;color:rgba(255,255,255,.8);text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 11 | 900 |
| 12 | </span> |
| 13 | <span class="font-monospace" style="font-size:8px;color:rgba(255,255,255,.6);text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 14 | #1E3A8A |
| 15 | </span> |
| 16 | </div> |
| 17 | <div class="flex-fill rounded d-flex flex-column align-items-center justify-content-center" style="height:56px;background:#1D4ED8;cursor:pointer"> |
| 18 | <span class="fw-bold" style="font-size:9px;color:rgba(255,255,255,.8);text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 19 | 700 |
| 20 | </span> |
| 21 | <span class="font-monospace" style="font-size:8px;color:rgba(255,255,255,.6);text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 22 | #1D4ED8 |
| 23 | </span> |
| 24 | </div> |
| 25 | <div class="flex-fill rounded d-flex flex-column align-items-center justify-content-center" style="height:56px;background:#3B82F6;cursor:pointer"> |
| 26 | <span class="fw-bold" style="font-size:9px;color:rgba(255,255,255,.8);text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 27 | 500 |
| 28 | </span> |
| 29 | <span class="font-monospace" style="font-size:8px;color:rgba(255,255,255,.6);text-shadow:0 1px 2px rgba(0,0,0,.5)"> |
| 30 | #3B82F6 |
| 31 | </span> |
| 32 | </div> |
| 33 | <div class="flex-fill rounded d-flex flex-column align-items-center justify-content-center" style="height:56px;background:#93C5FD;cursor:pointer"> |
| 34 | <span class="fw-bold" style="font-size:9px;color:rgba(0,0,0,.7);text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 35 | 300 |
| 36 | </span> |
| 37 | <span class="font-monospace" style="font-size:8px;color:rgba(0,0,0,.6);text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 38 | #93C5FD |
| 39 | </span> |
| 40 | </div> |
| 41 | <div class="flex-fill rounded d-flex flex-column align-items-center justify-content-center" style="height:56px;background:#DBEAFE;cursor:pointer"> |
| 42 | <span class="fw-bold" style="font-size:9px;color:rgba(0,0,0,.7);text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 43 | 100 |
| 44 | </span> |
| 45 | <span class="font-monospace" style="font-size:8px;color:rgba(0,0,0,.6);text-shadow:0 1px 2px rgba(255,255,255,.5)"> |
| 46 | #DBEAFE |
| 47 | </span> |
| 48 | </div> |
| 49 | </div> |
| 50 | </div> |
A gradient builder with two color stops and angle control. The preview shows the live CSS gradient and the output is ready to copy.
| 1 | <div class="grad-demo"> |
| 2 | <div class="grad-preview" id="grad-preview" style="background:linear-gradient(135deg,#3B82F6,#8B5CF6)"> |
| 3 | </div> |
| 4 | <div class="grad-fields"> |
| 5 | <div class="grad-row"> |
| 6 | <label> |
| 7 | Start |
| 8 | </label> |
| 9 | <input type="color" value="#3B82F6" id="grad-start" class="grad-color"/> |
| 10 | <span class="grad-hex" id="grad-start-hex"> |
| 11 | #3B82F6 |
| 12 | </span> |
| 13 | </div> |
| 14 | <div class="grad-row"> |
| 15 | <label> |
| 16 | End |
| 17 | </label> |
| 18 | <input type="color" value="#8B5CF6" id="grad-end" class="grad-color"/> |
| 19 | <span class="grad-hex" id="grad-end-hex"> |
| 20 | #8B5CF6 |
| 21 | </span> |
| 22 | </div> |
| 23 | <div class="grad-row full"> |
| 24 | <div class="grad-angle-header"> |
| 25 | <label> |
| 26 | Angle |
| 27 | </label> |
| 28 | <span class="grad-angle-val" id="grad-angle-val"> |
| 29 | 135° |
| 30 | </span> |
| 31 | </div> |
| 32 | <input type="range" class="grad-slider" id="grad-angle" min="0" max="360" value="135"/> |
| 33 | </div> |
| 34 | </div> |
| 35 | <div class="grad-output"> |
| 36 | <code id="grad-css"> |
| 37 | linear-gradient(135deg, #3B82F6, #8B5CF6) |
| 38 | </code> |
| 39 | <button class="grad-copy" id="grad-copy"> |
| 40 | Copy |
| 41 | </button> |
| 42 | </div> |
| 43 | </div> |
| 1 | .grad-demo { |
| 2 | max-width:340px; |
| 3 | margin:16px auto; |
| 4 | padding:16px 20px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:10px; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .grad-preview { |
| 12 | width:100%; |
| 13 | height:48px; |
| 14 | border-radius:8px; |
| 15 | margin-bottom:14px; |
| 16 | border:1px solid rgba(255, |
| 17 | 255, |
| 18 | 255, |
| 19 | .05); |
| 20 | transition:background .15s ease |
| 21 | } |
| 22 | .grad-fields { |
| 23 | display:flex; |
| 24 | flex-wrap:wrap; |
| 25 | gap:10px; |
| 26 | margin-bottom:12px |
| 27 | } |
| 28 | .grad-row { |
| 29 | display:flex; |
| 30 | align-items:center; |
| 31 | gap:8px; |
| 32 | flex:1; |
| 33 | min-width:120px |
| 34 | } |
| 35 | .grad-row.full { |
| 36 | flex-basis:100% |
| 37 | } |
| 38 | .grad-row label { |
| 39 | font-size:10px; |
| 40 | color:#808080; |
| 41 | font-weight:500; |
| 42 | min-width:32px |
| 43 | } |
| 44 | .grad-color { |
| 45 | width:28px; |
| 46 | height:24px; |
| 47 | border:1px solid #2A2A3E; |
| 48 | border-radius:4px; |
| 49 | cursor:pointer; |
| 50 | background:transparent; |
| 51 | padding:1px |
| 52 | } |
| 53 | .grad-color::-webkit-color-swatch-wrapper { |
| 54 | padding:0 |
| 55 | } |
| 56 | .grad-color::-webkit-color-swatch { |
| 57 | border:none; |
| 58 | border-radius:2px |
| 59 | } |
| 60 | .grad-hex { |
| 61 | font-size:10px; |
| 62 | color:#00FF41; |
| 63 | font-family:monospace |
| 64 | } |
| 65 | .grad-angle-header { |
| 66 | display:flex; |
| 67 | justify-content:space-between; |
| 68 | width:100%; |
| 69 | margin-bottom:2px |
| 70 | } |
| 71 | .grad-angle-val { |
| 72 | font-size:10px; |
| 73 | color:#00FF41; |
| 74 | font-weight:600 |
| 75 | } |
| 76 | .grad-slider { |
| 77 | width:100%; |
| 78 | height:4px; |
| 79 | border-radius:2px; |
| 80 | appearance:none; |
| 81 | background:linear-gradient(90deg, |
| 82 | #3B82F6, |
| 83 | #8B5CF6); |
| 84 | outline:none; |
| 85 | cursor:pointer |
| 86 | } |
| 87 | .grad-slider::-webkit-slider-thumb { |
| 88 | appearance:none; |
| 89 | width:14px; |
| 90 | height:14px; |
| 91 | border-radius:50%; |
| 92 | background:#E0E0E0; |
| 93 | border:2px solid #0A0A0A; |
| 94 | cursor:pointer |
| 95 | } |
| 96 | .grad-slider::-moz-range-thumb { |
| 97 | width:14px; |
| 98 | height:14px; |
| 99 | border-radius:50%; |
| 100 | background:#E0E0E0; |
| 101 | border:2px solid #0A0A0A; |
| 102 | cursor:pointer |
| 103 | } |
| 104 | .grad-output { |
| 105 | display:flex; |
| 106 | align-items:center; |
| 107 | gap:8px; |
| 108 | padding:8px 10px; |
| 109 | background:#0A0A0A; |
| 110 | border-radius:6px; |
| 111 | border:1px solid #222 |
| 112 | } |
| 113 | .grad-output code { |
| 114 | font-size:10px; |
| 115 | color:#00FF41; |
| 116 | font-family:monospace; |
| 117 | flex:1; |
| 118 | word-break:break-all |
| 119 | } |
| 120 | .grad-copy { |
| 121 | padding:4px 10px; |
| 122 | border-radius:4px; |
| 123 | font-size:10px; |
| 124 | font-weight:600; |
| 125 | background:transparent; |
| 126 | color:#808080; |
| 127 | border:1px solid #333; |
| 128 | cursor:pointer; |
| 129 | transition:all .2s; |
| 130 | font-family:system-ui, |
| 131 | sans-serif; |
| 132 | flex-shrink:0 |
| 133 | } |
| 134 | .grad-copy:hover { |
| 135 | color:#E0E0E0; |
| 136 | border-color:#555 |
| 137 | } |
| 1 | const start=document.getElementById('grad-start');const end=document.getElementById('grad-end');const angle=document.getElementById('grad-angle');const preview=document.getElementById('grad-preview');const cssOut=document.getElementById('grad-css');const sHex=document.getElementById('grad-start-hex');const eHex=document.getElementById('grad-end-hex');const aVal=document.getElementById('grad-angle-val');function updateGrad(){const v=angle.value;const c='linear-gradient('+v+'deg, '+start.value+', '+end.value+')';preview.style.background=c;cssOut.textContent=c;sHex.textContent=start.value.toUpperCase();eHex.textContent=end.value.toUpperCase();aVal.textContent=v+'°';document.querySelector('.grad-slider').style.background='linear-gradient(90deg,'+start.value+','+end.value+')'}[start,end,angle].forEach(el=>el.addEventListener('input',updateGrad));document.getElementById('grad-copy').addEventListener('click',function(){navigator.clipboard.writeText(cssOut.textContent);this.textContent='Copied!';setTimeout(()=>this.textContent='Copy',1500)}) |
| 1 | <div class="max-w-[340px] mx-auto p-4 bg-[#111] border border-[#222] rounded-xl font-sans"> |
| 2 | <div id="tw-grad-preview" class="w-full h-12 rounded-lg mb-3.5 border border-white/5 transition-colors" style="background:linear-gradient(135deg,#3B82F6,#8B5CF6)"> |
| 3 | </div> |
| 4 | <div class="flex flex-wrap gap-2.5 mb-3"> |
| 5 | <div class="flex items-center gap-2 flex-1 min-w-[120px]"> |
| 6 | <label class="text-[10px] font-medium text-[#808080] min-w-[32px]"> |
| 7 | Start |
| 8 | </label> |
| 9 | <input type="color" id="tw-grad-start" value="#3B82F6" class="w-7 h-6 p-0.5 bg-transparent border border-[#2A2A3E] rounded cursor-pointer"/> |
| 10 | <span id="tw-grad-start-hex" class="text-[10px] text-[#00FF41] font-mono"> |
| 11 | #3B82F6 |
| 12 | </span> |
| 13 | </div> |
| 14 | <div class="flex items-center gap-2 flex-1 min-w-[120px]"> |
| 15 | <label class="text-[10px] font-medium text-[#808080] min-w-[32px]"> |
| 16 | End |
| 17 | </label> |
| 18 | <input type="color" id="tw-grad-end" value="#8B5CF6" class="w-7 h-6 p-0.5 bg-transparent border border-[#2A2A3E] rounded cursor-pointer"/> |
| 19 | <span id="tw-grad-end-hex" class="text-[10px] text-[#00FF41] font-mono"> |
| 20 | #8B5CF6 |
| 21 | </span> |
| 22 | </div> |
| 23 | <div class="w-full flex flex-col gap-0.5"> |
| 24 | <div class="flex justify-between"> |
| 25 | <label class="text-[10px] font-medium text-[#808080]"> |
| 26 | Angle |
| 27 | </label> |
| 28 | <span id="tw-grad-angle-val" class="text-[10px] font-semibold text-[#00FF41]"> |
| 29 | 135° |
| 30 | </span> |
| 31 | </div> |
| 32 | <input type="range" id="tw-grad-angle" min="0" max="360" value="135" class="w-full h-1 rounded outline-none cursor-pointer appearance-none" style="background:linear-gradient(90deg,#3B82F6,#8B5CF6)"/> |
| 33 | </div> |
| 34 | </div> |
| 35 | <div class="flex items-center gap-2 px-2.5 py-2 bg-[#0A0A0A] rounded-md border border-[#222]"> |
| 36 | <code id="tw-grad-css" class="text-[10px] text-[#00FF41] font-mono flex-1 break-all"> |
| 37 | linear-gradient(135deg, #3B82F6, #8B5CF6) |
| 38 | </code> |
| 39 | <button id="tw-grad-copy" class="px-2.5 py-1 rounded text-[10px] font-semibold bg-transparent text-[#808080] border border-[#333] hover:text-[#E0E0E0] hover:border-[#555] transition-colors shrink-0"> |
| 40 | Copy |
| 41 | </button> |
| 42 | </div> |
| 43 | </div> |
| 1 | <div class="mx-auto p-4 rounded" style="max-width:340px;background:#111;border:1px solid #222"> |
| 2 | <div id="bs-grad-preview" class="w-100 rounded" style="height:48px;background:linear-gradient(135deg,#3B82F6,#8B5CF6);margin-bottom:14px;border:1px solid rgba(255,255,255,.05)"> |
| 3 | </div> |
| 4 | <div class="row g-2 mb-3"> |
| 5 | <div class="col-6 d-flex align-items-center gap-2"> |
| 6 | <label class="mb-0" style="font-size:10px;color:#808080;min-width:32px"> |
| 7 | Start |
| 8 | </label> |
| 9 | <input type="color" id="bs-grad-start" value="#3B82F6" class="form-control form-control-sm form-control-color p-0" style="width:28px;height:24px;background:transparent;border-color:#2A2A3E;border-radius:4px"/> |
| 10 | <span id="bs-grad-start-hex" class="font-monospace" style="font-size:10px;color:#00FF41"> |
| 11 | #3B82F6 |
| 12 | </span> |
| 13 | </div> |
| 14 | <div class="col-6 d-flex align-items-center gap-2"> |
| 15 | <label class="mb-0" style="font-size:10px;color:#808080;min-width:32px"> |
| 16 | End |
| 17 | </label> |
| 18 | <input type="color" id="bs-grad-end" value="#8B5CF6" class="form-control form-control-sm form-control-color p-0" style="width:28px;height:24px;background:transparent;border-color:#2A2A3E;border-radius:4px"/> |
| 19 | <span id="bs-grad-end-hex" class="font-monospace" style="font-size:10px;color:#00FF41"> |
| 20 | #8B5CF6 |
| 21 | </span> |
| 22 | </div> |
| 23 | <div class="col-12"> |
| 24 | <div class="d-flex justify-content-between mb-1"> |
| 25 | <label class="mb-0" style="font-size:10px;color:#808080"> |
| 26 | Angle |
| 27 | </label> |
| 28 | <span id="bs-grad-angle-val" class="font-monospace fw-semibold" style="font-size:10px;color:#00FF41"> |
| 29 | 135° |
| 30 | </span> |
| 31 | </div> |
| 32 | <input type="range" id="bs-grad-angle" min="0" max="360" value="135" class="form-range" style="height:4px;border-radius:2px;background:linear-gradient(90deg,#3B82F6,#8B5CF6)"/> |
| 33 | </div> |
| 34 | </div> |
| 35 | <div class="d-flex align-items-center gap-2 px-2 py-2 rounded" style="background:#0A0A0A;border:1px solid #222"> |
| 36 | <code id="bs-grad-css" class="font-monospace flex-grow-1" style="font-size:10px;color:#00FF41;word-break:break-all"> |
| 37 | linear-gradient(135deg, #3B82F6, #8B5CF6) |
| 38 | </code> |
| 39 | <button id="bs-grad-copy" class="btn btn-sm" style="font-size:10px;font-weight:600;background:transparent;color:#808080;border:1px solid #333"> |
| 40 | Copy |
| 41 | </button> |
| 42 | </div> |
| 43 | </div> |
Generate complementary and triadic color schemes from a single base color. Useful for building balanced palettes and exploring relationships on the color wheel.
| 1 | <div class="harmony-demo"> |
| 2 | <div class="hm-input"> |
| 3 | <label> |
| 4 | Base |
| 5 | </label> |
| 6 | <input type="color" value="#00FF41" id="hm-base" class="hm-picker"/> |
| 7 | </div> |
| 8 | <div class="hm-row"> |
| 9 | <span class="hm-name"> |
| 10 | Complementary |
| 11 | </span> |
| 12 | <div class="hm-swatches" id="hm-comp"> |
| 13 | <div class="hm-swatch" style="background:#00FF41" data-hex="#00FF41"> |
| 14 | </div> |
| 15 | <div class="hm-swatch" style="background:#FF00BE" data-hex="#FF00BE"> |
| 16 | </div> |
| 17 | </div> |
| 18 | </div> |
| 19 | <div class="hm-row"> |
| 20 | <span class="hm-name"> |
| 21 | Triadic |
| 22 | </span> |
| 23 | <div class="hm-swatches" id="hm-triad"> |
| 24 | <div class="hm-swatch" style="background:#00FF41" data-hex="#00FF41"> |
| 25 | </div> |
| 26 | <div class="hm-swatch" style="background:#4100FF" data-hex="#4100FF"> |
| 27 | </div> |
| 28 | <div class="hm-swatch" style="background:#FF4100" data-hex="#FF4100"> |
| 29 | </div> |
| 30 | </div> |
| 31 | </div> |
| 32 | </div> |
| 1 | .harmony-demo { |
| 2 | max-width:360px; |
| 3 | margin:16px auto; |
| 4 | padding:16px 20px; |
| 5 | background:#111; |
| 6 | border:1px solid #222; |
| 7 | border-radius:10px; |
| 8 | font-family:system-ui, |
| 9 | sans-serif |
| 10 | } |
| 11 | .hm-input { |
| 12 | display:flex; |
| 13 | align-items:center; |
| 14 | gap:10px; |
| 15 | margin-bottom:16px |
| 16 | } |
| 17 | .hm-input label { |
| 18 | font-size:12px; |
| 19 | font-weight:600; |
| 20 | color:#E0E0E0 |
| 21 | } |
| 22 | .hm-picker { |
| 23 | width:32px; |
| 24 | height:28px; |
| 25 | border:2px solid #2A2A3E; |
| 26 | border-radius:6px; |
| 27 | cursor:pointer; |
| 28 | background:transparent; |
| 29 | padding:1px |
| 30 | } |
| 31 | .hm-row { |
| 32 | display:flex; |
| 33 | align-items:center; |
| 34 | gap:12px; |
| 35 | margin-bottom:12px |
| 36 | } |
| 37 | .hm-row:last-child { |
| 38 | margin-bottom:0 |
| 39 | } |
| 40 | .hm-name { |
| 41 | width:96px; |
| 42 | font-size:11px; |
| 43 | color:#808080; |
| 44 | font-weight:500 |
| 45 | } |
| 46 | .hm-swatches { |
| 47 | display:flex; |
| 48 | gap:8px; |
| 49 | flex:1 |
| 50 | } |
| 51 | .hm-swatch { |
| 52 | flex:1; |
| 53 | height:36px; |
| 54 | border-radius:8px; |
| 55 | cursor:pointer; |
| 56 | transition:transform .2s; |
| 57 | position:relative |
| 58 | } |
| 59 | .hm-swatch:hover { |
| 60 | transform:scale(1.05) |
| 61 | } |
| 62 | .hm-swatch::after { |
| 63 | content:attr(data-hex); |
| 64 | position:absolute; |
| 65 | inset:0; |
| 66 | display:flex; |
| 67 | align-items:center; |
| 68 | justify-content:center; |
| 69 | font-size:9px; |
| 70 | font-weight:600; |
| 71 | color:#fff; |
| 72 | text-shadow:0 1px 2px rgba(0, |
| 73 | 0, |
| 74 | 0, |
| 75 | .6); |
| 76 | font-family:monospace |
| 77 | } |
| 1 | function hexToHSL(H){let r=0,g=0,b=0;if(H.length===4){r=parseInt(H[1]+H[1],16);g=parseInt(H[2]+H[2],16);b=parseInt(H[3]+H[3],16)}else if(H.length===7){r=parseInt(H.slice(1,3),16);g=parseInt(H.slice(3,5),16);b=parseInt(H.slice(5,7),16)}r/=255;g/=255;b/=255;const max=Math.max(r,g,b),min=Math.min(r,g,b);let h=0,s=0,l=(max+min)/2;if(max!==min){const d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=((g-b)/d+(g<b?6:0))/6;break;case g:h=((b-r)/d+2)/6;break;case b:h=((r-g)/d+4)/6;break}}return{h:Math.round(h*360),s:Math.round(s*100),l:Math.round(l*100)}}function hslToHex(h,s,l){l/=100;const a=s*Math.min(l,1-l)/100;const f=n=>{const k=(n+h/30)%12;const c=l-a*Math.max(Math.min(k-3,9-k,1),-1);return Math.round(255*c).toString(16).padStart(2,'0')};return'#'+f(0)+f(8)+f(4)}function render(container,colors){container.innerHTML='';colors.forEach(c=>{const div=document.createElement('div');div.className='hm-swatch';div.style.background=c;div.dataset.hex=c;div.addEventListener('click',()=>{navigator.clipboard.writeText(c);div.style.outline='2px solid #fff';setTimeout(()=>div.style.outline='',800)});container.appendChild(div)})}function updateHarmonies(){const base=document.getElementById('hm-base').value;const hsl=hexToHSL(base);render(document.getElementById('hm-comp'),[base,hslToHex((hsl.h+180)%360,hsl.s,hsl.l)]);render(document.getElementById('hm-triad'),[base,hslToHex((hsl.h+120)%360,hsl.s,hsl.l),hslToHex((hsl.h+240)%360,hsl.s,hsl.l)])}document.getElementById('hm-base').addEventListener('input',updateHarmonies);updateHarmonies() |
| 1 | <div class="max-w-[360px] mx-auto p-4 bg-[#111] border border-[#222] rounded-xl font-sans"> |
| 2 | <div class="flex items-center gap-2.5 mb-4"> |
| 3 | <label class="text-xs font-semibold text-[#E0E0E0]"> |
| 4 | Base |
| 5 | </label> |
| 6 | <input type="color" id="tw-hm-base" value="#00FF41" class="w-8 h-7 p-0.5 bg-transparent border-2 border-[#2A2A3E] rounded-md cursor-pointer"/> |
| 7 | </div> |
| 8 | <div class="flex items-center gap-3 mb-3"> |
| 9 | <span class="w-24 text-[11px] font-medium text-[#808080]"> |
| 10 | Complementary |
| 11 | </span> |
| 12 | <div id="tw-hm-comp" class="flex gap-2 flex-1"> |
| 13 | <div class="flex-1 h-9 rounded-lg cursor-pointer hover:scale-105 transition-transform relative" style="background:#00FF41" data-hex="#00FF41"> |
| 14 | <span class="absolute inset-0 flex items-center justify-center text-[9px] font-semibold text-white font-mono" style="text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 15 | #00FF41 |
| 16 | </span> |
| 17 | </div> |
| 18 | <div class="flex-1 h-9 rounded-lg cursor-pointer hover:scale-105 transition-transform relative" style="background:#FF00BE" data-hex="#FF00BE"> |
| 19 | <span class="absolute inset-0 flex items-center justify-center text-[9px] font-semibold text-white font-mono" style="text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 20 | #FF00BE |
| 21 | </span> |
| 22 | </div> |
| 23 | </div> |
| 24 | </div> |
| 25 | <div class="flex items-center gap-3"> |
| 26 | <span class="w-24 text-[11px] font-medium text-[#808080]"> |
| 27 | Triadic |
| 28 | </span> |
| 29 | <div id="tw-hm-triad" class="flex gap-2 flex-1"> |
| 30 | <div class="flex-1 h-9 rounded-lg cursor-pointer hover:scale-105 transition-transform relative" style="background:#00FF41" data-hex="#00FF41"> |
| 31 | <span class="absolute inset-0 flex items-center justify-center text-[9px] font-semibold text-white font-mono" style="text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 32 | #00FF41 |
| 33 | </span> |
| 34 | </div> |
| 35 | <div class="flex-1 h-9 rounded-lg cursor-pointer hover:scale-105 transition-transform relative" style="background:#4100FF" data-hex="#4100FF"> |
| 36 | <span class="absolute inset-0 flex items-center justify-center text-[9px] font-semibold text-white font-mono" style="text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 37 | #4100FF |
| 38 | </span> |
| 39 | </div> |
| 40 | <div class="flex-1 h-9 rounded-lg cursor-pointer hover:scale-105 transition-transform relative" style="background:#FF4100" data-hex="#FF4100"> |
| 41 | <span class="absolute inset-0 flex items-center justify-center text-[9px] font-semibold text-white font-mono" style="text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 42 | #FF4100 |
| 43 | </span> |
| 44 | </div> |
| 45 | </div> |
| 46 | </div> |
| 47 | </div> |
| 1 | <div class="mx-auto p-4 rounded" style="max-width:360px;background:#111;border:1px solid #222"> |
| 2 | <div class="d-flex align-items-center gap-2 mb-3"> |
| 3 | <label class="small fw-semibold mb-0" style="color:#E0E0E0"> |
| 4 | Base |
| 5 | </label> |
| 6 | <input type="color" id="bs-hm-base" value="#00FF41" class="form-control form-control-color p-0" style="width:32px;height:28px;background:transparent;border-color:#2A2A3E;border-radius:6px"/> |
| 7 | </div> |
| 8 | <div class="d-flex align-items-center gap-3 mb-3"> |
| 9 | <span class="fw-medium" style="width:96px;font-size:11px;color:#808080"> |
| 10 | Complementary |
| 11 | </span> |
| 12 | <div id="bs-hm-comp" class="d-flex gap-2 flex-fill"> |
| 13 | <div class="flex-fill rounded position-relative" style="height:36px;background:#00FF41;cursor:pointer"> |
| 14 | <span class="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center fw-semibold font-monospace" style="font-size:9px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 15 | #00FF41 |
| 16 | </span> |
| 17 | </div> |
| 18 | <div class="flex-fill rounded position-relative" style="height:36px;background:#FF00BE;cursor:pointer"> |
| 19 | <span class="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center fw-semibold font-monospace" style="font-size:9px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 20 | #FF00BE |
| 21 | </span> |
| 22 | </div> |
| 23 | </div> |
| 24 | </div> |
| 25 | <div class="d-flex align-items-center gap-3"> |
| 26 | <span class="fw-medium" style="width:96px;font-size:11px;color:#808080"> |
| 27 | Triadic |
| 28 | </span> |
| 29 | <div id="bs-hm-triad" class="d-flex gap-2 flex-fill"> |
| 30 | <div class="flex-fill rounded position-relative" style="height:36px;background:#00FF41;cursor:pointer"> |
| 31 | <span class="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center fw-semibold font-monospace" style="font-size:9px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 32 | #00FF41 |
| 33 | </span> |
| 34 | </div> |
| 35 | <div class="flex-fill rounded position-relative" style="height:36px;background:#4100FF;cursor:pointer"> |
| 36 | <span class="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center fw-semibold font-monospace" style="font-size:9px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 37 | #4100FF |
| 38 | </span> |
| 39 | </div> |
| 40 | <div class="flex-fill rounded position-relative" style="height:36px;background:#FF4100;cursor:pointer"> |
| 41 | <span class="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center fw-semibold font-monospace" style="font-size:9px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6)"> |
| 42 | #FF4100 |
| 43 | </span> |
| 44 | </div> |
| 45 | </div> |
| 46 | </div> |
| 47 | </div> |
Pair a native color input with visible hex/RGB inputs and a preview swatch. Sync all inputs bidirectionally and include a copy button.
| 1 | <div class="color-picker"> |
| 2 | <!-- Live preview swatch --> |
| 3 | <div class="preview-swatch" |
| 4 | style="background: #3B82F6"></div> |
| 5 | |
| 6 | <!-- Native color input --> |
| 7 | <input type="color" value="#3B82F6" |
| 8 | aria-label="Color selector" /> |
| 9 | |
| 10 | <!-- Manual hex input --> |
| 11 | <label for="hex-input">HEX</label> |
| 12 | <input type="text" id="hex-input" |
| 13 | value="#3B82F6" maxlength="7" /> |
| 14 | |
| 15 | <!-- RGB inputs --> |
| 16 | <label for="rgb-r">R</label> |
| 17 | <input type="number" id="rgb-r" min="0" max="255" /> |
| 18 | |
| 19 | <!-- CSS output --> |
| 20 | <code>rgb(59, 130, 246)</code> |
| 21 | </div> |
Color pickers must communicate color values to all users, not just sighted ones. Pair visual controls with text labels, keyboard support, and clear focus states.
- Use a real <input type="color"> as the underlying control so keyboard and screen-reader users can access the browser picker.
- Add aria-label to every color swatch button — color alone is not accessible.
- Show the current value as text (hex, RGB, or HSL) next to the preview so it can be read by a screen reader.
- Ensure focus indicators are visible on sliders, inputs, and swatches.
- Validate hex input and announce errors if the user enters an invalid format.
- Copy-to-clipboard buttons should provide visual and textual feedback (for example, "Copied" text).
info
warning
best practice
- Ensure sufficient contrast between the selected color and the preview text.
- For swatch grids, always include a neutral or black swatch for non-color defaults.
- Debounce rapid color changes when syncing with external previews to avoid layout thrashing.
- Persist the last selected color in local storage so users do not lose their choice on reload.
Community
Get help on Slack, Discord or VIP
Stuck on a guide? Join the community and ask.