Skip to content
Robbie Bardijn edited this page Nov 20, 2015 · 3 revisions

5.1 General

All Drupal projects use the Drupal-theme-boilerplate. Most of the time we use Omega as a base theme; so make sure to checkout the omega branch!

https://github.com/Crosscheck/Ocelot

Omega is a contrib theme and should live inside /sites/{all}/themes/contrib/omega. The custom theme is (obviously) custom and should live inside /sites/{all}/themes/custom/{projectname}_omega

5.2 CSS and SCSS Coding standards

Here is an overview of the css/scss coding standards and the file organisation structure for a project (using the one-boilerplate theme).

General coding standards

  • All helper files* should start with an underscore (_).
  • Use a - for filenames with multiple words, eg: _upcoming-events.scss
  • Split up code in to small sepate files. Rather 100 files with 10 lines of code than 10 files with 100 rules of code.
  • by helper files we mean partials, files that shouldn't be compiled into css. They are usually included in other files.

/scss folder structure

The folder is structured in a SMACSS way (https://smacss.com/). The scss folder therefor contains a few subfolders:

  • base
  • components
  • layout
  • print
  • utils
    • classes
    • functions
    • mixins
    • variables

The last folder, utils, isn't in the SMACSS spec. This folder contains additional functionality such as variables, mixins and placeholders. This is useful to abstract code and to keep the front-end DRY (Don't repeat yourself!). It's pretty obvious what should be inside those subfolders. Make sure to split up all the mixins, placeholder, … in separate files based on their functionality.

	File: scss/utils/mixins/_shapes.scss
	
	@mixin circle($size) {
	  width: $size;
	  height: $size;
	  @include border-radius($size / 2);
	}
	
	@mixin square($size) {
	  width: $size;
	  height: $size;
	}

The (main) folder contains 5 other files:

  • base-styles.css
  • component-styles.css
  • helper-styles.css
  • layout-styles.css
  • print-styles.scss

Base folder

The base folder contains files involving the default styling for (base) elements. We split these up in separate files.

  • _forms.scss: default form element styling (input, textarea, …)
  • _base.scss: default element styling (a, a:hover, a:focus, img, …)

Components folder

Contains styling for components. Make sure to smartly split up each component.

  • /blocks: contains styling for (Drupal) blocks

      File: scss/components/block/_bean-copyright.scss
      	
      .block--bean-copyright {
      	color: $c-red;
      }
    
  • /menus: contains styling for menus or menu blocks

      File: scss/components/menus/_main-menu.scss
      	
      .block--menu-block-main-menu-level-1 {
      …	
      }
    
  • /nodes: contains styling for nodes

    File: scss/components/nodes/_event.scss
    
      .node--event {
      	// Default styling for a page node
      	
      	.title {
      	  color: red;
      	}
      	
      	&--full {
      	  // Specific styling for a page node in full view mode.
      	}
      	
      	&--teaser {
      	// Specific styling for a page node in teaser view mode.
        }
      }
    
  • /views: contains styling for views (usually created with the contrib views module).

    File: scss/components/views/_upcoming-events.scss
      	
      	.view-upcoming-events {
    		.node--event {
      		.title {
      		  color: blue;
      		}
    		}
      
    		.views-row {
    		  @include span(1 of 3); // Each row 
    		}
          
    	  .views-row-last {
    		  @include last; // The last row - should be floated right
    		}
      }
    

Remark: Nodes are often used in views or blocks. Inside the /nodes folder we add the default theming for a node in a certain view mode. Inside the view, the structure or specific overrides happen for a view. NEVER theme a complete node view mode using classes from views.

In the example above we have a node event. It has two view modes: teaser and full. A view showing the upcoming events shows 3 nodes from the content type event in teaser mode. The view mode event nodes are styled inside /nodes/_events.scss, because this is generic theming for these node. Inside the /views/_upcoming-events.scss we only theme views classes or overrides that should happen when using this view. If these changes are huge, make sure to concider creating a different view mode!

Component variables

To abstract a component even more, you can create variables for a component. These variables should be defined inside a SASS map; where the name for the map equals the name of the component.

	// Variables
	$component: (
	  bg-color: $c-red;
	  color: $c-green;
	);
	
	// Component style
	.component {
	  background: map-get($component, bg-color);
	  color: map-get($component, color);
	}

Variable naming

  • _typography.scss: contains the typography variables, such as font-size, font-family, … ($t- prefix)
  • _defaults.scss: contains defaults for the website.
    • If the website uses the same border-radius on each element, this border-radius can be defined here. Generally, the $default- prefix is used for these elements: $default-border-radius.

5.3 Javascript

  • Never, never, never ever, ever, ever start to write the "entire" site in Javascript. This was sometimes done in old (meanwhile legacy) themes. Always ask a backend developer for help if you don't know where certain html-code comes from, but never start wrapping elements or changing the document structure in javascript. Even on mobile. Try to find a solution where a least amount of javascript code is required.

  • All of the javascript code must be declared inside a closure wrapping the whole file. This closure must be in strict mode.

      (function () {
      	'use strict';
      		// Custom javascript
      })();
    
  • In any part of your code it should be easy to understand which variables are jQuery objects and which are not. Always prefix varialbes that contain jQuery object with a $.

Incorrect

	var foo = $('.foo');
	var object = { bar: $('.bar') };

Correct

	var $foo = $('.foo');
	var object = { $bar: $('.bar') };