ADRS file structure

author: orionrush@gmail.com | 28.04.19


css/
- app.css
scss/ 
|	| 
|	|– tools/ 
|	|		|– _colors.scss      
|	|		|– _functions.scss 
|	|		|– _fonts.scss      
|	|		|– _grid.scss       
|	|		|– _mixins.scss
|	|		|– _variables.scss
|	|		|– _zindex.scss        # See smashing mag article below
|	|		...                  
|	|		|– layers/ 
|	|		|– _b_{base}.scss      # Base Layer    (including reset, typography rules, framework etc)
|	|		|– _l_{layout}.scss    # Layout Layer  (basic layout for ideal pages posts etc, followed by specific page overrides)
|	|		|– _o_{object}.scss    # Object Layer  (atoms molecules organisms -  buttons, .hero-unit .card-preview .top-nav ect.)
|	|		|– _u_{utility}.scss   # Utility Layer (utility classes .font-small etc, the only place where !important is allowed)
|	|		|– _v_{vendor}.scss    # Vendor Layer
|	|
|	|– _media-queries.scss         # @media rules
|	|– _tools.scss                 # third-party tools
|	|– _vendor/		              # third-party styles
|	|		|– tachyons etc
|	|
|	|- vendors-public.scss			# imports for public
|	|- vendors-app.scss				# imports for app
|	|
|	|– shame/ 
|	|		|– _shame.scss 		   # All the bits you're embarrassed about, @*$£*%$ just work! important! all the bits!
|	|
|	|– main-public.scss
|	|- main-app.scss                  # primary Sass file

A Note on vendor styles: As seen above there is a directory for third party style sheets (plugin's etc.) as well as _vendors-app.scss and vendors-public.scss importer files. This approach was taken due to the sprawl of imported 3rd party styles that was starting to form in themain-*.scss file.

Notes:

Class naming conventions

For rapid prototyping, we use Tachyon's built in classes. However as the design/prototyping becomes more stable, we transition reusable collections to flat, low specificity selectors, following an adapted versions of BEM conventions, with Atomic Design components: ABEM.

Version Number Prefix v{X}-

followed by:

Capitalised Prefix  / {o}rganism- / {m}olecule- / {a}tom- 

Which translates to:

.v{X}-{a}-{blockName}__{elementName}

Strictly following BEM conventions could result in monstrously long modifiers, so we use a distinct class instead, with an explicit -is- like so:

.-is-{modifierName}

In SASS we can be efficient and use nesting rules:

.v1-O-blockName {
  &__elementName {
    &.-is-modifierName  {
      /* modifier styles go here */
    }
  }
}

Notes:

SASS tools and techniques used

@mixins``(@include) will insert css where ever they appear - can be sussed with $arguments.

@mixin awesome($w: 100%, $h: 100%) {
    width: $w;
    height: $h;
}

body {
    @include awesome(960px);
}
p {
    @include awesome;
}

Becomes:

body {
	width: 960px;
	height: 100%;
}
p {
	width: 100%;
	height: 100%;
}

The down side of @mixins is that can dump a large amount of duplicate css all over your style sheet - ie not very DRY. However, while this isn't pretty, gzipping does an excellent job of compressing duplicate lines of text, so the size penalty is mitigated.

@extend

.awesome {
    width: 100%;
    height: 100%;
}

body {
    @extend .awesome;
}
p {
    @extend .awesome;
}

Becomes:

.awesome, body, p {
	width: 100%;
	height: 100%;
}

@extend can be used to share properties between elements. However, we should generally avoid extending classes as they can unnecessarily bloat the size of our style sheet and sometimes create a whole range of bizarre specificity issues.

However, when used with silent classes aka placeholders @extend becomes a very powerful tool.

Placeholders:

.awesome, %awesome {
    width: 100%;
    height: 100%;
}
body {
    @extend %awesome;
}
p {
    @extend %awesome;
}

Becomes:

body, p {
	width: 100%;
	height: 100%;
}

The rules to follow when using @extend with silent classes/pointers are as follows:

  1. Only write a given silent class once in your Sass.
  2. Only ever @extend silent classes.
  3. Use solid classes in markup, and as many times as you need in your Sass.

Notes:

Mixing a framework into your BEM flavored SCSS like a smarty:

NOTE: SASS hazards with variables:

Before we proceed, it must be noted that in SASS, the FIRST declaration of a var is king. Subsequent declarations cannot override previously declared values. Because of this, the import order is very important! Basically frameworks need to be toward the bottom of your import tree, and your overriding variable declarations near the top.

// main.css

// Overriding variables (duplicating the framework vars in question)
@import “theme/variables”;

// Importing Bootstrap-Sass
@import “../bootstrap/assets/stylesheets/bootstrap”;

// and so on....

Incorporating a framework's styles into your own component selectors:

Using @extend with with silent placeholder classes and our ABEM conventions:

<article class="pb4">
	<div class="mw9 center tc-m">
		<h1 class="f4 fw6 lh-title f1-ns">
			H1 heading
      </h1>
      <div>
      	...
      <div>
	</div>
</article>
... *becomes*
<article class="v1-o-pageArticle">
	<div class="v1-o-pageArticle_wrap ">
		<h1 class="v1-a-articleHeading">
			H1 heading
      </h1>
      <div>
      	...
      <div>
	</div>
</article>
  
...
     
.v1-o-pageArticle {
	@extend %pb4;
  		
  	&__wrap {
		@extend %mw9;
  		@extend %center;
		@extend %tc-m;
			
		.v1-a-articleHeading {
			@extend %f4 ;
			@extend %fw6;
			@extend %lh-title;
			@extend %f1-ns;
		}	
	}
}
  
// See note on breakpoint specific rules -l -m -ns etc. 
  
@media #{$breakpoint-medium} {
	article div {
		@extend %tc-m;
	}
}
@media @media #{$breakpoint-not-small} {
	article div h1 {
		@extend %f1-ns;
	}
}

While this may seem more verbose in our style sheet, it is the first step in making the project, framework agnostic, and at the same time using @extend with placeholders is a very powerful tool.

To this end we have created a fork of the original Tachyons SASS project, where we have added placeholders to all of the project classes. This fork can be found at: https://github.com/orionrush/tachyons-sass/tree/pointers

Note: placeholders that are declared in @media breakpoint rules, cannot be extended outside of the same rule.

Quick References: