Why do I have to change the Z position of the camera with different canvas sizes to get things to fit?

I have a scene with playing cards. Each card is a cube made from MeshBasicMaterial surfaces. The cube dimensions are X, X/10, and X, to emulate the look of a card that has a large front and back, but 4 thin faces in the Z direction. To make it look like the “playing table” is flat, I set the camera Y rotation to 0 and then I flip each cube 90 degrees on its X axis to face the camera. The camera position is set to (0, 0, Z).

The problem is, I have to tweak the camera’s Z position a lot for each canvas size. I do force the camera aspect ratio to be 4:3. But though I use the exact same initial Z value for the camera when initializing the ThreeJS scene, some canvas sizes end up with the camera so close that the scene clips and you can only see a few cards, other canvas sizes result in the cards looking really small and far away but without clipping.

Note by clipping I don’t mean clipping due to the near or far planes of the camera. I mean clipping along the edges of the viewport so that when it happens, some of the cards or parts of some cards are beyond the edge of the viewport.

I have this same problem with the perspective camera, regardless of the FOV I use, or the orthographic camera. Why does this happen and is there a way to make things so the card always appear to be the same size and are not clipped by the viewport, regardless of the size of the ThreeJS canvas?