#chris-eppstein

position:unique

Sass Language Design: Philosophy & Approach

By Chris Eppstein & Natalie Weizenbaum

Sass has a lot of language features that CSS does not provide. To
the outside observer, the way new features come into existence
might seem like a bit of mystery. It’s become clear recently
that we need to do a better job of explaining it.

First, there’s no formal process for how we decide to add new features to
Sass. Good ideas can come from anyone from anywhere and we’re happy to
consider them from the mailing list, IRC, twitter, blog posts, other css
compilers, or any other source. However, most of the time we end up saying
no.

In this post, we hope to describe the thought process we go through to make
those decisions. In future posts, Natalie and I will cover some
often-requested features and why we’ve decided against them.

Personas

There are four personas who we consider when thinking about new Sass features:

Beginning Front-Ender

Knows CSS syntax, but is confused and frustrated by the nuances of
building cross-browser websites. Often bases their stylesheets
using a core from a blog post or CSS framework. Maybe a programmer
who has to do CSS for one reason or another.

Knowledgeable Front-Ender

Has a strong working knowledge of CSS. Gets the job done,
but still gets frustrated when the styling for a site gets large and complex.
Reads blog posts about CSS, but probably doesn’t write them.

Expert Front-Ender

Lives and breathes CSS. Knows what to avoid and has most of
quirksmode memorized.
Has read several books on stylesheets. Can create novel designs
and implementations that inspire others.

Extension/Framework Builder

Sees patterns in their work and wants to share them
with others. Likely to have some programming skill.
May overlap with other personas to varying degrees.

We’ve come up with these personas by talking to people who write CSS.
We include as wide a sample as possible.
We talk to people who love Sass, people who dislike it,
people who are new to it and ask for help on the mailing list,
and even people who have never heard of it.

We’re primarily focused on supporting the knowledgeable front-ender,
because that’s the largest group of users. For them, we want features
that are frequently useful, and that don’t require exceptionally deep
knowledge of CSS or Sass to use. Our secondary focus is
making it easy for a beginner to get started using Sass, and to create
cross-browser designs with very little effort.

Only once we’re confident that these two personas are well-served are
we willing to add advanced features for the expert front-ender and the
extension builder. This means that features that are very complex,
that require advanced knowledge of CSS or Sass, or that require
advanced programming ability, usually don’t make it in.

The Gauntlet

Any new feature proposal must run the gauntlet, and be able to stand
up against a series of difficult questions. Following is a list of
some of these questions. It’s not comprehensive and we don’t
explicitly check each one off, but it’s a good summary of our thought
process when evaluating a new feature.

What problem does the feature solve? Any new feature must solve
a real problem that can be clearly explained. The more common the
problem, the more awesome the feature and Awesome is Sass’s middle
name.

Does this problem have another solution? If an existing solution
exists then we’d prefer to keep things as they are. But this does
not mean that the feature is rejected, instead it must bring
substantial benefit. This is often the case for those features
that make a very common task easier. The ability to nest
selectors is a good example of a feature that optimizes something
that is very simple to do, but that happens a lot, resulting in a
large cumulative benefit.

How does the feature interact with the other Sass features? Are
there cases where the feature would introduce confusion? Features that
work well with existing features are more likely to be accepted. Can
the interaction of with another feature be reasoned about easily? Will
it generate the expected result for a Sass user who understands both
features individually? For instance, if a user understands both the
parent selector (&) and mixins, when she sees the & used at the top
level of a mixin, she’ll understand that it refers to the selector that
includes the mixin.

Will the user understand the feature intuitively? Ideally, a new feature
would be so obvious it wouldn’t need any explanation at all.
Unfortunately, this can’t always be the case. If it does need to be
learned, how hard is it? Can it be explained to even the beginning
front-ender in one or two sentences? Variables pass this test with
flying colors – when a new user sees them, they know what’s going on
right away. Mixins usually aren’t that obvious, but they require very
little explanation to be clear.

Does the feature make a stylesheet harder to maintain? When a
feature would create a situation where a change in one place in the
stylesheet causes unexpected changes elsewhere, it’s unlikely to be
accepted. Many features found in other CSS preprocessors fail this
test, and it is our primary reason for rejecting them in Sass. Usually
we consider this question in the context of a team of designers working
on one stylesheet, or one person picking up a stylesheet that hasn’t
been touched in months and changing it without fear.

Does the feature make something new possible?
This question is structural in nature: of course, Sass can’t add
anything that’s impossible in CSS. But the @extend directive and
numeric expressions are great examples where features allow the
expression of a relationship that exists in practice but that couldn’t
be expressed in a stylesheet before.

Will the feature be misused? Sass’s philosophy leans towards
giving power to advanced users, but there are cases
where a powerful feature is likely to be misused by a beginning user.
Unless it provides enough benefit to warrant inclusion anyway,
it’s likely to be rejected.

For Example

A common request that we get for sass is to allow @import to import an entire
folder of sass files with one call using some sort of globbing syntax. This
feature has been rejected and you can view the feature request for
it if you like.

Does it solve a problem? Yes, this feature solves a common problem of
having to create a top level import file and then specify each imported file
explicitly. This saves time because the person adding a new stylesheet doesn’t
have to worry about adding it to their master stylesheet.

Does it have an existing solution? Sort-of. The import directive can accept
more than one stylesheet separated by commas.

Does it interact well with existing features? It has no positive or
negative impact.

Will the user understand it intuitively? Yes. We think it is not hard to
understand this feature and most users will grok it immediately or can learn
it in a few minutes of research.

Does the feature make a stylesheet harder to maintain? This feature would
make stylesheets easier to maintain in some respects: Less files changed when
adding a new one, less time spent figuring out that you forgot to import it.
But it will also make some stylesheets harder to maintain: Adding a new file
might import into a point of the cascade that causes styles to apply in an
unexpected way – fixing this requires reverting to the current import
mechanism and debugging it might take a while to understand.

Does the feature make something possible that wasn’t possible before? Yes.

Will the feature be misused? Yes. This feature is best used when following
certain best practices like having scoped stylesheets or importing library
files that don’t themselves define any selectors, but there’s no good way to
enforce this, thus leaving the the feature open to misuse by users who think
they are saving time only to lose all those savings and then some when it
fails for them.

Is it CSS-y? Yes. Presumably the syntax for such a feature would use * to
glob imports and * means any element in a selector so it has some
familiarity.

Clearly this feature was a mixed bag. It benefits some users but it also
discourages other users from thinking through an important aspect of CSS:
Where does a partial belong in the cascade. If the feature offered a greater
benefit to the power users, it might have been approved but files are added
rarely and the error scenarios around forgetting to add an import are much
easier to diagnose than the error scenarios around breaking the cascade. At
the end of the day, we said no to this feature because it had more downsides
than upsides in a “weighted average” sense.

We’re not perfect

We understand that reasonable people might come to different conclusions
when they evaluate features against these criteria. Many of them can be
influenced by one’s past experiences and their mindset. In this respect,
it’s good that there are other stylesheet compilers making different decisions
about what features should exist and what features shouldn’t. It allows for
experimentation and learning.

At the end of the day, someone has to make a decision about whether a proposed
feature is in or out. In almost all cases, Natalie and I come to an agreement
– sometimes this takes minutes, sometimes it takes weeks or more. But open
source software is generally governed by a benevolent dictatorship
and for at least a couple years now that person has been Natalie. I’ve found
her to be increasingly good at this role. She’s eager to hear new ideas,
and careful in her consideration. With a well crafted argument, it is very
possible to change her (and my) mind.

About Me

I am an open source hacker and stylesheet architect at LinkedIn.
I live in San Jose, California with my wife and daughter.

Open Source

I'm the creator of Compass, a stylesheet authoring framework
and I'm on the core team of
Sass — the stylesheet syntax upon which Compass is built.
I maintain about a dozen less well known ruby libraries and rails plugins on
github,
and am an active contributor of patches to the many open source projects that I use.