It is my understanding that while opaque triangles can be rendered in any order thanks to the Z buffer (especially when rendering in hardware), semitransparent triangles cannot. Instead, they need to be rendered from furthest to closest (from the camera's point of view) in order to get the correct result. If you render them in the wrong order, the result will be incorrect (and may even suddenly visually change if the rendering order changes as the camera moves).
Sorting polygons, even triangles, from furthest to closest is actually a difficult problem. In fact, in the general case it's an impossible problem (even with triangles) because in some pathological cases there is no unambiguous order in which they can be rendered correctly. For example, three triangles may overlap each other in a cyclic manner so that each one is partially in front of another (and thus it's impossible to render them without error, unless they are opaque and using a Z buffer, or without splitting at least one of the triangles). Using a naive sorting of triangles is very inefficient, especially if the need arises to split a triangle due to a cyclicity problem.
I know that there exist clever data containers that solve this exact problem and allow very quickly traversing the triangles from furthest to closest, regardless of where the camera is located, without the need to sort anything, and with any splitting of triangles already having been done in preprocessing. One example of such a data container (which name I can't remember now) is a binary tree where there's a triangle at each node which splits the entire space into two halves, with the rest of the triangles being on the left or right branches depending on which side of the plane defined by this triangle they are (and if a triangle intersects said plane, it's split in preprocessing into two using that plane). This binary tree allows traversing all the triangles from furthest to closest with a simple dot product (against the normal vector of the triangle) comparison at each node, regardless of where the camera is located.
While this construct is very clever, there's one problem with it: It only works with a completely static scene. The tree has to be precalculated (and triangles possibly split) as a preprocessing step (usually while building the project). Doing it at runtime on each frame would be madness.
But games use dynamic semi-transparent polygons all the time, for all kinds of particle effects etc. So how are they rendered properly?