OOScss architecture for Rails apps. My proposition.
We've been struggling to find a best way to bootsrap an application
andredesign it in further phase.
How many of you write front-end code?
How many of you use Bootstrap for that?
//application.scss
/**=require_self*=require_tree*/
@import "bootstrap";
...
Looks familiar?
|- stylesheets|-application.scss+-controllers| +-/admin/*| |- main.scss| +- controller.scss|...
How many of you use it for a client work?
Is it bad?
NO*
*if you're OK with it's look and feel.
*if you're not tired of the whole Internet looking the same (or at least 90% of open source projects)
*if you do it for prototyping.
*if you do it for fast bootstraping project for a client
*you have a well explained documentation (more less)
...
Have you ever tried to build a custom design/framework on top of a Bootstrap?
Let me show you some numbers:
bootstrap: 266 KB and ~6700 lines of css + responsive: 320 KB and ~8200 lines of css + overrides: 362 KB and ~9200 lines of css
+ custom comp.: 445 KB and ~11000 lines of code + site specific: 556 KB and ~13780 lines of code
556KB for a production css
NOT BAD AT ALL.so we're good right?
NO!*
*have you seen the markup?
*have you seen how much overriding you have to do?
*are you sure your devs understand Bootstrap?
*we haven't styled 100screens (I won't tell you how many of them we covered ;-)
So what should I do when the designs come from the creative agency?
Bootstrap
Example 1. - what's wrong with this code?
Example 1. - what's wrong with this code?
.span9 { width: 740px; }
My reaction was like:
WHY!?
let's correct this code.
Example 2. - what's wrong with this code?
Example 2. - what's wrong with this code?
- it won't fit into the row because of the .well class
Example 2. - what's wrong with this code?
- it won't fit into the row because of the .well class- that's why the dev overrided span9 for that view and used span2 for the sidebar previously
Example 2. - what's wrong with this code?
- it won't fit into the row because of the .well class- that's why the dev overrided span9 for that view and used span2 for the sidebar previously- do you know what's the purpose of the row class?- do you need ALL of that in the markup?
Fun Fun Fun
Example 3. - what's wrong with this code?
Example 3. - what's wrong with this code?
- we dropped the well class to fit into the grid- that's not what we want
Example 4. - what's wrong with this code?
.well { box-sizing: border-box; }
Example 4. - what's wrong with this code?
.well { box-sizing: border-box; }
- we have to override default .well box-model
Example 4. - what's wrong with this code?
.well { box-sizing: border-box; }
- we have to override default .well box-model- aaaand we haven't even reached the fluid grid yet
Do you really think you know how to use Bootstrap?
Do you really think you know how to use Bootstrap?
Are you sure it enforces some conventions?
Do you really think you know how to use Bootstrap?
Are you sure it enforces some conventions?
Do you really think you know it that good to build something on top of it?
Do you really think you know how to use Bootstrap?
Are you sure it enforces some conventions?
Do you really think you know it that good to build something on top of it?
Are you sure it's easy for your devs to understand it?
Do you really think you know how to use Bootstrap?
Are you sure it enforces some conventions?
Do you really think you know it that good to build something on top of it?
Are you sure it's easy for your devs to understand it?
Are you sure it's easy for your devs to understand components build on top of it?
How this markup should look like?
Have you ever seen something like this in ror app?
.users { &.show { padding-top: 0; header { position: fixed; z-index: 10; width: 100%; } nav { background: #fff; box-shadow: 0px 2px 15px 2px rgba(80, 80, 80, 1); position: relative; height: 20px; ul { padding-top: 10px; } } .top_container { background: image-url("controllers/preview/upper_bar_bg.png") background-size: cover; height: 6%;
Have you ever seen something like this?
.logo_container { float: left; position:relative; text-indent: -99999px; z-index: 10; top: 0px; height: 10%; padding-top: 5px; a { h1 { background: image-url("controllers/preview/Logo_white.png") no-repeat top center; height: 86px; width: 95px; margin: 5px 26px 0px 2px; } } }
Why this is bad?
- it's nested to the infinity- it's styled by the elements selectors
- sizes mixed with theme ...
OOCSS principles:
- identify reusable objects- be semantic w/HTML- minimize selectors (you know how browser reads selectors?)
- extend classes- 'style' separate from content- 'content' separate from container
https://speakerdeck.com/anotheruiguy/module-design-ui-dev-patterns
How to achieve that?
That's kinda impossible with pure CSS so...SCSS to the rescue!
How to achieve that?
OOScss+
BEM
How to achieve that?
OOscss+
BEM=
SMACSS
(scalable and modular architecture for css)
BEM (block element modifier)
.component-name {}
.component-name--modifier-name {}
.component-name__sub-object {}
.component-name__sub-object--modifier-name {}
.person{} .person__hand > .animal__hand
.person--woman{}
.person__hand{}
.person__hand--left{}
.person__hand--right{} TIPS:- don't nest to infinity- indent to reflect html structure
/* Layout Rules */ .l-layout-method
/* State Rules */ .is-state-type
/* Non-styled JavaScript Hooks */ .js-action-name
Introduce naming conventions
OOScss
divide your design into:
- (reusable) components- (reusable) modules
OOScss ( probably ) the best way:
Abstract class selector A.K.A. SASS %placeholder (since SASS 3.2)
Placeholders are selectors that output nothing unless they are extended.
Example:
%separator border-top: 1px solid black
hr @extend %separator
.separator @extend %separator
hr,.separator { border-top: 1px solid black}
OOScss ( probably ) the best way:
Placeholders don’t have the code bloat problems that mixins or regular @extend calls have.
That makes placeholders perfect for creating non-semantic CSS modules.
http://ianstormtaylor.com/oocss-plus-sass-is-the-best-way-to-css/
File structure:
- settings - reset - variables - grid-settings - type ... - bourbon (useful set of mixins)- neat (grid library)- utilities (i.e. custom mixins)- components- modules- layout - base-view - views/
Explained
you can add themes/ here
Real life example:
https://github.com/dawidw/cssattempt
- http://bourbon.io/docs- http://neat.bourbon.io/docs/ - https://speakerdeck.com/anotheruiguy/sass-32-silent-classes- http://philipwalton.com/articles/the-future-of-oocss-a-proposal/- http://ianstormtaylor.com/oocss-plus-sass-is-the-best-way-to-css/- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#placeholders- http://blog.teamtreehouse.com/extending-placeholder-selectors-with-sass- https://speakerdeck.com/anotheruiguy/module-design-ui-dev-patterns- https://github.com/csswizardry/CSS-Guidelines- http://bem.info/
pictures from http://frontenddevreactions.tumblr.com/
Further reading