Is it possible to add a button into the scene?

Hi everyone!

I am wondering on how can I achieve this (see the blue button on the wall):

This is what I’ve achieved so far:

I am wondering if I can embed an HTML button into a mesh and just position it normally like any other mesh in the scene.

If not, what would be possible? I’m thinking positioning it absolutely won’t work for several reasons.

Any help would be greatly appreciated.


Collection of examples from
use transparentDOM - @trusktr

Maybe this will help
@Norman updated @Mugen87)

Hi hofk,

Thank you for your reply. I tried doing the same thing as the transparentDOM example, but this is the result (black rectangle, no eventlistener):

And my code:

    var wallRight = new WhiteWall( 10 , 10 ); //wall with text and button
wallRight.position.set( 2 , 4 , 4 );
wallRight.rotation.y -= Math.PI/2;

const button = makeElementObject('button', 0.7, 0.2)    
    button.css3dObject.element.textContent = "Click me!"
    button.css3dObject.element.addEventListener('click', () => alert('Button clicked!'))
    button.position.y = -3.44
    button.position.z = -0.49
    button.position.x = -2.7

Any idea on how to achieve/fix it?

Thanks a lot once again!

I think you should ask @trusktr :question:
I just collect the examples, but I have no deeper knowledge about the totality of all examples. :neutral_face:

There’s also an option to check UV coordinates of point of intersection, and if it’s in a predefined rectangle, then do some stuff. The hardest part here is to find coordinates of the predefined rectangle :slight_smile: You need 4 clicks for it with logging of uv coordinates though :slight_smile:

Take a look at this post: Sprite positioning in 3D scene - #8 by prisoner849

Do you have a working example to look at?

Did you remember to make the canvas have pointer-events:none so that the click will go behind the canvas element to the css3d element?

Thanks for your reply and sorry for such a delayed response…
this is the working example:
(all of my JS is in the JS editor).

Thanks a lot :slight_smile:

@shonsirsha Sorry for taking so long, but I got your button working. You needed to

  • make a CSS3DRenderer (not just WebGLRenderer)
  • then scale the sizing by 1000 (see why below)

Demo (click the button):

Search the code for cssRenderer to find the new parts, and take a look at each size or position number being 1000x bigger.

The reason the sizes must be bigger is because a DOM elements can not be smaller than 1 unit (CSS pixels), and your size was 0.7, 0.2. At that size, you can’t get precise DOM sizing. So by changing it to 700 and 200 the sizing works.

But I broke some stuff (now the text is far out from the wall) but you can take it from there. The button works!

But now you may want to tune the material for the css3d object mesh (the mesh returned from the makeElementObject function, to configure how transparent you want it to be, so that you can see the content of the button.

To learn how, I highly recommend studying this example:


I have included the examples in the Collection of examples from

You get an error in the console ( Button example, but it works ):
THREE.OrbitControls: “document” should not be used as the target “domElement”. Please use “renderer.domElement” instead.

I corrected it in the copy.

//var controls = new THREE.OrbitControls(camera, document); // error in console … Please use “renderer.domElement” instead.
var controls = new THREE.OrbitControls(camera, renderer.domElement); // changed hofk

Weird. :thinking:
Browser: With Firefox the click only works when I open the console.
With Chrome, Opera immediately.

Huh. Thanks for pointing that out.

It would be neat if your examples archive were filterable/searchable with a live input search field, with tags and descriptions.

That would certainly not be bad, but I can’t afford that at the moment. See the Discussion about this side link at the bottom of

It also takes time to read, especially since my English is still poor and I use a translator:2020-03-20 19.52.23

But maybe someone who has already done such a thing would like to add it? Then please contact me.

Let’s keep it on our wishlist. :slight_smile: