'Using the THREE.js CSS2DRenderer to position HTML elements from the top left

The CSS2DRenderer allows me to place an HTML element in a scene based on a 3D position, which can in turn correspond to some object placed in the 3D scene. For example, I can do:

const mesh; // <some other mesh in the scene>

const el = document.createElement('div')
el.innerHTML = 'hello world'
const objectCSS = new CSS2DObject(el)
objectCSS.position.set(0, 0, 0)

mesh.add(objectCSS)

This will place the hello world div directly centered on the mesh, e.g.

_________________
|               |
|  hello world  |
|_______________|

How could I change the coordinates of the hello world div so that it is placed with respect to the top left of the div, instead of with respect to the center of the div? e.g.

 _________________
|               |
|       hello world  
|_______________|

EDIT: Note that the goal is not to just offset the text. I want to change the alignment. So for example, if I was just trying to offset, more text would look like like this:

_________________
|               |
|  hello world blah blah blah
|_______________|

wheres changing the alignment would look like this

_________________
|               |
|       hello world blah blah blah
|_______________|


Solution 1:[1]

I ended up being able to do this by utilizing a few nested div containers. My final code ended up looking something like this:

const mesh; // <some other mesh in the scene>

// Create the relevant html elements.
const el = document.createElement('div')
const container = documnet.createElement('div');
const inner = document.createElmeent('div');

// Add styling.
container.style.display = 'flex'
container.style.flexDirection = 'column'
container.style.width = 'fit-content'  // needed to 'reset' the width calculations

// Set the text.
inner.innerHTML = 'HELLO WORLD'

// Set the rest of the THREE object.
const objectCSS = new CSS2DObject(el)
objectCSS.position.set(0, 0, 0)
objectCSS.element.style.overflow = 'visible'
objectCSS.element.style.width = '1px'  // I dont know if this is strictly needed
objectCSS.element.style.height = '1px'

mesh.add(objectCSS)

Solution 2:[2]

If you set a position on objectCSS, it will apply as an offset from the mesh.

Try: objectCSS.position.set(10, 0, 0)

See this example for more details: https://threejs.org/examples/#css2d_label

Specifically on this line: https://github.com/mrdoob/three.js/blob/master/examples/css2d_label.html#L132

Solution 3:[3]

I've come across the same problem. Lines 131 or 135 in the CSS2DRenderer the the transform to translate(-50%,-50%) to center the html element around the given position. Probably the best fix would be to have some sort of control over this when creating the CSS2DObject, maybe passing an optional argument argument? It might be worth making a PR?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 theahura
Solution 2 Nicholas Ficara
Solution 3 bguiz