How to add mose events to <Html/>

I am using Drei’s Html component to create some objects in my scene, such as the following code snippet. However none of the mouse events work. Is there sometihng I am missing? Is it possible to have mouse events on a Html component and, if not, is there a workaround ?

    onClick={(a) => console.log('click')} //these dont work
    onPointerDown={(a) => console.log('mouse down') // these dont work
    <span style={{
        backgroundColor: 'red', 
        display: 'inline-block', 
        width: '100px', 
        height: '100px',
        borderRadius: '50%'

Yes - the way you’re doing it is correct. Is there something else that’s affecting user input, besides this component? OrbitControls? CSS styling of pointer events? Some transparent fullscreen overlay that may be covering the html element?

I do use OrbitControls, but not the others you mentioned, no overlays nor CSS styling. I don’t know if this is useful or not, but if I replace the with something like or then the mouse events work fine.

you are still in the threejs reconciler with the drei <Html> components, so all events go against geometry. <Html> is a portal into react-dom, it has no threejs geometry, events on it will do nothing. instead put them on the span, the actual html, and you’ll have regular react-dom events since everything inside <Html> is being rendered by react-dom.

<Html center>
    onClick={(a) => console.log('click')} 
    onPointerDown={(a) => console.log('mouse down')
    style={{ ...

btw, in order for both html and canvas to receive events according to the dom api both the canvas and the html elements must share the same parent. otherwise either the canvas will take events away from the html, or html from the canvas. fiber makes this easy:

example using drei/html
example using canvas + regular html

<Canvas eventSource={document.getElementById('root')} eventPrefix="client">

the prefix tells it which events to use. offsetX/Y or clientX/Y, screen etc. each even type works differently but that’s all just the dom api.


ps, there’s a library on pmndrs now that can render html/css/tailwind into threejs, as instanced meshes and glyphs, so you don’t have to use clunky html on top of the canvas no more. the ui is an actual part of the scene with this: GitHub - pmndrs/uikit: 🎨 user interfaces for react-three-fiber

even a html → uikit converter
and one for figma → uikit for good measure

1 Like

Thank you so much for the help and thorough explanation! That fixed the problem!