This is by no means a 100% correct article about CSS performance (there are many outside in the web already from people being far more competent in this field), but it should provide you with a quick outline of best practices.
With the rise of HTML5 and the concomitant increase of available (semantic) tags the temptation of writing CSS like
header > nav li { ...
instead of the (unsemantic?)
.nav-item { ...
emerged. After all, that’s what CSS (Cascading Style Sheets) is about, isn’t it? Well, sadly CSS should not be written “cascadingly” performance-wise. (See Google Developers for a thorough explanation), instead we should stick to our beloved classes. So if you see something like
<nav class="nav">
the author (most probably) did not just change his old div-soup-markup into some HTML5 elements in order to proudly state he uses the latest technology (of course he didn’t, we are humanists after all, aren’t we?) he just wanted to gain performance (the more specific a selector is, the better it is performance-wise).
Another benefit that arises when using some extra-markup is that your site is kept flexible – you don’t have to worry about your entire CSS when moving the navigation to another place.
Another question that I bothered myself with when HTML5 emerged was: Can I use those unsemantic divs? At first I flinched from using them anymore – as a result I pushed CSS’s pseudo elements :before and :after (and some more) to its limits (See Chris Coyier’s collection of tremendously useful fields of application) and learned pretty much about CSS. What I didn’t notice at that moment was that I switched from one unsemantic workaround (adding empty <span> elements to style an element/…) to another (abusing pseudo elements and radio buttons for behavior that should be controlled by JS).
It’s up to you to decide what’s worse (probably you are of the opinion that the CSS hacks are ultra-semantic, because they don’t need any extra markup, I don’t know (I, personally, am of the opinion that CSS should be used for styling purposes only)) and as I learned incredibly much when picking up CSS hacks I would not like to miss them – but after all I just switched from one workaround (a little bit harder to maintain, because older workarounds contain out of HTML and CSS) to another that is more complicated to code and what’s most important: These workarounds do not work in every browser.
Bearing all this in mind, I came to the conclusion to strike a balance – if possible use CSS hacks to keep HTML tidy, but if cross-browser-compatibility suffers or if it gets too costly in terms of labour I’ll switch back to HTML workarounds using divs. After all, the divs official purpose is defined as follows:
The div element has no special meaning at all. It represents its children. It can be used with the class, lang, and title attributes to mark up semantics common to a group of consecutive elements.
or as html5doctor concluded:
You should use
<div>when there is no other more semantically appropriate element that suits your purpose. Its most common use will likely be for stylistic purposes — i.e., wrapping some semantically marked-up content in a CSS-styled container. (full article: http://html5doctor.com/you-can-still-use-div/)
This being said I would like to encourage you to use the div again instead of making your life unpleasant by desperately trying to only use 100% semantic tags. After all, divs are not that unsemantic even if you use them for styling purposes only!