Split-complementary

분할 보색

A base hue plus the two hues flanking its complement (±30°) — nearly as bold as a straight complement, but easier to live with.

Also known as: Split complement
···
html
<div class="wrap">
  <div class="wheel" id="wheel"><div class="marker" id="m0"></div><div class="marker" id="m1"></div><div class="marker" id="m2"></div></div>
  <div class="swatches" id="sws"></div>
</div>
css
.wrap{display:grid;grid-template-columns:auto 1fr;gap:clamp(14px,4vmin,28px);align-items:center;width:min(560px,94%)}
.wheel{position:relative;width:clamp(100px,32vmin,190px);height:clamp(100px,32vmin,190px);border-radius:50%;cursor:grab;touch-action:none;
  background:conic-gradient(hsl(0 80% 55%),hsl(60 80% 55%),hsl(120 80% 55%),hsl(180 80% 55%),hsl(240 80% 55%),hsl(300 80% 55%),hsl(360 80% 55%));
  box-shadow:0 0 0 1px var(--line),0 10px 26px rgba(0,0,0,.18)}
.marker{position:absolute;width:18%;height:18%;min-width:14px;min-height:14px;border-radius:50%;background:#fff;border:3px solid var(--fg);transform:translate(-50%,-50%);box-shadow:0 2px 6px rgba(0,0,0,.35)}
.marker.base{width:22%;height:22%}
.swatches{display:grid;gap:8px}
.sw{height:clamp(24px,5.6vmin,34px);border-radius:8px;border:1px solid var(--line);display:flex;align-items:center;padding:0 10px;font:700 clamp(10px,2.6vmin,12px)/1 ui-monospace,monospace;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.4)}
js
const OFFSETS = [0, 150, 210];
const wheel = document.getElementById('wheel');
const markers = OFFSETS.map((_, i) => document.getElementById('m' + i));
markers[0].classList.add('base');
const sws = document.getElementById('sws');
sws.innerHTML = OFFSETS.map((_, i) => '<div class="sw" id="s' + i + '"></div>').join('');
const swatchEls = OFFSETS.map((_, i) => document.getElementById('s' + i));

let base = 260, autoRotate = true;
function place(hue, el, R) {
  const rad = hue * Math.PI / 180;
  el.style.left = (50 + R * Math.sin(rad)) + '%';
  el.style.top = (50 - R * Math.cos(rad)) + '%';
}
function render() {
  OFFSETS.forEach((off, i) => {
    const h = (base + off + 360) % 360;
    place(h, markers[i], 41);
    const c = 'hsl(' + h + ', 76%, 53%)';
    markers[i].style.background = c;
    swatchEls[i].style.background = c;
    swatchEls[i].textContent = Math.round(h) + '°';
  });
}
function angleFromEvent(e) {
  const r = wheel.getBoundingClientRect();
  const cx = r.left + r.width / 2, cy = r.top + r.height / 2;
  const deg = Math.atan2(e.clientX - cx, -(e.clientY - cy)) * 180 / Math.PI;
  return (deg + 360) % 360;
}
wheel.addEventListener('pointerdown', e => { autoRotate = false; wheel.setPointerCapture(e.pointerId); base = angleFromEvent(e); render(); });
wheel.addEventListener('pointermove', e => { if (e.buttons) { base = angleFromEvent(e); render(); } });

(function tick() {
  if (autoRotate) base = (base + 0.3) % 360;
  render();
  requestAnimationFrame(tick);
})();

Keep the base hue, but instead of the exact complement (180°) use the two hues on either side of it — 150° and 210°. Plotted on the wheel, the three points form an isosceles triangle.

You keep the punch of a complementary pair while giving yourself more room to balance the composition than a single opposite hue allows. It's often recommended as the easiest harmony for beginners to get right.

Use the base hue as the dominant color and split the other two across different roles — one for the button, one for a tag — to keep the hierarchy clear.

When to use

Reach for this when you want complementary-level contrast without it feeling too loud.