In those cases, you’ll probably want to use separate nodes. Tag the intersection with highway=traffic_signals, and then tag a separate node at the actual location of the crossing(s) with the relevant crossing tags.

The crossing=* tag is meant to add detail to an object already tagged with highway=crossing or railway=crossing. Many data consumers are unlikely to look only at the crossing=* tag on its own. They’ll look for highway=crossing first, and only then use crossing=* to further improve things. Without highway=crossing, you’ve effectively omitted the crossing entirely.