When you are building a transaction, you can hand pick the inputs and outputs you want to use. There are no constraints or limits. CoinJoin effectively allows you to collude with multiple parties when generating a transaction (take multiple inputs {see:unspent outputs} from the different parties), such that it is difficult to follow the coins to their respective outputs.
Gmaxwell says it better than I:
>The signatures, one per input, inside a transaction are completely independent of each other. This means that it's possible for Bitcoin users to agree on a set of inputs to spend, and a set of outputs to pay to, and then to individually and separately sign a transaction and later merge their signatures. The transaction is not valid and won't be accepted by the network until all signatures are provided, and no one will sign a transaction which is not to their liking.[1]
Well there would need to be a server/host to manage all the signatures, but it could be built into a client. There is one implementation I know of so far: https://github.com/calafou/coinjoin
I wouldn't recommend using it, not sure if it's complete or not.