Hacker News new | past | comments | ask | show | jobs | submit login
CSS coding techniques (hacks.mozilla.org)
329 points by nachtigall on May 20, 2016 | hide | past | favorite | 132 comments



> This is implied in the previous recommendations, but since it’s crucial I want to stress it: Don’t use !important in your code.

Ehhhh, sometimes `!important` is a good option. I agree that just for the 'quick fix' it's a bad idea, but it can solve other issues beautifully.

For example: If you're writing a plugin or some sort of module that will inject a block of styled content in websites whose normal styling you have no control over, and you need to not accidentally let the sites override your own styling, it's a great fit.

In that situation, it's used to ensure that your block will display correctly across thousands or millions of websites and not fall victim to some awkward accidental local CSS rule like `#body #content #post strong {}` that some developer thought was a clever idea at one point, but didn't realize the implications of the insane level of specificity that is assigned. (I've seen this happen and the support load that it causes).

Far better to have reasonable selectors targeting only your markup, with `!important` so that sites, if they want to, can override your styling, but they just need to be explicit about it.

Long story short, rigidly holding to rules like these in /all/ situations can lead to far worse results for your users than taking them with a grain of salt and making educated decisions while understanding the implications.


>> This is implied in the previous recommendations, but since it’s crucial I want to stress it: Don’t use !important in your code.

> Ehhhh, sometimes `!important` is a good option. I agree that just for the 'quick fix' it's a bad idea, but it can solve other issues beautifully.

`!important` is the GOTO of CSS.

In general you're not supposed to use it, but if you do, it makes some things much simpler.


I thought of the same analogy while reading the article


agree


For junior developers, !important is far and above the most abused feature of CSS. 99% of the time I see !important in code, it shouldn't exist and theres probably a better way. Additionally, once you start using it, it becomes very difficult to refactor out of code.

If you've reached the point where you know the right time to use !important, you probably already know its bad and most likely don't need any of this advice.


I agree but only if all front-end aspects your application is 100% built in-house. Otherwise, you have framework styles, 3rd party plugin/library styles, etc. Sometimes you have to lean on !important and it's OK - not something to bug yourself out over.


The best use of "!important" is for utility classes. For example, if you want to just have a single class that determines when something is hidden, it's a lot easier to have a ".hidden" class that has "display: none !important" on it that overrides any other display you may have set. Otherwise, you'd need to have a ".Module_hidden" class for every single module or component you have - which is dumb.


I am surprised none of the replies (thus far) endorsed the above view, so I will.

Yes, if you are building something that should look the same across websites, this is a good idea.

Though it's often better to just have your own iFrames and use cross-domain communication, since your plugin will have to do its own authentication and API as well.


I think any training wheels or safeguards against specificity should be left up to the developer, not a plugin. And any issues that come up as a result from their lack of understanding of specificity is that developer's own problem--not yours. No offense, I know you may think of it as helpful, but this type of hand-holding for developers actually makes things worse for programmers and the coding community in general imo.


Apparently you're at a stage where you get to follow your own recommendations. For the rest of us, not using !important is probably a good guideline.


Even writing a stand alone module, you can get some weirdness... A module I recently wrote is injected into an element at the end of the body with a specific MyModuleName as the id attribute... all of my rules were nested #MyModuleName .foo, unfortunately, even with a reset for MyModuleName div... there were some things I didn't catch, only because something else in the project it was being embedded in had defined .foo, and properties I didn't think to reset.

If you're writing a module, best to prefix each class with some abbreviation. `#MyModuleName .mmn-foo` ... much less likely to clash, still need the `#MyModuleName div` reset, but it's better than dealing with weird integration issues.


> In that situation, it's used to ensure that your block will display correctly across thousands or millions of websites and not fall victim to some awkward accidental local CSS rule like `#body #content #post strong {}`

Yeah, and possibly break font-size and contrast changes for the visually impaired, if it's not scoped right - break printing ... in general I'd say you're more likely to create an issue than not, using !important.


The author does mention that "It is also used a lot when you are including a CSS framework with very specific rules and it’s just too hard to override them." Which seems like a perfectly valid use case for !important.

In my experience working with a lot of CSS frameworks there are times where not using !important would make the site too brittle if layout had to be changed.

When it comes down to abusing selector nesting vs using !important, use !important.


The only situation I can justify using it for is to override inline styles that jQuery can leave behind in the DOM. Other than that, I haven't seen any legitimate cases for using it to get past the normal specificity rules.


I use it for 'style classes' that you add to an element purely to get some styling change - for example '.pad-left' or '.text-center'. In this case you may be trying to override a style from a stronger selector like `.table td { text-align: left }`.

With style classes you don't run in to the issue of needing to then override the !important rule w/ another important rule - you would just remove the style class.


This is a pretty good article about general things to do or to avoid when writing CSS.

If you'd like to go a step further, I really recommend this[1] CSS style guide by the folks at Trello. I try to use it on all my projects. It makes working with CSS so much easier in my experience.

[1] https://gist.github.com/bobbygrace/9e961e8982f42eb91b80


The Trello CSS Guide is awesome. I especially like the part about media queries and.. well, everything else too. Thanks!


Hadn't seen this before. Many sensible rules that would help keep things sane.


> And using JavaScript to do the things CSS is meant for is just a terrible idea.

That's very strong wording, and I couldn't disagree more. I've added in-line styles into my React workflow for several projects and couldn't be happier with it.

To me, React is primarily a tool that lets the developer define their view in terms of their model, separating business logic from display. Styling is a part of that view. Class names are just an extra abstraction between the view and the model, and offer little benefit.


Thanks for adding this comment. Having good CSS practices is important, but if a module has styles that only it should ever see, why the abstraction to another file/location is beneficial is puzzling me. Bulkier CSS or bulkier templates? (And if those templates are rendered programmatically on the client like many single page applications there's no penalty due to js caching.)


I guess you don’t have to maintain those projects. You’re coupling the style to the view so tightly that any updates in the future will be serious effort.


As a counter-point, the "style" is usually heavily coupled to the "view". It's rare to see a re-style which wouldn't also require a reworking of the view anyway.

I like the idea of purist separation of "style" and "view" but it's unrealistic to think it needs to be a point of dogma.

There are clearly cases where you would want most your styling to be separate, particular for client-specific branding, but there is likely "functional" css such as css that gets date pickers etc working and those can't really be cleanly separated from the view.

A lot of CSS isn't really "style", it's actually far more functional than that. Try turning off CSS and see what happens to fancy date-pickers or rich text editors or other controls, they don't degrade cleanly they just break.


I’m not talking about a complete rebrand, but let’s say your a/b testing discovers that users react better when there’s 20% more whitespace between elements. If you’ve got all your margins contained in your CSS (or better yet a global SASS variable to control default gutter sizes) then it‘s trivial to update and push. If you have to search through every view in your project to see where you might have snuck in some inline styles… well, you’re just not going to bother. Which means you’re throwing user need / conversion away.


In the react style he was talking about, you would import reusable styles so you can still change just one variable to update the gutter size.


Can you elaborate? The design is modular. Reusability of styles is implicit in the re-use of components, it's not like you duplicate styles all over the place (or at all). In my experience maintenance changes have been easier, since it's a piece of cake to nail down exactly what component the styles belong to by quickly scanning the code, eliminating the need to inspect the DOM to discover which selectors are impacting a certain element.


You can get the same functionality by structuring your SASS into a components/* tree that maps to your components. That way your styles can use global style variables that are shared throughout your project, which in turn reduces the maintenance load.

(to be fair, React doesn’t seem to solve more problems for me than it creates - quite the opposite - so I’ve never built anything past toy apps in it)


> can use global style variables that are shared throughout your project,

... which you can just as easily do in React. It's JS after all, so you just use JS modules -- and I hasten to add that there are probably-better-than-plain-JS solutions out there[1].

[1] Here's one example: https://github.com/gajus/react-css-modules . (Dislaimer: haven't actually used this, I'm using scala.js)


Wait, the style and view typically are coupled.

There needs to be a happy medium. Projects that go to extremes to decouple everything are

a) a waste of much effort for little gain. b) as big a pain to work with as code that is completely coupled.


Yes, I think one way coupling isn't really a problem - your controller knows about your model layer, but not the other way around.


IMO react is a special case...

I think what that line is trying to convey is that you shouldn't be doing things like adding a script tag that goes in and sets all classes to have "background-color: red", and to try to avoid using JS for animations/transitions where possible.

Just like when someone says don't HTML and JS, they aren't talking about JSX most of the time.


We've just released Universal.css, which is a great state-of-the-art CSS library. https://github.com/marmelab/universal.css

What do you thinks, guys?


You laugh, but some fool's gonna download this thing and think it solves all his problems. Because now he can use the more cool-sounding "class=" instead of "style=" on the inline styles he's so proud of.


I'm missing a `display-none` css class, looks good otherwise!

Edit: Meant `js--on-hover-this-element-do-display-block-other-class`. Obviously, other class would be an element with `.other-class`


Great idea! I've opened an issue, feel free to open anothers for each idea.

https://github.com/marmelab/universal.css/issues/2


I think nearly 5MB for a prototype css file is orders of magnitude too large.


Read the project FAQ: they offer an alternative technique, using JS, which uses only a few KBs.


It's satire.


I really hope so, but I'm not sure :(


At the bottom of the README:

    Is this a joke?
    
    Of course it's a joke. Use semantic CSS class names.


broad smile

This is border-line Poe's law; I really had to deal with web-3.11-for-workgroups folks who argued that this style is the way to go.

Never felt this good to realize to have been tricked 8)


I'm glad you put the explanation at the end. I don't know much about css but as i was reading I was thinking "Why would you do this? I must be missing something."


I am by no means a CSS-guy, I only do it when necessary (i.e. when prototyping something) but this approach feels so wrong to me: It basically moves the styles from the "style" attribute to the "class" attribute.

How does this approach deal with themes? How can I redesign a page without editing all HTML?


Check the others comments, it's not a real deal.


Of course!


All the people piling on with "!important is evil, nuke it from orbit!" have clearly never been tasked with branding an enterprise product like SharePoint.


SharePoint and !important together is like a nuclear standoff of perfect evil in balance.


Truer words were never spoken. Have you discovered the elusive double-!important? Or the fabled inline style with !important?

SharePoint's markup is rad. /s


Hitting the nail on the head.

!important isn't intended as a workaround for your own code. It's for an external asset to override an internal one.


It's so bad in SharePoint. I try to avoid !important as much as possible, but it's really hard. Maybe it'll get better with the release of the SP Framework. Who knows?


I...I'll reserve judgment. The SharePoint Framework (awful name) will either become an amazing thing, or will be another example of "we didn't get this right (CSR, content search web parts, FrontPage/SPD itself, Design Manager, etc., etc.), so screw it, you guys do it. We give up."

But I'm okay with it either way. We'll still have to help people figure out where master pages / page layouts still fit in, and we will (hopefully) have an easier-to-reason-about path to use React or whatever other framework with SP in a supported way.


I know not everyone is using react and webpack, but using CSS modules has made CSS incredibly easy and removes the pitfalls that most large projects fall into.

With CSS modules you don't have to think about whether you're being too specific or whether your styles will have side effects, because all of your CSS is locally scoped to just the component you're working with.

https://github.com/css-modules/css-modules


http://j2c.py.gy provides similar avantages from JS. You get the full CSS feature set (at-rules, pseudo-selectors) unlike with inline styles, and local class names. No need for WebPack since it's plain JS.

Disclaimer: I wrote it :-)


What also helps a lot is to keep in mind that classes are for classifications (categories) and id's for identifications (unique).

I see a lot of people using classes to create unique styles for specific elements. This will make a mess of your stylesheet.

Also try not to think too much in subcategories (nested classes) because it will remove flexibility from you stylesheet. For example:

  .button {}
  .button.text-center {}
is used to create buttons with centered text. But now you need to create another class for other elements that need centered text. So instead this would be more flexible:

  .button {}
  .text-center {}
In both cases you can use <element class="button text-center">.


I disagree.

If you're stuck using vanilla CSS, that's probably the best you can do. But if you have a preprocessor that allows mixins (and god, you really should), I find life is made infinitely better if you have very specific class names, ie. every element with a given class name should be styled exactly the same.

Any styling that's shared across multiple classes (both in the literal sense of a selector, and in the sense of "grouping of alike elements") belongs in a mixin that gets mixed in appropriately.

If you're certain that's unique, you can use ids if you like, but I don't really see the point. Plus, like all feelings of certainty in programming, the future will love mocking you for having it.

(On reflection, the same frequently applies to OOP classes...)


Sadly using only classes is now considered a "Best Practice" and some employers forbid id or are considering it as an antipattern [1] resulting in a clusterfuck of classes in the html. But best practices in CSS changes so often that I wouldn't be surprised if people starts to use id again in two or three years.

[1] https://github.com/airbnb/css


That's why just like not growing sideburns I'm not listening to this trend either. Use classes where there may be multiple. Use ID when it's a Highlander.


ids do have some fortunate side effects, like magically creating global JS variables.


These days, based on the requirements I would suggest using CSS Modules [1].

On the other hand if this would be an overkill ( small landing page ), then basically whatever you would choose it would be okay, because rewriting the stylesheets will take less than a day.

If the requirements doesn't allow that and you are building a huge complex UI, then I would advise >against styling tags<. There have been at least 100 times in my career, where I discover someone styled an `a` element, that I would like to become a button. My approach is to use class names everywhere.

1 : https://github.com/css-modules/css-modules


I'm a dev so I think I'll carry on using Bootstrap thanks.

It may be a 'bloated framework' but it works and I've spent enough time on CSS already.


8 months ago, building my first web app, I grabbed bootstrap and got to coding. For the same reasons as you.

Cleaning up my code last week I decided to remove it from my source folder to see what would happen. Gulp did its thing, I hit refresh and my app looked exactly the same.

The CSS I added on top of Bootstrap removed the need for 160ish kb of styling rules and gave me full control of the look of my app. No more "col-sm-6 col-md-5 col-md-offset-2 col-lg-6 col-lg-offset-0" nonsense and no more wrestling with the framework.

A day learning CSS basics, Flexbox, Psuedo-elements and best practice brings big returns. And more importantly, gives you design control over whatever you're building which makes prototyping super easy.


Thank you. Hearing I'm not the only one who feels that way makes me feel better about not including Bootstrap in the app rewrite we are doing at work (taking a decade old, 500K+ LOC, Struts app into the rich web client / Angular 1 era).

In general, I have been happy with making a little style file that grew up to 300 (I think) lines or so over that last almost a year. This approach (not using a mystery CSS file) also paid off when we had to make a custom page with alternate styling for embedding within another app.

Now if only CSS selectors were as full featured as XPath :-)


> and I've spent enough time on CSS already

I hope that time wasn't spent customizing Bootstrap to your liking and requirements - you could have worked on your very own and much more lightweight set of common CSS rules instead.

I'm sorry but how anyone, who is at least moderately experienced in web design, could use massive CSS frameworks like Bootstrap or Foundation for anything but quick previews and basic demo apps is beyond me.


It's not massive.


Totallay.


I am always suspicious when anyone tells me their reason for using something is cause "it works" and they don't have to mess with it anymore. This almost always translates into "I don't know why it works and I don't care".


I do know why it works. Because the bootstrap team spend 100s of man hours getting it to work.


Make friends with flexbox and a pre-processor and I think you'll see how you can quickly do much better than bootstrap.


KISS:

- Only use cascading for global theme styles, like type faces

- Don't nest rules with sass or w/e, it's too hard to know what's affecting what in a template

- Naming conventions: Prefix every component class with the titlecased version of the name, have one css file per component that's of the same name. This makes it easy to know where to look for styles when you're working in a template. e.g. styles/header.css would contain:

  - .Header-container .Header-link .Header-title--hover .Header-image


I guess I can agree with that, in spirit. My CSS include file has very broad look and feel stuff. There is also a CSS block inside some pages that customizes size / layout stuff that only applies to that page (e.g. - fieldset and label widths based on content of various blocks).


For me personally, the hardest problem in CSS is the inability to automate testing effectively. If I change this declaration to fix this bug, who knows what's going to happen across the rest of the project? It's less likely to break something else if I add a new class to fix this bug.

Of course, I know in the long run, that will lead to even more bugs but I don't have an effective workflow around that.


I've used two techniques:

1) use a prefix (t-) for test selectors and do not attach any styles to them (put them on the elements you need to target directly so the tests do not have to know about the DOM structure)

2) use data- attributes for test selectors (again directly on the target elements so DOM changes won't break the tests)

The second I got from this article, which is a bit Ember specific, but makes a lot of good recommendations:

https://dockyard.com/blog/2015/09/25/ember-best-practices-ac...


Actually this is a really good idea... But I was referring to to testing the CSS itself - in the same way I text my JavaScript. I'd love to have a suite of tests that say "this element should be 10px from the left of the page" or something like that. I've seen tools that attempt to make this possible but they are hard to work with.

Thanks for the suggestion on how to work with test classes anyway. Very useful.


Probably the best way to test things like that is with a visual regression testing tool [1][2]. In practice these are difficult to get right and tend to produce a lot of false positives and negatives. See for instance Huxley [3]

[1]: https://github.com/BBC-News/wraith

[2]: https://percy.io/

[3]: https://github.com/facebookarchive/huxley


Easy solution: don't go writing styles that affect more than one thing. Avoid styling elements and descendent classes, and it becomes pretty safe. Once you pick a system and stick to it, it takes care of itself. A visual regression testing tool can help you keep your sanity as well.


You sound much more confident with CSS than me. On day one, my designer gives me PSDs and all the buttons are red with 10px padding so I create a button class with those properties. Later I get green buttons with 20px padding and the sad trombone rings loudly.


Great article. It should emphasize the part about !important even more.

!important should be banned. !important divides the good guys from the bad guys. Whenever I see code with !important I instantly know that guy was lazy, unexperienced, wrong guided - you name it. And it also makes my life hard if I have to continue to work on that same css.

I also miss one of the most useful methods to be more granular with the cascading. To apply a new rule, instead of using a fresh new class or to hammer into some new style definitions with an id/!important just use the class twice in your css. More of the same class means more important.

  .button.button.button outranks .button.button which outranks .button. 
See here for an example: http://codepen.io/gkey/pen/ONevEe

It's not beautiful and if you're doing css right you won't need it most of the time. But try this before using the big bad boys like an #ID or the !important statement.


>> just use the class twice in your css. More of the same class means more important

This is even crazier than using an "!important" once in a while. You're creating obfuscated CSS that technically respects the concept of cascades and specificity. Yet your reason for doing this is essentially just to avoid "!important", while not actually fixing your cascading/specificity problem. I'd rather see the rare "!important" as a visible warning sign that something was lazily patched, rather than a poor workaround that is invisible.

This kind of solution sounds a lot like I get in trouble for using "!important", so I'll use an alternative dirty hack that is hidden well enough that I probably won't get caught.


No way. You are not considering the places where the developer doesn't have access to all the CSS that is happening on the page. !important is a way to override styles you don't have access to. For example, I've integrated plenty of third party social media widgets in micro-sites, and they often have the capacity to customise the design by adding new CSS, not replacing the untouchable CSS.

Various other scenarios similar to above is not uncommon for frontend developers to find themselves dealing with in the workplace.


Just curious: what happens if they start to use important, too?


Well of course it's not cool when that happens, and while generally most people agree !important is to be avoided, I was responding to the idea it should be banned completely, or the article where it says it's only good for debugging. It's a last resort that needs to be there, and has probably saved a lot more time than it's wasted.


Sometimes I wish you could chain multiple `!important`s, then I realize the horrible idea I just had...


I disagree on !important. Good use of !important in high level css is outlined pretty nicely in this article: http://csswizardry.com/2016/05/the-importance-of-important/


From that article: "However… if your friend is dying in the back seat and you’re trying to get them to hospital before they bleed out everywhere, by all means, drive faster than 70mph!

In 90% of situations, the [avoid !important] rule is a good one. By and large, we’re much better off following it than not following it. But there will definitely be situations that fall outside of that 90%."

Sooooo, I guess 10% of the time he's driving dying people to a hospital. DON'T TAKE DRIVING ADVICE FROM AMBULANCES!!!!!


Your comment is one of the best I have ever read, thank you :D !


>>Whenever I see code with !important I instantly know that guy was lazy, unexperienced, wrong guided

Your narrow mindedness on the scope of issues that could be at play makes me doubt your abilities.

[EDIT] I am slightly jesting by reflecting your comment judging others based on few factors


!important is the only way to force a CSS rule to be more specific than an inline style.

As such, it has legitimates uses in rare cases (a responsive websites with some javascript style changes specific to a breakpoint per exemple.)

I would personally say that what divides good and bad guys is opinionated though.


Wow, I have to admit I got here to the very wrong guys.

When you're already reflecting about !important, well then you're happy to use it, because you think and know about all the consequences. HN readers reflect a lot. So you're clearly the wrong audience.

I'm sorry for my harsh 'lazy and not so experienced' expression. But sometimes you have to exaggerate to be heard.

Those developers I'm talking about just don't think about the consequences. !important is not a tool for them, it's their last resort to fix something. And then? Well it's a dead end and the rise of all the problems with !important we are talking about. If they would know about chaining, they would have used chaining before using !important. It would be a mess too. Yes. But at least it's not a dead end for them and for any other developer who have to contribute to the same codebase.


Surely, you mean:

    .buffalo.buffalo.buffalo
yes?


I do a lot of WordPress programming. You'd be surprised at the number of WordPress plugin developers who use inline styles. !important is pretty much the only way to override these inline styles, aside from duplicating a plugin (which presents it's own set of problems).


Being old enough to remember the Bill and Ted movies, this makes me want to write a website where there's just varying numbers of a ".station" class on elements.


TIL! Thanks!


Compounding em is total hell to keep track of in my head, even with a stylesheet open in front of me. I'm not much on top of front-end, but why aren't rem units just better in every way?


If you use em for say the bottom margin on a heading, it is going to be relative to the font size of that heading (if specified).

Where as a rem would always be relative to the root of the document, which is not always the desired effect when it comes to responsive typography.


I'm sure grandparent knows that. The problem with cascadingly using em is that you cannot easily deduce the derived em-value on the nth level (e.g. header > nav > div > a, each with their own em-based font-size; good luck reasoning about a's em-value).


I like em for small exceptions. Likes <small> modifier to make that text smaller than its parent. Exactly the use case where you want a "relative" unit.

Everywhere else, I'll just use pixels.


I thought this as well until I had to use a "widget library" that used REM to style.

If i set the HTML font-size to 16px (the default) the widgets are WAY too big, if it set it to 10px (what they use in their examples) it looks great but everything else is too small.

So I need to either re-style all the widgets (damn near impossible), or set all other elements to 1.6rem...

If they used em, i could just set the container to what I wanted and called it a day.

So em definitely has it's place, but I think the majority misuse it.


They don’t work in IE8. If you’re working on smaller projects that’s less of an issue, but I still get 6 figures of IE8 users per month on mine.


You should only use classes in CSS! Leave #id's for Javascript: Wont have to update your JavaScript when you update your CSS and vice versa.


I like most of these except the one about not using !important.

I use .flat { margin-bottom: 0 !important } to remove the default bottom margin from certain typographical elements (ie. h1,p,ul). In this case where I absolutely know that I mean what I say when I apply that class, it works great.


In the future, try using:

    .flat.flat.flat.flat { margin-bottom: 0; }
It gives you the specificity to override most things, and still leaves you the "nuclear option" of `!important` if you ever need it.


I'd rather see !important instead of this. This rule would call for quite a lengthy comment explaining just what in the hell the repeated .flat rules are for, and what other rules it's attempting to pave over such that you know when you need to add a 5th .flat as a "fix'.


That seems frighteningly unclear. If you do need the "nuclear" option, why not have that be the case where you get into weird specificity hacks (flat.flat !important /hack/) and leave the common style clear in its intention (.flat !important)?


People who work in a team have a harder time absolutely knowing what's in their team's heads, though.


Overall rather mundane stuff (I kind of expected something more profound when it addressed the "seasoned developers" in the opening paragraph). I recommend csswizardy.com articles for more insightful thoughts/solutions to actual high level css problems.


Great post, I did not know about the view port options. The specificity I first learned about from another poster on here that created a store locator module for websites. He pointed me to this 3rd party javascript book written by former engineers at Disqus.

I love using SASS to generate my CSS, and I recently started using bourbon and neat with my Go project.

I ran into issues as I did not want to use gulp or grunt so I put together my own way using a Makefile

http://www.tysonmaly.com/programming/go/how-to-use-sass/


I'm partial to BEM From Yandex for my CSS -

http://docs.emmet.io/filters/bem/


BEM is extremely verbose:

  <div class="block block__element block__element--modifier"></div>
Is there some good reason people write that instead of just the following?

  <div block="element modifier"></div>
Unless I'm missing something, with the second approach you get the same specificity, higher flexibility and shorter and more readable markup. Moreover, you end up using selectors the way they're intended to use.


It's supposed to be extremely verbose, and extremely explicit, and create single-responsibility classes as much as is possible. It makes it explicit what is being modified. It's not very nice to write, but on balance, it works well.


Initially I thought the verbosity mattered but there was gains to be made restructuring my CSS too and it forced me to fill in some knowledge gaps so overall it was a big gain with a very small gain in bytes.

I reached BEM via AirBNB's CSS style guide - to me the real value in these style guides is I don't have to care about formatting CSS, JS etc anymore.

http://github.com/airbnb/css


Don't use !important and don't use any id.

If you are reduced to needing to use either of them, it means that your CSS had gotten out of hands and you are trying to apply band-aids.

If you ever need to use !important or an id to fight selector specificity, take a step back and rework all your CSS.

Source: 5 years of not using either of those as a front-end developer.


My main learning in this article was: Be as unspecific as possible. I think making things as specific as possible is what coders learn early on (component thinking etc). But since we want the whole page/component to profit from the styles we write - this makes a lot of sense.


NO, NO, NO! This advice is completely and utterly wrong.

Component thinking is good, it's CSS "best practices" that are backwards and insane, probably because many of the people who came up with them were designers who weren't educated in the basic principles of writing maintainable code.

You do not want to be in a situation where, when you change a particular class, in order to fix a bug in one UI element, it potentially has side-effects in a myriad of others, none of which you know about.

You do want to be able to come into a codebase and make a fix to a particular element, or component, in your UI, and have absolutely confidence that you have not broken anything else.

How do you do that? By breaking down your UI into independent, encapsulated and composable components. And the component's styles should be specific and encapsulated in the same way as its JS code would be. The fact that CSS allows you to create a big stew of global variables does not mean that it's a good idea to do so. Anyone who tells you otherwise is misleading you.

Follow this "be as unspecific as possible" advice and I guarantee that in a year or so, your CSS will contains thousands of low specificity rules, all applying randomly to different bits of your DOM, with thousands more specific classes to override the unwanted styles that are being picked up from elsewhere.


Perhaps a bit more subtlety: Keep global concerns global, and local concerns local. Coloring and font schemes (margins/padding too, I suppose) are usually global, with variations for broad types of components. Sizes / positions of components often end up being very specific, at least in cases where "auto" doesn't work well for what you want.


Yes, that's the scope I was talking about, intuitively. I don't understand grandparent's agitation, but yes, sure, local rules should be constrained to their scope.


Having been on projects where !important was used, I'm not able to rationalize why it's okay to use. It's a quick fix and leads to bad css. We have it in a linter at work so nobody tries to pull a fast one :)


Be careful some of these tips wont work in old browsers! Yeh, there's still old browsers out there (mobile devices, enterprise workstations)


For that, there are tools like autoprefixer


The majority of these problems have been solved for me by adopting SMACSS and BEM.


Pretty cool set of tips. I didn't even know about the !important tip.


Am I the only person who thinks that writing CSS should not count as "coding"?

I feel like the term "coding" should be reserved for writing code that will be compiled. Anything that's not compiled (but is still Turing complete) is "scripting". CSS, HTML, etc. is just "tagging".


Don't know if you are the only one (I doubt it), but I don't agree :-) Programming (also known as "coding") is instructing the computer what to do. If we wanted to stay as close to the processor as possible, we would all be writing machine language code (without an assembler!). Or maybe we should just write micro-code. Or design everything in hardware...

Higher level languages help you abstract things more easily. Of course you can make any arbitrary distinction you want between languages and runtime systems, but to what purpose? And even if you were to make a distinction like you have made, where would you draw the line? Is compiled byte code that is run on a VM "coding" or "scripting"? What about tokenized languages that are simply executing lists of precompiled tokens? What about threaded interpretive languages that compile down to jump tables?

Besides, CSS is an excellent example of a declarative programming language. I don't even know that it is not turing complete. I rather suspect it is, actually (though not in any useful way). Writing CSS is programming... just in a different way.

Different kinds of abstractions are useful for creating elegant designs. Programming is young so we only have a few abstractions. It behoves the good programmer to learn how to use all of these kinds of abstractions appropriately. Each is powerful an beautiful in its own way.


"Hey can you tag up a gallery page this week?" - You

"What?" - Everyone

Not sure that this matters except to preserve some "purists'" (read: pretentious engineers') holy lands. CSS is code. Writing code is called coding.

I don't think it should be called programming, though.


> I don't think it should be called programming, though.

So you're suggesting that the term programming be used to describe writing code that will be compiled?


No, I think that's awfully arbitrary. I'd say CSS doesn't really have any computational capabilities (although that's been changing recently) so it doesn't seem right to call it programming.

I really don't care though. Call it whatever you want as long as I can understand what you're trying to say. "Tagging" doesn't satisfy that sole requirement.


What does it matter, beyond some elitist thing? I'm not accusing you of such, but I'm just not sure what another reason might be.


I can write simple HTML and do a bit of shell scripting but I stay well away from anything that involves compiling code. I feel like a bit of a fake describing writing HTML or scripting up something in bash as "coding".


HTML5+CSS is turing complete, btw. (in the same way as a hand-cranked mechanical turing machine) https://github.com/elitheeli/stupid-machines

More discussion of that and a jsfiddle demo: http://stackoverflow.com/a/5239256


If you compare the web with how one makes a desktop application, laying out objects on the display and deciding what gets colored and whatnot would be considered coding - it's just that the web has abstracted away these portions into static files.

I feel that the root of my frustration with HTML/CSS is that it enforces a specific design pattern (that of boxes and inheritance) that is so bulky and unintuitive.

But I do agree with previous commenters that it seems like splitting hairs to declare web stuff not "coding". In practice, you would very much like a "coder" (someone with a CS background/education) to be handling your HTML/CSS, then have a lay person doing that work.


You're differentiating procedural versus descriptive code.


declarative, not descriptive. And you're quite right.


To me, "scripting" means writing code that's not intended for re-use.

The compiled / interpreted distinction is sort of unimportant - I certainly wouldn't refer to myself as a "Python programmer", because all I do is use matplotlib to make figures for publication, but the guys and gals who wrote matplotlib are most certainly "Python programmers" in my book.


I don't know, I think I have had more issues over the years with HTML/CSS than c# and vb :-p




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: