2

Reading SASS basic features on their website, I stumbled upon the @extend feature.

The example they give is the following:

.message {
    border: 1px solid #ccc;
    padding: 10px;
    color: #333;
}

.success {
    @extend .message;
    border-color: green;
}

.error {
    @extend .message;
    border-color: red;
}

.warning {
    @extend .message;
    border-color: yellow;
}

That compiles to

.message, .success, .error, .warning {
    border: 1px solid #cccccc;
    padding: 10px;
    color: #333;
}

.success {
    border-color: green;
}

.error {
    border-color: red;
}

.warning {
    border-color: yellow;
}

Thus with this snippet of HTML

<div class="success">hello world</div>

you style your element with properties of .message and .success. However I feel this way of writing HTML (and CSS) very poor, in terms of semantic (you don't explicitly see from the markup above that the element has also the styling of .message).

Shouldn't the snippet above be

<div class="message success">hello world</div>

?

I feel it to be more descriptive, and more easily reusable. For example I could assign the .success class (as written in the above CSS but without the @extend) to other elements which are not messages, and so using the class as a modifier, in a BEM-fashion.

So my question is, is the SASS example approach more desiderable than mine?

4

Both approaches are valuable and semantically, they are not very different. Remember that you also can use both in Sass.

I believe that what makes you think that yours is more descriptive is their choice of class names: success class is not descriptive enough: how would anyone guess that success refers to a message, and not, say, a small green check icon on the side of an item showing whether a unit test passed? If we chose a (meaningless) example with better names, things become clearer:

.animal { ... }
.cat { @extend .animal; ... }
.dog { @extend .animal; ... }

Would you rather write:

<div class="animal cat">...</div>

or:

<div class="cat">...</div>

Probably the second variant, since it avoids redundancy and makes your HTML more readable.

If you know object oriented programming, think of:

  • Their approach as inheritance: Cat class inherits Animal, and can have only zero or one base classes.

  • Your approach as interfaces: ISuccessful interface can be implemented by both Message class and TestResult; at the same time, Message can implement at the same time ISuccessful, IImportant and IMandatory.

  • Yes, there are cases where the "single class" approach isn't worse, or is even better as the one you reported, but in CSS I saw more often the other case, hence my question. – mattecapu Aug 3 '14 at 13:05
  • I see only now your edit, that's a very good point. But isn't the interface approach more broadly used as it permits to add functionalities more easily? (I'm actually quite ignorant in this field, so I'm not really trying to protect my position) – mattecapu Aug 3 '14 at 13:08
  • 1
    @mattecapu: from my experience, your approach is used indeed more frequently in CSS. – Arseni Mourzenko Aug 3 '14 at 13:13
  • @mattecapu It's probably more frequent because it's more flexible. With the "clearer" animal-based example, if you have interactivity with javascript, you'll either have to select all types of animals or go back and add the animal class to the elements. It also distinguishes between ambiguities in English - for example, is it "bat" or "bat"? – Izkata Aug 3 '14 at 23:54
  • @Izkata yes these are other benefits of that kind of approach, I didn't think about it – mattecapu Aug 4 '14 at 8:45
-1

Coming back a year later, I now support the exactly opposite view: @extend is usually better than filling your markup with classes.

Let's take for example this code

.component1 {
   font-family: 'custom font', sans-serif;
   text-transform: capitalize;
   border: 2px dashed red;
}
.component2 {
   font-family: 'custom font', sans-serif;
   text-transform: capitalize;
   text-align: center;
   padding: 10px;
}

<div class="component1"></div>
<div class="component2"></div>

I notice component1 and component2 share a common style, that could potentially be used in other components as well: it's a good candidate for a separate class (by the DRY principle),

.utility1 {
   font-family: 'custom font', sans-serif;
   text-transform: capitalize;
}
.component1 {
   border: 2px dashed red;
}
.component2 {
   padding: 10px;
}


<div class="component1 utility1"></div>
<div class="component2 utility1"></div>

But this code brings at least 2 new problems in town:

  1. If I'm coding sensically, component1 and component2 styles will live in different stylesheets. This means that by looking at component1.css, I can see all the styles that are going to be applied to the component, except this is not the case anymore: utility1, which will probably reside is a separate stylesheet, changes the styles of the component without any explicit reference to it in the component own stylesheet.
    Another way to see this is that you are not tying the utility1 styles to component1, but you leave them as separate entities that could as well live separately, yet this is a false assumption because component1 needs always those styles, and can't live without (it's not a state like a modifier class, it's part of its very own visual nature).

  2. Even worse, this reference is moved into the markup.
    In the question, I talk about semantics, but while in the case of a modifier class (i.e. --active, --hidden, --warning/--error/--success), an extra class in the markup will actually provide additional semantic information on the component, it isn't the case here. utility1 is a purely styling hook, and styling has no place in the page markup except for stylesheets declarations in the <head> section. Putting utility1 in the component markup is no different from styling things from the style attribute. You're relying on markup code to change the visual styles of your components, and that's no good.

I understand these views are not absolutely shared or right (there is not such a thing as an absolute truth in coding, yet we can agree on some general principles), because there are school of thought that sees styling from markup as completely legit.

  • why the downvote? – mattecapu Nov 11 '15 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.