The simplest way to do this that I can think of would be to pull (and compile, possibly) the two different commits into two different development environments then compare the parts of the interface effected by the commits.
You could take this a step further and automate the process, interfacing with a commit history and triggering using batch files or similar a set of operations that pulled two different given commits and set them up for review. This would be advisable if you were doing this often and would also mean the process could be put into the hands of someone less technical.
Taking the web as an example, as you do in your question (though the principles could well be applied to other development situations) with well written, modular css and views you could set things up to compile and display just the parts of the interface effected by the commit.
Another thing you could do would be use javascript to take commit hashes and add those as classes to html snippets / views where things had changed in order to mark them as changed. i.e. look at every view that has changed between two commits and add a class to every element in those views. You could cross reference the css or javascript to see what elements are targeted by the changes in those files and feed that back in to make the visual feedback richer, i.e. 'this element had an event bound' or 'this element had a class added'. This would help you focus in on the changes that had had an effect.
Merging would be done in the usual way, in the version control, once a prefered interface was selected.
You would benefit massively if your developers to be making very good commits, i.e. atomic, contained pieces of development rather than a days work, 10.6 tasks and a message like 'changes, sorry, I'm bad'. Commit messages would need to be very well written so you could see which part of the system to target with whatever method you used and tasks would need to be carefully distributed amongst developers so they could work efficiently on one thing then commit and push.
You would need to use branching too so that sets of commits could be more easily divided into the tasks that they represent as a whole. Then compare between the branch heads or the branch heads sequentially with the master head.
There's going to be some pretty sophisticated programming involved in making this work well, it's no mean feat, good luck!