Your first example:
<button class="button main center">Submit</button>
is wrong:
button
class is repeating the element itself. Do you have a class="p"
for every paragraph, and a class="li"
for every list item? What's the point?
main
is particularly unclear. Just by looking at the CSS, how would you be able to determine what's main
is referring to?
center
is a wrong name for a class: center
is a value, not a class name. Imagine you want your hyperlinks to be green. Would you do:
a {
color: green;
}
or you'll create:
.green {
color: green;
}
and then add class="green"
to all your links, and then learn that the customer wants the links to be shown in orange now?
Consider a slightly improved example of a button which cancels an operation while being highlighted for some reason and shows an icon near the text. Should you do this:
<button class="cancel highlighted with-icon">Cancel</button>
or be more specific?
<button class="cancel-highlighted-with-icon">Cancel</button>
It all comes to how styles are used. For instance:
- Would it make sense to highlight buttons which are not cancel buttons?
- Is there an icon option for buttons which are not cancel buttons?
The first question would probably receive a positive answer, and the highlight style will probably be the same for any other type of button—submit button, ordinary button, save button, delete button—you name it. Therefore, it makes sense to keep a separate .highlighted
style. To prevent collisions, it may be scoped to buttons: button.highlighted
.
The second question, on the other hand, is less obvious. While submit buttons and save buttons and delete buttons could all have an icon, it might be that their style would be different every time; if all the style contains is the background-image
property, by using with-icon
class, you'll still have code duplication:
.cancel {
border: ...; border-radius: ...; padding: ...; }
.cancel.with-icon {
background-image: ...; }
.save {
border: ...; border-radius: ...; padding: ...; }
.save.with-icon {
background-image: ...; }
...
However, what are the alternatives? Let's say you end up combining cancel
class with with-icon
. Now you have:
.cancel {
border: ...; border-radius: ...; padding: ...; }
.cancel-with-icon {
border: ...; border-radius: ...; padding: ...; background-image: ...; }
.save {
border: ...; border-radius: ...; padding: ...; }
.save-with-icon {
border: ...; border-radius: ...; padding: ...; background-image: ...; }
with huge code duplication.
If this alone is not enough, there is another reason to keep with-icon
separate. If you need to toggle icons on and off on the buttons, you can do it in a single method through jQuery if with-icon
is an actual class. Otherwise, you'll be forced to create a map between cancel
and cancel-with-icon
, save
and save-with-icon
, and change those classes, which, while technically feasible, requires more code.