"If you are going to do something you should do it to the best of your ability." - Ken Morse
These are words that my dad imparted on me over and over again. I'm quite sure he did not make them up. And to be honest the words weren't that powerful. But that's how my dad lived his life and after years of observing it in practice I am quite sure it has informed my approach to designing things.
I am a designer who is simply trying to design the best possible products. If it has anything to do with the overall product, I care about it deeply.
Re: http://www.kapowaz.net/articles/cargo-cult-css
A few things that should be made clear that were presented incorrectly.
- OOCSS is an architecture pattern.
- BEM is a naming convention.
They are not mutually exclusive or inclusive to each other at all.
I cannot speak for everyone who promotes OOCSS but I can say this. I don't care about expounding methodologies. I don't care about fitting things into how I want them to work. What I'm trying to do is build the best product, the fastest, with the least amount of effort. These are some of the lessons I've learned along the way working by myself, with small teams, and now with 100 other designers in one department :)
Don't do it. Professional web developers who do understand how specificity works should never have to use them to style something. Many people who touch html and css are not expert front-end developers. Let's not make their lives unneccessarily harder.
"Since class names in this type of project must describe their presentation, they are inherently non-semantic"
This quote seems to indicate a misunderstanding of what the word semantic means.
Semantics are
'the study of the relationships between signs and symbols and what they represent'
To say something IS semantic in a dictionary sense is to say
'Of or relating to meaning'
Let's look at one of the css / markup examples provided.
@mixin news-item($color) {
border: 2px solid $color;
border-radius: 5px;
padding: 20px;
font-family: Helvetica, Arial, sans-serif;
font-weight: normal;
font-size: 1rem;
line-height: 1.4;
}
div.news {
@include news-item(blue);
}
div.breaking {
@include news-item(red);
font-weight: bold;
}
<div class="news">
Here is a news item.
</div>
<div class="breaking">
Here is a breaking news item!
</div>
This example to me involves several unneccessary and detrimental abstractions to providing any type of real meaning that will allow me to design or develop an interface faster. There are now two classes that represent mostly the same visual style (with some custom overrides). I now have no visibility that they are related when looking through the markup. This would be my workflow to discover that these classes are related / coupled together in anyway:
- Look up definition of class in css.
- See that it includes a mixin or @extend
- Look up definition of mixin / @extend
- Grep for all instances where that mixin / @extend is included and look for other classes it is included in
If a class is comprised of more than one mixin or extend, then the process continues...
- Look up definition of second mixin / @extend
- Grep for all instances of mixin and diff it against the first list to output one discreet list
This is a lot of steps. And the subsequent information is very difficult to memorize and leverage later on during development. It gets even more difficult when jumping from project to project. Across projects you will most-likely have more similarity in visual patterns than in content patterns. So why base your visual style naming schemes around the content that it's styling?
Class names that describe semantic content are more than likely redundant in the information they are conveying. This in turn, dilutes the intended semantics.
<span class="item-price">{{ item.price }}</span>
The most important part of the semantics is the actual element used to mark up the content. After that, naming a class "news" doesn't help me or anyone else. This couples together content to visual styles and that is actually what we are trying to seperate. A piece of news might be styled many different ways. In a list view, in a single post or article, or maybe it's in a summary view on the homepage. It's all 'news' content. So now I need to create additional hooks or ovverides to style them independently. This generally results in poorly chosen class names because there isn't something 'unique' that describes the semantics of the content. Or new parent classes used as hooks to override styles.
In turn, increasing the number of overrides in your css, makes it more difficult for browsers (yes even modern faster ones) to render your page. And your code requires more and more cognitive strain for humans reading it. This seems like a lose lose situation.
When I think of designing I think of using scales. In the example above of the .box-standard class, we've included border styles, padding, typography, and color into one class. This seems very difficult to remember if you're familiar with the system and even more difficult to learn if you are new to the system. You definitively have to read css to understand what visual styles will be applied to an element. CSS must be read at times to understand things. You cannot understand code without reading it. But we can reduce the amount of times you need to read it and make it easier to grock.
Why declare a font-size to be 1rem? You should never have to override a class to set the font-size to what is presumably intended to render as 16px. We could most likely get away with only having a few classes (and no overrides!) that are actually pretty easy to read and understand. Depending on other parts of your design scales and patterns I would probably name these classes a bit differently.
<!-- news -->
<div class="border border--red pam sans-serif">
</div>
<!-- breaking -->
<div class="border border--blue pam sans-serif bold">
</div>
The corresponding css could look like this:
.sans-serif { font-family: Helvetica, Arial, sans-serif; }
.bold { font-weight: bold; }
.pam { padding: 20px; } /* would be apart of a larger spacing scale */
.border {
border-width: 2px;
border-style: solid;
border-radius: 5px;
}
.border--red { border-color: red; }
.border--blue { border-color: blue; }
This gives me a sequence of symbols that mean something to me without needing to investigate any more. If I was confused about what a class did - there is a one to one relationship between a class and its definition. This is not the case when you combine mixins and @extends. In a small example like this often times oocss and single purpose class architecture don't shine. Their strength is really in creating a large maintainable system. But even in this example - I find more meaningful 'semantic' information in the class names than in the example of 'news' and 'breaking'. When I style things, the type of content never matters. The type of styles do though.
Performance is a browser level issue, it is not something for HTML/CSS authors to fix or work around. As long as we are authoring valid and sensible HTML and CSS, we should not need to resort to such ridiculous rules simply to enhance the speed at which a given page renders. - Matt Wilcox
This seems like a fair point that I can't argue against as I guess I'm not an HTML/CSS author. I'm a designer. And to my earlier point - I am attempting to design the best products for my users. That means I am not going to sit around and wait for browsers to get faster when I know how to deliver a faster product, to my users, TODAY. Not tomorrow. Not later. Right fucking now. And who knows if my users are even using new browsers? I certainly don't. It's a big open web and I want everyone to be able to get to the content they want, as fast as possible.
CSS performance falls into two categories. First being how long it takes to download the css file(s). So file size matters a bit. But the more important part is render time. Because no amount of caching a file will ever speed up how long it takes the browser to parse your css. The more "overrides" you have and the more unqualified elements you use in selectors, the longer each page will take to paint out to the screen. Using telemetry to test paint speed I have commonly found css to be easily optimized to the tune of .5 to 2.5 seconds a page. That is a lot of time to save. The fastest thing I have found is small classes that don't override eachother. You create a shallow but wide cascade. You spend way less time debugging CSS. AND THAT IS IMPORTANT as it has a huge impact on dev velocity. Time you aren't spending debugging can be used for better things like designing stuff. Or laying on the floor with cats. Or looking at cat gifs. Or thinking about cats. But let's certainly spend less time wrangling css.
Finally, the argument that oocss slows down dev velocity is not backed by any data that I have seen. I have found it to be the opposite actually. But that is a different story for a different time.
Hope this rant helps. Feel free to hit me with questions.
Amazing articles by amazing people:
http://nicolasgallagher.com/about-html-semantics-front-end-architecture/ http://www.stubbornella.org/content/2011/04/28/our-best-practices-are-killing-us/ http://csswizardry.com/2012/10/a-classless-class-on-using-more-classes-in-your-html/
@mrmrs – thanks so much for writing this (found it a few days ago via @jxnblk), a huge help and wake up call for me personally (I feel like my understanding of CSS hadn't developed past a few years ago, text editing cleverness aside). This past week has been huge though thanks to this and articles like it.