
CSS Architecture - twog
http://engineering.appfolio.com/2012/11/16/css-architecture/
======
bbx
Interesting article that summarizes quite well the criticism aimed at CSS you
come across periodically on the web.

The way CSS is written amongst the web developers and designers depends on
whether you have easy access to the HTML or not.

If I work on a Tumblr or WordPress theme, I can strip down my HTML structure
to the minimal and work my way around with _context_ selectors (for example
having global styles for my .post-title, and add specific adjustments for
#sidebar .post-title or #single .post-title).

But if I need to send HTML/CSS templates to a client's developers, I will need
to turn my components into reusable and _independent_ objects (like in a
Bootstrap file), that will carry their style while being moved around to
prevent them from being altered by the context in which they end up. I would
also increase the density of my HTML to cover for all the possible cases, and
give the developers some flexibility.

As a front-end developer only working on HTML and CSS, keeping content and
style completely seperate is the goal I aim for everytime I start a new
project. But maintaining such a division is hard when working with developers
because they generally don't touch the CSS at all. So I need to provide
styling directly into the HTML because that's what developers generate and
have their hands on. I don't blame the working process for making me write a
different kind of CSS. It's just how it has to be done. Neither type of CSS is
better than the other: they are just suited for 2 different situations.

And that's why I don't believe there is a perfect way to write CSS. There are
useful tricks and smart shortcuts but, although having been a dedicated front-
ender for 4 years with no programming skills, I don't think CSS is meant to be
discussed too thoroughly.

------
bretthopper
The best point in this article is that you need to take your CSS seriously and
treat it as an equal to any other piece of code. A common practice in
companies is to rigorously code review application code while basically giving
CSS a pass.

Obviously your CSS might be less important than core business logic, but just
ignoring any sort of practices will make developing new features take longer
and less efficiently. It will also come back to haunt you at some point.

A key metric of any company is how fast you can develop new features while
keeping quality, consistency and reliability. Following good CSS practices
will only help out that cause.

~~~
mattacular
In terms of developer time spent, working out thoughtfully organized and tidy
stylesheets up front can save a lot in the long term (just like with any other
part of the codebase). Maintaining and adding to stylesheets is difficult:
they almost always (and quickly) devolve into the CSS equivalent of spaghetti
code, especially on teams where you have multiple people working on them. The
'easy/fast' approach at that point is to just create a new style rule and re-
class the majority of the elements you're trying to affect and it is just a
vicious cycle.

------
csomar
I don't agree with some points. For example, he mentions this to be a good
practice

    
    
      /* Bad */
      .widget { }
      #sidebar .widget { }
    
      /* Good */
      .widget { }
      .widget-sidebar { }
    

In my opinion, it's _best_ to use a "sidebar" class for the widget.

    
    
      .widget { }
      .widget.sidebar { }
    

Now, you might be worried that the "sidebar" class affects the widget in
unwanted ways. Well, it shouldn't. That class should have generic/basic
styling that anything in the sidebar should have.

Maybe you want to have special font styling for things in the sidebar. The
".widget.sidebar" is a special selector for a widget in the sidebar. You can
also have the following

    
    
      .separator 
      .separator.sidebar 
      .separator.footer
    

That makes elements easier to maintain and debug. Well, just my opinion.

~~~
philipwalton
There are a few reasons I prefer the namespaced modifier approach to what
you've described:

1) This approach is more error prone and less predictable. For a one-man job
it's probably OK, but on a team it's harder to guarantee someone else isn't
going to apply some styles to `.sidebar`, which will cause unwanted styles to
be applied to your separator component. The namespaced approach is very
intentional, so it's unlikely someone will add styles to that rule without
knowing exactly what they're affecting.

2) chaining like this ups the specificity of the CSS rule, which means your
other modifier/presenter classes might not work on the element anymore. In CSS
specificity is everything, and keeping it nice and low is usually preferable.

~~~
gibbitz
Yeah but if my .widget-title rule refers to the title inside the widget
.widget-sidebar seems like it should also be inside the widget, not a widget
inside a sidebar. I appreciate the idea of predictable results but I find
placing a widget in the sidebar styling it differently based on decendant
selectors far more predictable than somehow guessing that I have to add
another class to it. I'm less likely to research a site for a class I'm
unaware of as an unknown unknown.That could be a deep rabbit hole. I see
decendant selectors as the best practice here. If the problem is with sidebars
being everywhere, make your selectors more specific for them. I found most of
this article promoting magic markup. There's a logical conclusion to that
approach which is creating a sass-like system to write embedded and inline
styles. It would surely reduce http requests and remove cross site CSS bugs.
;)

------
markdown
Looks like he just rewrote the ideas of [Nicole
Sullivan](<http://stubbornella.org>) and [Harry
Roberts](<http://csswizardry.com>).

~~~
bmuon
I'd say it's Nicole's OOCSS with extra annotations like -- and __.

It's also worth noting that this makes a lot of sense when you think about it,
but from thought to application there is a big gap and it's not an easy one to
cover. It takes a lot of time to incorporate it and it's really hard to get
right.

~~~
markdown
Agreed. In my opinion, the vast majority of websites don't need it.

OOCSS is most useful on massive websites.

------
jdwissler
Kind of a side issue to the article.

CSSLint is useful, at least for me. The only problem is I find myself
disabling a lot of rules.

There are certain rules that _would_ be useful if you could easily specify
their parameters. For example, there is a rule that says that you can only
have 10 font-size declarations in your CSS sheet, which is completely and
utterly arbitrary. What if I need 11? Or what if I ONLY want 3? It would be
useful if I could specify that. In fact I should be able to do that for any
property.

Developers need to be able to enforce standards in their JS, CSS and even
HTML. The fact, however, is that certain standards aren't ubiquitous across
every webpage, and need to be set by the developer.

~~~
philipwalton
I was going to point you to this Github issue, but then I realized I'd be
linking you to yourself :)

<https://github.com/stubbornella/csslint/issues/380>

~~~
jdwissler
Ha ha thanks ;)

------
rimantas
I think theres is not enough of the understanding of what CSS is. And a lot of
times trying to make "reusable CSS" is like trying to have make-up that is
reusable among many ladies. CSS is intended to be highly targeted and there
are tons of "it depends" so the best you can do is to try and spend some time
trying really understand CSS and what result you need. Writing CSS for widget
is one thing, styling the page where every byte off HTML counts is another.
Take any rules and advices with massive grain of salt, especially the moronic
"no IDs allowed" kind ones. And yes, do use preprocessors.

------
pan69
This is a very good article that trying to define some really good practices.

I'd like to add another practice that has served me well over the years;
Separate layout from style. Doing this will make your CSS much more modular
and reusable.

~~~
philipwalton
Totally, I discussed this a bit in the article but probably should have
stressed it more.

Nicole Sullivan (OOCSS creator) refers to this principle as "separating
content from container".

------
davidwoof1
Some of this sounds like it really complicates the layout code, but I'm not
sure I'm reading it right. Take, for example, a standard dialog template. If I
have a large number of dialogs for editing user/products/whatever, all with
the same basic `<div><label><span><input>` layout, it sounds like he's saying
that I can't rely on the dialog template to format my labels, I have to apply
the `dialog-label` class to every label in every dialog. Almost every tag in
my doc will have a class attribute, since I can never rely on selectors to
apply the right styling. In general, selectors are almost never used and
classes do all the work.

Am I reading this right? Or are templates an exception? I need to re-read the
template/component thing a few times to figure out exactly what nomenclature
he's using here. But in general, I'm not sure I see the advantage of
`.modal__form__item` vs. `.modal .form .item` except that the first is
exponentially more verbose in the html.

~~~
ahallock
I think you've read it right. Your HTML is more verbose, but you get used to
it. I have elements like <h1 class="product__head"></h1> and it seems ugly and
redundant (the h1 already indicates that the element is a heading!), but the
advantage is that your CSS rules have a narrow scope (fewer collisions) and
are easier to maintain. Further, your CSS is no longer coupled with your HTML.
I would use .product__head in my stylesheet instead of .product h1 or
h1.product__head. Then, if someone changes the h1 to h2, the stylesheet
doesn't have to change.

Essentially, you just have to treat your HTML class names as hooks into your
CSS; that's their function. Your CSS rules should not be concerned with your
HTML structure.

I hope that helps.

EDIT: This article, mentioned elsewhere in this thread, does a fine job
explaining these concepts: [http://nicolasgallagher.com/about-html-semantics-
front-end-a...](http://nicolasgallagher.com/about-html-semantics-front-end-
architecture/)

------
chrislomax
I love articles like this, I would like something like this but more concise
and indexed, does anyone know of anything like that?

There are so many things I do that are described in this article and I class
myself as a seasoned CSS developer.

Every project I do I try to improve my layout and modularisation of my code.
The one thing I find really difficult is naming, I always fall short on naming
my elements.

I like to group stuff too so I know where it is but grouping is sometimes
difficult, do I group buttons with buttons or inside the associated container
it is in?

I've just done my second full responsive site and have learnt a lot about
reusing code in this one due to the nature of responsive sites so on the next
one I really want to come up with a routine.

~~~
zapov
Naming in hard. It's one of the two most difficult things in programming:
naming, cache invalidation and one off errors.

~~~
Leszek
The three most difficult things in programming: naming, cache invalidation,
one and threadoff errors safety.

------
Avalaxy
Good article. I'm not much of a front-ender, so I always ended up with
completely unreusable and unmaintainable CSS. I've been trying to write more
maintainable and reusable CSS the last year, but I'm still struggling with
best practices.

------
Paul_D_Santana
Why is the use of tables considered poor practice?

[Edit]: And what then is the most optimal method to use instead of tables?

~~~
lancedouglas
Tables are a tool. I think that most agree that it is best used for
grid/tabular data representation.

Tables are similar to a club (caveman-style), it performs best at a particular
task, such as knocking-off dinos, but it was quite often used as a hammer,
paper-weight, table-leg, etc. Once specific and readily available tools came
about, the club's value as a club didn't diminish, just its extended usability
did.

CSS provided programmers the ability to not use a club as a wrench, but there
will always remain a value for tables until something more efficient and
effective comes about for the task that they serve.

~~~
ics
Divs are a like a club too, except the dinos are extinct and so they're
expected to be generic. Maybe I'm just feeling nostalgic for something that
doesn't exist, but even when looking at clean, clever, or well-architected
markup I can't help but think it could be much better.

------
jasallen
I disagree with this rule as phrased, though I agree with the examples:
"MODIFYING COMPONENTS BASED ON WHO THEIR PARENTS ARE"

In the example there is a 'regular' version of widget and a couple 'special
cases'. I think if it was treated as .mainContent>.widget{...} vs
.sideBar>.widget the granularity and expectations are the same, you can still
have a more generic .widget that sets common values. In general I think this
is more readable and concise than having a .mainContentWidget and
.sideBarWidget separately.

2c. :-)

~~~
akaBruce
I think the article suggests using modifiers instead. So rather than having

    
    
      .mainContentWidget {
        background-color: white;
        font-size: 1.5em;
        text-transform: uppercase;
      }
      .sideBarWidget {
        background-color: red;
        font-size: 1.5em;
        text-transform: uppercase;
      }
    
      <div class="mainContentWidget"></div>
      <div class="sideBarWidget"></div>
    

The article instead would suggest you do:

    
    
      .widget {
        background-color: white;
        font-size: 1.5em;
        text-transform: uppercase;
      }
      .widget-sidebar {
        background-color: red;
      }
    
      <div class="widget"></div>
      <div class="widget widget-sidebar"></div>
    

To address the bit about common values vs. special modifications. The
implication is, although you might have to change some names, it's not context
dependent. So if you decide that you want to put apply that same style to a
widget in your footer ...and the header ...and this special case on a certain
page landing page ...etc, then you just add the extra class to your HTML
rather than adding a bunch of context dependent rules in the CSS.

------
ahallock
I write all my CSS using BEM (Block-Element-Modifier) now and it's helped
quite a bit with making updates (no more specificity wars) and maintaing
contextual style rules.

I was thrown off at first by the ugly naming convention and "classitis" that
the pattern produces, but the gains are worth it.

------
wyck
CSS rarely gets mentioned in skill assessment because it's more akin to a
syntax than an actual _language_. Though this seems to be changing as more
advanced features are added at a snails pace.

None of your examples break anything, thought they should be considered if
writing something from the ground up, maintenance is another story. CSS
semantics don't even make it into the bug tracker unless you have nothing to
do, or your sole job is to write CSS. There is always more important things to
do.

This is similar to how you can always spot a "new" web dev over how they
obsess over WC3 validation. Sure it's important, but it's not that important.

~~~
ahallock
I had a really hard time parsing your comment. Anyway, writing narrowly-scoped
CSS speeds up development a lot. If you're fighting the specificity war, or
have coupled your HTML and CSS too much (I don't at all), your front-end code
will degrade over time to the point of being incomprehensible (in my
experience). Your marginalizing of CSS-related work says to me that you
haven't had to maintain large web apps, where CSS quality is _that_ important.

~~~
wyck
>Your marginalizing of CSS-related work says to me that you haven't had to
maintain large web apps, where CSS quality is that important.

This is my exact point, I have maintained large web apps that often have
budgets and limited resources. I my experience they are always way more
important pressing matters (aka actual bugs/features effecting revenue) then
CSS semantics. There are companies out there that will of course deem this as
important, but in my experience this has been a minority.

Getting bogged down into the semantics of html/css can also be limiting,
unless you really enjoy doing it, personally I hate CSS, it's an ends to a
means and a bad one at that.

~~~
philipwalton
You pretty clearly didn't read the article.

Semantics weren't discussed at all. The focus was on making the best of
working with a language that has a limited feature set, and learning to
reexamine long held best practices.

~~~
wyck
By semantic I am referring to the idea of "best method", the just of your
article being, name things properly and don't create long nested selectors.

------
ereckers
I guess I was doing it right the whole time. Somewhere along the line I
decided recently that I didn't like putting too much into the "namespace" and
started transitioning towards relying more on parent containers (especially if
sections where properly id'd), but it looks like this might be bad practice.

------
dreamfactory
How about applying the common aesthetic/architectural standard: 'of the
medium' == good. With CSS that means declarative, not procedural i.e SASS/LESS
etc would be considered a bad thing.

------
dfischer
Working on a project to improve CSS architecture: betterfrontend.com

I haven't had a lot of time lately but it's all Open Source - hoping the
community will start working together on it.

------
thejerz
Having used Appfolio for managing a small investment property portfolio, I
wish they would spend a little less time analyzing the philos of CSS and a
little more more time on high-priority features that customers have been
waiting for. There are a million things in life we can spend time on, and the
real challenge is to prioritize. Do we a) Get a PhD in CSS, or b) Deliver
features that 90% of our paying customers have been asking for? To quote Steve
Jobs, "I'm proud of the things we did; I'm even more proud of the things we
didn't do." You didn't catch Steve Jobs writing a dissertation on CSS... he
had more important things on his mind. As a customer, you can't help but get
frustrated when priorities are being so mismanaged and you're paying $4000 a
year for it.

~~~
markdown
Don't crap on the CSS developer for honing his craft and sharing his
knowledge.

That's like saying the guy who developed the CSS for apple.com shouldn't share
his CSS knowledge because because customers want a 5mm thick iPad and Apple
hasn't given that to them.

~~~
thejerz
While I appreciate your use of colorful language (i.e., "crap"), your point is
not consistent with the author or the article. The author prides himself on
looking outside the CSS; he says developers should question the bigger picture
into which the CSS fits, like a Rails developer is expected to do. My point is
simply that he should extend that line of questioning further and ask whether
constructing advanced design patterns for CSS is the best use of time given
other stakeholder priorities.

~~~
markdown
If you hire someone to paint your house, you don't expect him to spend time
wondering about whether the house needs another room, or whether the kitchen
drawers are deep enough. That's someone else's job.

The house painter has single job; paint the house to the very best of his
abilities.

If you have a problem with the design of the house, take it up with the home-
owner. He may or may not decide to accommodate your needs, but in any case,
whether or not he decides to do so is irrelevant to the painter. His job is to
paint the house.

~~~
rimantas
That's an extremely poor analogy.

