In my experience CSS is the preferable selector because it can be concise, is well documented and web developers are likely to have more experience and exposure to it.
id, name, tag_name and class_name can all be easily reproduced with simple CSS so I would avoid explicitly using those.
e.g.
id ; #my_id
name; [name="my_name"]
tag_name; my_tag
class_name; .my_class
The use of XPath is often much maligned; labeled as slow and unstable. However I disagree with this view point.
When I interview people I cringe when they say they avoid Xpath because it is slow and brittle. The speed is no longer a concern, and xpath is only as brittle as the person who wrote it. However, I prefer the syntax of CSS Selectors so that is why I would choose over XPath for the majority of use cases.
There are 3 scenarios in which XPath is the better choice;
Multiple CSS Selectors may be replaced with one XPath query (e.g find element then iterate through sub elements can be performed in one xpath)
XPath can select based on Text where as CSS Selector cannot
XPath allows you walk up the DOM Tree which can be really useful if you can only identify a control by its child
I would always avoid selecting by text if possible, but if I had to, I would prefer to use XPath over the built in Link Text and Partial Link Text methods because the Xpath query woudl allow me to be more expressive and allow me to select more than just anchor tags.
Finally, once gotcha when using XPath is that "class" is treated as a literal string rather than an array of class names as supported in CSS selectors;
HTML: <div class="ab cd">
CSS matches: div.ab
CSS matches: div.cd
CSS matches: div.cd.ab
CSS matches: div.ab.cd
XPath matches: //div[@class="ab cd"]
XPath matches: //div[contains(@class, "ab")]
XPath matches: //div[contains(@class, "cd")]
XPath matches: //div[contains(@class, "ab") and contains(@class, "cd")]
XPath DOES NOT match: //div[@class="cd"]
XPath DOES NOT match: //div[@class="ab"]
XPath DOES NOT match: //div[@class="cd ab"]