There are essentially three purposes for language semantics. Overall, as a smell test to guide language design: if you can't define a feature, it's probably bad. Second, to help other implementers of our language and programmers for the language -- unfortunately, I'd claim we generally fail on this point. Third, to help structure proofs about our language.
As part of the preparation for a paper submission, I'm finishing up my formalization of a subset of CSS 2.1 (blocks, inlines, inline-blocks, and floats) from last year. My first two, direct formalization approaches failed the smell test so Ras and I created a more orthogonal kernel language. It's small, and as the CSS spec is a scattered hodge-podge of prose and visual examples riddled with ambiguities, we phrase it as a total and deterministic attribute grammar that is easy to evaluate in parallel. Finally, to prove that it can be implemented efficiently (e.g., linear in the number of elements on a page, meaning no reflows), the grammar without floats leads to a syntactic proof, and the version with floats then only has to explain away some edge cases (using a single-assignment invariant, which can probably also be made syntactic).
All of this should have happened 10 years ago. However, the academic language design community, as per the norm, seems to have been late to the party. Instead, we have huge, slow interpreters that don't give the same answers and a generation of abused and confused artists and designers.