Most explanations frame ERC-20, ERC-721, and ERC-1155 as "fungible, non-fungible, and multi" — which is true but unhelpful. The deeper distinction is how each standard models ownership in contract storage.
ERC-20 stores a single mapping: address → uint256. One balance per address. The token ID is the contract address itself. Every unit is interchangeable because there is nothing to differentiate them — no metadata pointer, no index.
ERC-721 stores two core mappings: tokenId → owner (address) and owner → tokenCount (uint256). Each token is an entry in the first mapping. Enumeration (ERC-721Enumerable) adds a third mapping — tokenId → index — which is where gas costs explode on large collections.
ERC-1155 collapses both models into a nested mapping: tokenId → address → uint256. This is the key insight: ERC-1155 doesn't "support both fungible and non-fungible." It supports arbitrary balances per (id, address) pair. Whether a given id is fungible or non-fungible is an application-layer convention — the contract doesn't enforce it. You can mint 10 billion units of id 1 and exactly 1 unit of id 2. The standard is agnostic.
This storage difference drives every downstream trade-off in gas, composability, and indexing.