I notice nobody answered the poster’s actual question, "Why can’t I put HTML inside a snippet?". I suppose it doesn’t matter as he seemed happy to have suggestions as to how he could accomplish what he wanted.
The reason is that the snippet tag [[snippetname-and-arguments]] is being replaced by the return value of the actual execution of the PHP code in the snippet, not by the PHP interpreter processing a file in the way it would if one surfed to a URL which was a PHP file. I have no idea how this is implemented (other than the snippets appear to be cached for execution), but that is what the documentation says happens.
It is also a stylistic guideline not to put HTML in a snippet. This makes sense, especially if creating snippets that one is going to share. After all, the snippet writer doesn’t know how the end users are going to want to mark-up the content. So the snippet should be generating content, not marked-up content. Part of the MODx documentation explicitly discusses this separation in terms of implementing templates (i.e. chunks used as templates) to be used by snippets.
Am I the only one in the dark? What are the functions: ob_start(), ob_get_contents() and ob_end_clean()