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.
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.
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.
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.
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.
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. ;)
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.
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.
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.
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.
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.
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 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.
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.
There's nothing wrong at all with using tables when your content is tabular data. The problem is mostly an historical one, dating to before the widespread adoption of CSS: Tables were once the only reliable way to get any sort of layout structure on a page, and so were hacked to accommodate all sorts of layouts through clever use of colspans and rowspans. This was terribly inefficient, but before we had positionable divs, they were the only game in town.
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.
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.
In my own experience I find them to be very inflexible and unpredictable.
There are still scenarios when you need them though, so I wouldn't call them 'poor practice' so much as something that should only be used if it makes sense.
It really depends on what you are trying to do, I don't really know how to answer the question, it is too broad.
But like I said, I don't think tables are 'bad'. I think the main stigma against tables was that back in the old days they were used to layout pages that had column layouts, but I didn't program back then so I don't really know.
GMail uses a table for laying out emails, is that tabular? (Maybe it is, I don't know, which is why I'm asking.)
What if you have an element which has 5 children that are in a row and you want the one in the middle to take up all the remaining width while the rest just take the width they need? I'm actually curious because I haven't figured it out. (Besides using table cells that is)
A list of emails can be thought of as tabular data. In Gmail, you have columns (selection, star, important, participants, subject, and date) with one row per email. That's a table without explicit headers.
Yeah, with current css specs in browsers you need to resort to table-cell stylings like display:table-row and display:table-cell. But that can be done without using actual <table> elements.
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.
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.
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.
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.
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.
>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.
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.
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.
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.
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.
1) I didn't write this while on the job at Appfolio. I wrote it at home, in my spare time, because I like sharing the things I've learned on the job with the rest of the Web community. Based on the upvotes and overwhelmingly positive responses I've received, I think it's worth my time.
2) My work on the CSS for Appfolio Property Manager has greatly helped the development team (mostly back-enders) and sped up the process. We can release features much faster because of it. I'm sorry they're not the features you want (that's not my call), but if/when we deliver those features they'll get to you quicker because of my work.
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.
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.
You work as a development project manager, don't you?
It takes a certain kind of unique mindset to encounter excellent work somebody has done and use it as an opportunity to bash them because unrelated teams with unrelated skillsets are not churning out the features you want at the rate you want them. How in the world is doing his job the best he can do it somehow not the best use of his time?
What exactly is your argument here? Is it that appfolio should not hire such excellent front end developers because their backend is still lacking? Or is it that the front end developers should do worse work to mesh better with what you consider to be the failings of the back end? Even if the css author had anything to do with your complaints, your argument betrays the absolute worst mindset that one can find in software management: the idea that quality work is time-consuming rather than time-saving.
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.
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.