Salt passwords with the username? Salts should be unique so that an attacker can't brute force multiple passwords at once. However, since usernames are unique, wouldn't it be possible to use some representation of the username as a salt?

Of course that means that if a username changes, the password needs to be rehashed. I'm asking from a cryptographic perspective, not a user-experience perspective.
However, since usernames are unique [...]


But the same user is supposed to get a fresh salt when they change their password.  Salts are not supposed to be bound to usernames as you suggest; they're bound to states of individual password database entries.  If the attacker gets their hands on multiple password entries for the same user in your scenario, those entries will have the same salt and thus there is a work savings they can achieve. 

One practical illustration of this is to consider that many password storage APIs have been carefully designed to avoid salt misuse by factoring the process into these two operations:


Generate password token: Take a password as input and produce a password verification token as output.  This token incorporates:


A description of the algorithm that was used and any parameters required to rerun it;
A random salt (generated internally by the API operation);
The raw password hash output.

Verify password: Takes a password and a verification token as input, and outputs true if and only if the password checks out against the token.  Internally this:


Decodes the token to determine the algorithm, parameters, salt and raw hash;
Uses this information to select the password hashing algorithm and parameters;
Hashes the supplied password with those choices;
Compares the resulting raw hash to the one stored in the token.



When you use an API like this to manage your users' passwords, you call operation #1 not only when you enroll a new user, but also when an existing user changes their password.  Which means a new salt is implicitly generated afresh, and you can't make the mistake of reusing the same salt for the same user.



In addition, usernames are broadly predictable just like passwords are (or perhaps more so!).  Notably, an attacker can likely guess a bunch of your usernames even before they ever see your password database.  Which means that username salts are to some extent subject to precomputation attacks—if your scheme was broadly adopted, an attacker could conceivably precompute a rainbow table based on pairs of:


Common passwords (as is already well-known practice);
Usernames known to be common at large, or that have a high probability of being used among a small population of interest (e.g., a foreign adversary's influential politicians).


Which means that although password salts are nonsecret, they ideally should be unpredictable as well.  That sounds like an oxymoron at first, but what it means is that an attacker should not be able to guess what a password entry's salt might be before they actually see the entry.  Random salts trivially ace this test; usernames don't score well on that criterion, and neither do @cypherfox's "site identifiers" or counters, for that matter.