Gaze hover

게이즈 호버

The element your eyes land on highlights automatically — the eye-tracking equivalent of mouse hover.

Also known as: Eye tracking hoverLook-to-highlight
···
html
<div class="row">
  <button class="gb" id="b0">Play</button>
  <button class="gb" id="b1">Save</button>
  <button class="gb" id="b2">Share</button>
</div><div class="dot" id="gd"></div>
css
.dot{position:absolute;width:16px;height:16px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 7px color-mix(in srgb,var(--accent) 22%,transparent);pointer-events:none;
  transform:translate(-50%,-50%);transition:left .5s cubic-bezier(.3,.8,.3,1),top .5s cubic-bezier(.3,.8,.3,1)}
body{background:radial-gradient(circle at 50% 30%,#1c2440,#0b0d18 70%)}
.row{position:absolute;inset:0;display:flex;gap:clamp(10px,3vmin,20px);align-items:center;justify-content:center}
.gb{padding:clamp(10px,3vmin,16px) clamp(16px,4vmin,26px);border-radius:999px;border:1px solid rgba(255,255,255,.16);
  background:rgba(255,255,255,.06);color:#cfd2e6;font-weight:700;font-size:clamp(11px,3vmin,14px);
  transition:transform .35s,background .35s,color .35s,box-shadow .35s}
.gb.focus{background:var(--accent);color:#fff;transform:scale(1.1);box-shadow:0 0 0 8px color-mix(in srgb,var(--accent) 20%,transparent)}
js
const btns=[...document.querySelectorAll('.gb')];
const dot=document.getElementById('gd');
let i=0;
function place(){
  const r=btns[i].getBoundingClientRect();
  dot.style.left=(r.left+r.width/2)+'px'; dot.style.top=(r.top-10)+'px';
  btns.forEach((b,j)=>b.classList.toggle('focus',j===i));
}
place();
setInterval(()=>{ i=(i+1)%btns.length; place(); },1500);

On a headset without a mouse, where your eyes land is the pointer. Rest your gaze on a button and it lights up or grows slightly to signal "this is selectable" — that’s gaze hover.

One rule matters here: gaze alone never triggers an action. Eyes keep moving just from scanning a screen, so firing an action on everything you look at would fire constantly on things you didn’t mean to pick (known as the "Midas touch problem"). So gaze only shows a hover state; committing to it needs a separate gesture — a finger pinch, a controller button.

The demo moves like a wandering gaze between three buttons, lighting up only the one it currently rests on. In a real app this highlight has to pair with a pinch to become a complete interaction.

When to use

Always pair it with a pinch or controller click. A UI that executes on gaze alone will misfire the moment someone just looks around.