I think code reviews are critical for sharing knowledge on team projects. It helps keep your team informed about refactors and new functionality, while also giving a space for feedback on implementation (in a critical time, before the code has shipped). It allows a very organic way for people to learn from others (reading code, asking about code, thinking about others' code).
That said, you have to get useful code reviews to see any benefit. To me that means using automated tools to do most of the style checks (your braces should be on this line, no space after this foreach, etc) and having an active culture of not being human-powered code linters when doing code reviews. There is a lot of work that goes into having a team give effective code reviews.
I agree that code reviews can slow down an individual, but the speed up to the team through shared understanding should make up for that.
In my experience the lower level classes increase flexibility, maintainability, and sanity of your css. It's what allows bootstrap to be such a powerful tool for so many products.
Using a conceptually high-level naming scheme won't scale very well as your team and site grows. Eventually someone will say, I need a large rounded button, I can use the .buy class for this contact form. Or perhaps your team is very disciplined but ends up with 10-15 different ways of specifying large rounded buttons.
You'll potentially end up where .buy makes sense in two different contexts which will then increase the complexity of your css:
button.buy {...}
h1.buy {...}
Having .button .button-rounded .button-large helps you keep your css simple allows it to be remixed and reused in ways you haven't planned for yet.
Not to say semantic classes are wrong, I like them, but I have yet to see a system for it that doesn't break down after a certain size for a project/team.
I've started combining both approaches, with help from SASS's '@extend' directive.
What I mean is, I have a section of my CSS for defining all of those simple, modular classes like 'button' and 'button-rounded' (I start with bootstrap for most of these and then add more as I need them), with the idea that I'll reuse these over and over.
BUT, these never get used in the HTML directly. Instead, I have a second section of my CSS which contains definitions for those high-level, one-time-use rules. So, for instance:
// Low-level CSS (don't nest anything or it breaks @extend)
.button { // basic button... }
.button-large { // large button... }
.button-rounded { // rounded button }
.button-primary { // blue button }
.button-warning { // red button }
// High-level CSS (avoid nesting, but sometimes it is okay)
#buy_page .buy_button {
@extend .button;
@extend .button-large;
@extend .button-primary;
}
#settings_page .deactivate_button {
@extend .button;
@extend .button-rounded;
@extend .button-warning;
}
The big rule for the HTML is that I can only use IDs and classes from the high-level CSS, and should really only have one class/id per element. For the most part the high-level selectors are 1:1 with the markup, but things like widgets/components it's okay to reuse them on multiple pages.
The major exception here is the CSS for actually laying out pages. I don't use a class-based grid system. Instead, I map <section> tags to rows and <header>/<article>/<aside> tags to columns. The grid behavior is defined using Susy[1], and for specific pages I can modify the standard layout pattern if necessary.
The result of all of this is CSS that is easy to navigate. The low-level CSS is highly reusable, and the high-level CSS is structurally similar to page content, yet keeps the presentation information entirely out of the HTML. It also sometimes results in very long selectors, but that's actually not an issue performance-wise and has yet to cause me any issues.
If all classes are basically strictly scoped, encapsulated components, targeted in the CSS via parent chains, then you won't have this problem, and you won't fall into the trap you describe.
For example, rather than having .buy, it would be named something like .NavigationBar_buy (ie., following a ComponentName_child naming convention) and it would be declared in NavigationBar.scss and look like something like:
The really nice thing about the mixin approach is that you will be able to trace all usage. After all, a huge problem with CSS is class rot (where you don't know which classes are actually being used by the app) and class leakage (where classes are used for unrelated things in surprising ways that break if you modify it not knowing about the potential side-effects). Whereas in a component/mixin system, the dependencies are crystal clear: if a mixin isn't used in the stylesheet, you know it's not used by the page, and similarly, you know exactly which classes map to which components. You may get some rot, but zero leakage, and the rot is carefully contained. The only downside is increased HTML/CSS size.
Class-based CSS doesn't scale to large teams, in my opinion. A strictly enforced design manual might do it, but I don't think most companies can work that way.
Not always. Different operating systems and browser combos have different ways of rendering fonts. I've seen fonts that look good in OSX in Firefox look poorly in Windows with Firefox (Gentium in my case).
Also these images look like they used gray scale instead of sub-pixel rendering so the differences in pixel geometry should be more or less mitigated.
I'm sure in theory it could look better as actual text for certain setups, but this probably allows them to get the best looking text in the widest amount of configurations.
I think this is really useful when you combine it with vhosts on apache/nginx. On my linux machine I run something similar that allows me to serve static assets, run a local dev server (runserver/flask/unicorn, etc) and have a .dev domain to test with.
You can then combine this with xip.io and be able to share your dev site with others.
I really like seeing companies build out their own style guide libraries. It's such a huge win in terms of maintaining css and keeping it consistent across an entire site/platform. We went through this process at Trulia about a year ago, and the results had a huge impact[1].
Sadly we never released our style guide to the public, but we did open source the tool for building it: https://github.com/trulia/hologram
It tries to keep things simple by letting you use markdown and html to document your css/js inline and then extracting that into a style guide.
Thanks for sharing this! Nicole Sullivan's talk about her work with Trulia was a huge inspiration for Yelp's styleguide.
The performance improvements you reported are very impressive. Well done!
That said, you have to get useful code reviews to see any benefit. To me that means using automated tools to do most of the style checks (your braces should be on this line, no space after this foreach, etc) and having an active culture of not being human-powered code linters when doing code reviews. There is a lot of work that goes into having a team give effective code reviews.
I agree that code reviews can slow down an individual, but the speed up to the team through shared understanding should make up for that.