Skip to content

Instantly share code, notes, and snippets.

@chinchang
Created March 29, 2016 18:28
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chinchang/2832a1f24d29023f687deb408e9397ba to your computer and use it in GitHub Desktop.
Save chinchang/2832a1f24d29023f687deb408e9397ba to your computer and use it in GitHub Desktop.
Comparing code for OOCSS and Atomic CSS
<!--
Example: A simple list component with each item as a block one below other with some padding and border.
-->
<!-- Atomic CSS -->
<ul class="MB(baseSpacing) Bgc(#0280ae)">
<li class="P(halfBaseSpacing) BdB(1px)"></li>
...
</ul>
<!-- OOCSS
The styles have been defined in CSS. Eg.
.block-list { margin-top: $base-spacing; background-color: #0280ae; }
.block-list > li { padding: $half-base-spacing; border-bottom: 1px; }
-->
<ul class="block-list">
<li></li>
...
</ul>
@chinchang
Copy link
Author

@jitendravyas Thats what styleguides are for. Styleguides can show visually what components are available to select from. And your question should be more towards Atomic syntax as to how developer will get to know the weird classnames (even though documented).

@pankajparashar-zz
Copy link

Before I dive into each bullet point, let's look at a basic component that uses Atomic CSS. Hopefully this should clear some of the questions that you have.

import React from 'react';

class ListComponent extends React.Component {
    render() {
        return (
            <ul className="MB(baseSpacing)  Bgc(#0280ae)">
               <li className="P(halfBaseSpacing) BdB(1px)">List item #1</li>
               ...
           </ul>);
    }
}

export default ListComponent;

Although the example above uses React, this works pretty much the same with Polymer, riot.js etc.


Now onto the specific questions raised (also quoting your question here for brevity),

Anyone who tries using a block list for his work, may end up using his own classes and values. Some may style the item with 2px border!

Other developers will simply use the <ListComponent> component in their code and get all the Atomic CSS styles associated with it. It is because components are designed to be re-usable. This is how a typical component driven development works.

There can't be a styleguide to dictate objects/components, because there are no components! There are just atomic classes.

Ofcourse there can be! Style guides are not just related to CSS. Even a simple <ListComponent> like ours can be part of the style guide. For example, take a look at some of the component guide embodied by Polymer here. This is a classic example of a typical catalogue for Google Web Components.

Developer ends by writing more code. Nothing about file size or anything, but basic rule for avoiding bugs is write less code. But in atomic CSS approach, dev needs to write more code to style his components in HTML, in contrast to OOCSS approach where code is written once and devs just use a single class over n over again.

Components are designed only once and re-usable everywhere. These are very similar to defining a class in OOCSS approach. I don't think, one technique has advantage over the other in terms of 'writing more code'. Both are evenly matched.

That being said, if you use Atomizer in your project, then you don't write CSS at all! We only write markup with atomic class names and Atomizer will automatically generate the CSS. No need to author CSS files. Now I'm pretty sure with this approach, devs will be writing a lot less code than in a typical OOCSS approach.

If block list UI is to be changed across app, all occurrences will have to be changed individually.

If you have to make a change in the block list UI, you simply update the code for <ListComponent> component in one place. Other instances using this component will automatically get the latest update.


Finally,

I might be wrong and would love some pointers on what I might be missing here.

You have asked the right set of questions :-) and these are the questions every developer should ask before adopting a new methodology. Lets not get blinded with existing best practices and assume them to be the de-facto standard of the web. Question them, break them and then Improve them.

The basic premise of these questions is how the HTML is generated?

  • If it is written inside JavaScript like React then Atomic CSS workflow should be perfectly fine.
  • If it is generated by a template language like Handelbars, ejs etc then Atomic CSS workflow is still perfectly suitable here.
  • If you are hand coding all your HTML files then Atomic CSS may not be the right option. It will be more of a pain-in-the-ass.
  • If you have no control over the HTML generated then Atomic CSS should be the least preferred option of all.

At the end of the day, no single approach works for every project. You need to decide what fits best in your workflow and stick with it. Good Luck! 👍

@chinchang
Copy link
Author

@pankajparashar I understand that all my points are invalid if each visual object/component in the app is available as a HTML component (eg. in React) too. But I feel this assumption is too ideal and even too much to have. That is why I specially took example of a block-list which can definitely be a React component rendering a dynamic list of passed items , but at the same be used manually by a developer to render a list of static items...practical enough.

So I guess all my questions boil down to one - Don't you agree that there will always be visual components in an app which won't be available as reusable HTML components?

@pankajparashar-zz
Copy link

But I feel this assumption is too ideal and even too much to have.

It might be a far-fetched idea for smaller projects. But for any medium to large scale web projects, if you're user interface cannot be decomposed into visual components, then you got bigger problems at hand, namely, design, scale and maintainability issues in the long run.

but at the same be used manually by a developer to render a list of static items...practical enough

This is exactly why I had written pt no. 3 of the last paragraph in my previous response => If you are hand coding all your HTML files then Atomic CSS may not be the right option. It will be more of a pain-in-the-ass.

Don't you agree that there will always be visual components in an app which won't be available as reusable HTML components?

Yes I absolutely agree, 100%. As a general thumb rule, if these visual elements contribute to less than 10% of your overall project, then using semantic class for such elements will not have a detrimental effect to the overall performance of the website. If it contributes to more than 10%, then I'm afraid you will have to go back to the drawing board.

@chinchang
Copy link
Author

Pankaj, you gave a lot of clarity on Atomic CSS 😃 Thanks man!

Conclusion for anyone reading this:

Atomic CSS seems to be a suitable approach for writing your CSS (rather structuring your CSS once) when more than 90% of website HTML is made up from reusing predefined components i.e. if you mostly end up writing <some-component data-a="someData">Hello</some-component> and hence not much need to use classes. If not, its better to go the OOCSS way because developers will be writing markup for components and a higher form of abstraction in CSS is required in form of object classes.

@thierryk
Copy link

Thanks to Pankaj for his great explanation of the pros and cons of Atomic CSS.

In regard to your last comment:

Atomic CSS seems to be a suitable approach for writing your CSS (rather structuring your CSS once) when more than 90% of website HTML is made up from reusing predefined components

It does not have to be component-based per se though. For example, in most web sites (even basic/simple ones), many elements are "unique" (i.e. header, footer, navigation, etc,) so styling those via OOCSS or Atomic CSS should not make much difference in term of maintenance—because at the end of the day you are making edits in a single file, in a single place.

Also, Atomic CSS is not about abandoning classic styling. Authors can incorporate Atomic CSS as they see fit. It is not the same as on-boarding a CSS library, because if you rely on Atomizer then no CSS is added to your code base unless Atomic classes are actually being used. This is an important "feature" because it lowers the cost of refactoring.

Finally, to answer one of your earlier questions (how can we change a style in multiple places at once?), Atomizer has a config file that lets you use "variables", for example:

In the config

"custom": {
    "myBorder": "1px solid teal"
}

In the markup

<div class="Bd(myBorder)"></div>
<div class="Bd(myBorder)"></div>
<div class="Bd(myBorder)"></div>
<div class="Bd(myBorder)"></div>

Rather than editing the class in each div you'd only change the value in the config to style that border the way you want across the board.

@thierryk
Copy link

One last remark, this time related to semantic and redundancy.

In OOCSS, a media object would look like this:

<div class="Media">
  <img class="Media-figure" src="" alt="">
  <p class="Media-body"></p>
</div>

In ACSS it would look like that:

<div class="Ov(h)">
  <img class="Fl(start) W(20%) Mend(10px)" src="" alt="">
  <p class="Ov(h)"></p>
</div>

Now a simple 2 column layout in OCSS could be:

<div class="line">
  <div class="unit size1of5"></div>
  <div class="unit size4of5 lastUnit"></div>
</div>

That same 2 column would look like this in ACSS:

<div class="Ov(h)">
  <div class="Fl(start) W(20%)"></div>
  <div class="Ov(h)"></div>
</div>

With ACSS, we are able to create very different "objects" using the exact same classes.

Please note that this simple example also debunks the myth that Atomic CSS creates bloat in the markup.

@chinchang
Copy link
Author

Hey, thanks @thierryk for that explanation. Taking further your examples of media object and grid, I have a question - Don't you think, seeing the markup should quickly convey what the visual structure will finally be when rendered?
Seeing the ACSS HTML blocks, I would say the brain would need to do more work in order to recreate an image of the final output in comparison to if I just see a Media or line class.

Also, I just realised that ACSS requires the developer to be more well-versed with CSS and its quirks because what he has in his hands are essentially individual CSS properties. And he needs a solid understanding of each property to be able to combine them to create visual structures. Whereas in OOCSS, he would have classes available that can abstract those quirks & other complex bits.

@thierryk
Copy link

thierryk commented Feb 9, 2017

@chinchang this is not a real concern if you offer a style guide that is component based—where devs can copy/paste html snippets from. Imagine this for example:

<!-- Media Object -->
<div class="Ov(h)">
  <img class="Fl(start) W(20%) Mend(10px)" src="" alt="">
  <p class="Ov(h)"></p>
</div>

Also, I may be wrong but I'd think it's easy for the brain to recognize a pattern like this after just a couple of uses. After all, it's only composed of 3 elements and 2 main classes.

Also, I just realised that ACSS requires the developer to be more well-versed with CSS and its quirks because what he has in his hands are essentially individual CSS properties. [...]. Whereas in OOCSS, he would have classes available that can abstract those quirks & other complex bits.

Sure, but this goes both ways. Looking at a class like Media may tell you how the element will display but it won't give you any hint about how this is actually done in term of styling (CSS). So one approach may be easier to grasp but there is nothing to learn from it while the other approach may require you to learn about a few class and at the same time learn how the layout of these boxes is created through specific properties. In my opinion, in the long run, less abstraction makes you a better developer. But note that I'm not saying devs should use a Atomic CSS approach just for this reason (that would be wrong).

When it comes to CSS there is no simple solution, no simple answer. You look at your problems/requirements, you look at the solutions out there, and you pick what works best for you; and that may be OOCSS, ACSS, ECSS, SMACSS, Bootstrap, whatever...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment