"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/
Hi Adam!
Again, I appreciate you taking the time to share your thoughts. Oh, and thank you for your previous contribution to my CSS framework, Cardinal.
I share the same drive as you and your father when it comes to the work that we do. My father instilled the same work ethic in me. I have been making websites since I was 12 (I turn 26 next month) - it's always been one of the few things I gravitate towards.
The example in "Cargo Cult CSS" that resonated with me was this one:
It's an extreme example, but I've run into similar scenarios on past projects that were trying to use OOCSS principles. I've seen your css-uncut experiment, and modular frameworks like inuit.css too. Do you think its a good idea to set CSS rules with such granularity? How is it any better, from a workflow perspective, from using inline styles? The only advantage I see is not having to remember the values for each CSS rule you want to apply to an element.
Is the above example simply a bad implementation of OOCSS? I tend to favor a balance of both modular and human-readable worlds. I like how in your example you used classes like
.sans-serif
and.bold
... but what if I wanted a certain element to have.border
for certain viewport widths and not others? How would that class then be handled? Additional classes, similar to how I handle Cardinal's grid? All those overrides can add up quickly.It might seem like a petty scenario, but they can add up and make code confusing if not implemented in a thoughtful manner or planned beforehand. Also, with OOCSS you are creating a system of CSS classes, which does effect onboarding time. New developers on the project must take time to learn and memorize the system. Also, sometimes backend developers have to do front-end work in a pinch, and don't have time to learn an entire methodology, which is something to also consider.
Although, I think I agree that its probably easier to deduce what a
.display-block
class does as opposed to something like.breaking
or.news
. But what the heck does a.media
block do? Could be completely different from one project to the next. I then have to remember that a.media
block means a video embed on Project #1, and a status update on Project #2. I often find myself wondering how granular is too granular / how modular is too modular when coming up with class names, which in itself wastes time when I can just name it whatever to get something done NOW, and refactor / reorganize later.I know I'm all over the place here, but I think that's because I'm still trying to figure out the best approach for me and the people that I work with to build products and websites. The industry changes so quickly, its often hard to keep up! Generally, whatever approach can meet deadlines and create a quality result tends to win out for me, so it seems we are in agreement at that most basic level.
Cheers!
😝