Code Guidelines

The following document outlines a reasonable style guide for code development. These guidelines strongly encourage the use of existing, common, sensible patterns. This is a living document and new ideas are always welcome. Please contribute.

Our approach to HTML & CSS emphasizes maintainability, scalability, upgradability, and modularity. It is important that HTML and CSS are written in a symbiotic way:

  • HTML, CSS and JavaScript should be used for their intended purposes, ie Document Structure, Visual Style, and Behavior respectively
  • CSS should read like English, and the particular element being styled should be able to be inferred from reading the selector
  • SASS should be used to reinforce the above principles

General Principles

  • Don't try to prematurely optimize your code; keep it readable and understandable
  • All code in any code-base should look like a single person typed it, even when many people are contributing to it
  • Strictly enforce the agreed-upon style
  • If in doubt when deciding upon a style use existing, common patterns

Best Practices

  • Don't reinvent the wheel; use styles, templates and code that have already been developed
  • Check spelling and grammar in text and code
  • Check console output for warnings or errors
  • Design with a mobile-first approach
  • Build in sufficient testing time
  • Test pages and components on all browsers and devices
  • Set aside time to write documentation

Whitespace

Use soft tabs with two spaces, they're the only way to guarantee code renders the same in any environemnt. Always be consistent in your use of whitespace, never mix spaces and tabs for indentation. Use whitespace to improve readability.

Tip: configure your editor to “show invisibles” and to automatically remove end-of-line whitespace.

Comments

Well commented code is extremely important. Take time to describe components, how they work, their limitations, and the way they are constructed. Don't leave others in the team guessing as to the purpose of uncommon or non-obvious code.

  • Place comments on a new line above their subject
  • Keep line-length to a sensible maximum of 80 columns
  • Make liberal use of comments to break your code into discrete sections
  • Use “sentene case” comments and consistent text indentation

Tip: configure your editor to provide you with shortcuts to output agreed-upon comment patterns.

Code Editors

Many code editors have settings for configuring code, whitespace and comments, along with additional features. Many have dark ‘themes’ which is easier on the eyes, and large collections of plugins to make coding quicker and easier. Some of the best options are:

HTML should be clean, semantic, free of unecessary clutter, and should follow the naming conventions described below.

Syntax

  • Use soft tabs with two spaces, they're the only way to guarantee code renders the same in any environment
  • Nested elements should be indented once (two spaces)
  • Always use lowercase for all element and attribute names, as it looks neater
  • Always use double quotes, never single quotes, on attributes ie. <div className="double-quote">
  • Do not include closing slashes in void (self-closing) elements ie. <br>, <hr>, <img>, and <input>
  • Always include closing tags for non-void elements ie. </li> or </body>
  • Avoid using inline styles
  • Use semantic code whenever possible
  • Validate your markup with online tools like the W3C Validator

Attribute Order

HTML attributes should come in this particular order to keep code consistently easy to read. ALL styling and semantics should be applied to classes (never id's) so they come first. Id's come next since they are primarily needed for JavaScript lookup. All other attributs follow according to the list below:

  1. class
  2. id, name
  3. data-*
  4. src, for, type, href, value
  5. title, alt
  6. role, aria-*

Boolean Attributes

A boolean attribute is one that needs no declared value. Don't worry about writing out attributes in full, if the value is the same as the name. That means, required="required" is not really necessary; just required is perfectly understandable and works fine. For example:

<input type="text" disabled />

Block Formatting

  • Use soft tabs with two spaces, they're the only way to guarantee code renders the same in any environment
  • Nested elements should be indented once (two spaces)
  • ALL stylings should be applied to classes, never IDs
  • When targeting multiple selectors in one CSS block, keep each selector on its own line
  • Include one space before the opening brace of CSS block
  • Place closing braces on a new line
  • Include one space after each :
  • Each property declaration should appear on its own line
  • End all property declarations with a semicolon
  • In instances where a rule set includes only one declaration, consider removing line breaks for readability and faster editing

Selector Formatting

  • Comma-separated property values should include one space after each comma
  • Don't include spaces after commas within rgb(), rgba(), hsl(), hsla(), or rect() values
  • Don't over-qualify selectors with an element like div.class-name
  • Don't prefix property values or color parameters with a leading zero (e.g. .5 instead of 0.5 and -.5 instead of -0.5)
  • Use variables for colors, spacing, etc. whenever possible
  • Use shorthand hex values where available, e.g., #fff instead of #ffffff
  • Lowercase all hex values, e.g., #ffa700. Lowercase letters are much easier to discern when scanning a document as they tend to have more unique shapes
  • Strive to limit use of shorthand declarations to instances where you must explicitly set all the available values, eg., background-color: #fff; instead of background: #fff;. Common misused shorthand properties are padding, margin, and background elements
  • Always use double quotes, never single quotes, on attribute selectors, ie. input[type="text"]
/* Bad */
.selector-one, .selector-two
{
display:block;
margin-bottom:0px;
background-image:linear-gradient(to right,red,green);
box-shadow:rgba(0,0,0,0.5);
}
input.selector-three[type='text'] { display: none; }

/* Good */
.selector-one,
.selector-two {
  display: block;
  margin-bottom: 0;
  background-image: linear-gradient(to right, $red, $green);
  box-shadow: rgba($black,.5);
}

.selector-three[type="text"] { display: none; }

Declaration Order

Related property declarations should be grouped together following this order:

  1. Scss Extends @extends
    • Extends CSS declarations from other classes or placeholders. Try to limit the use of @extend due to the issues with cascading
  2. Scss Mixins @include
    • Mixins allow the ability to run a preset block of code while passing in varaibles specific to the application
  3. Component Specific Variables
    • Next comes any component specific variables, which is helpful when working with if, each, for and while directives
  4. Positioning (position, top, right, …)
    • These declarations can remove an element from the normal flow of the document and override box model related styles
  5. Box Model (display, float, width, …)
    • Box model declarations come next as they dictate a component's dimensions and placement
  6. Typography (font-size, color, text-align, …)
    • Typography declarations take place inside the component or without impacting the previous sections, and thus they come after the initial declarations
  7. Visual (background-color, border, box-shadow, …)
    • Visual declarations take place inside the component or without impacting the previous sections, and thus they come last

For a complete list of properties and their order, please see this cheatsheet on Github.

.element-lg {
  @extend .element;              // sass extend
  @include element-style;        // sass mixins
  $element-spacing: 1em;         // component specific variable
  position: relative;            // Position
  padding: $element-spacing;     // Box Model
  color: $text-color;            // Typography
  border: 1px solid $text-color; // Visual
}

Naming Convention

NXP-WEB uses the same grid layout and mobile ready styling built into Bootstrap. We have customized it to reflect the NXP Brand Design through the use of compound classes. Component guidelines are provided below to help build modular and re-usable components.

  • Keep classes lowercase and use dashes (not underscores or camelCase). Dashes serve as natural breaks in related class (e.g., .btn and .btn-danger)
  • ID's should use underscores, ie. id_name so that it is easily distinguised from classes
  • Avoid excessive and arbitrary shorthand notation. .btn is useful for button, but .s doesn't mean anything
  • Keep classes as short and succinct as possible
  • Use meaningful names; use structural or purposeful names over presentational
  • Prefix classes based on the closest parent or base class
  • Use .js-* classes to denote behavior (as opposed to style), but keep these classes out of your CSS

Nesting

Avoid unnecessary nesting. Just because you can nest, doesn't mean you always should. Consider nesting only if you must scope styles to a parent and if there are multiple elements to be nested. This can usually be avoided by properly naming component elements and utilizing the ampersand in sass. Notice the example below keeps nesting to three levels (the unordered list), and those styles are scoped to a component module (.component-links). Unless substantial styles need to be applied to the li or a, it is unnecessary to apply a class to these elements (although it doesn't hurt). If instead, the li items included additional components, it would be recommended to apply a class name and scope the children to that component module.

<article className="component">
  <h2 className="component-title">Title</h2>
  <section className="component-text">
    <p>Some Text goes here.</p>
  </section>
  <ul className="component-links">
    <li><a href="#">Link</a></li>
  </ul>
</article>
// SCSS Styles
.component {
  position: relative;

  // Header Area
  &-title { font-size: 1.5em; }

  // Body Area
  &-text {
    margin-bottom: .5em;

    p { line-height: 1.5; }
  }

  // Footer Area
  &-links {
    list-style: none;

    li {
      padding-left: 0;

      a {
        color: $blue;

        &:hover {
          text-decoration: none;
        }
      }
    }
  }
}
/* Compiled CSS */
.component {
  position: relative; }

  .component-title {
    font-size: 1.5em; }

  .component-text {
    margin-bottom: .5em;}

  .component-text p {
    line-height: 1.5; }

  .component-links {
    list-style: none; }

    .component-links li {
      padding-left: 0; }

      .component-links li a {
        color: blue; }

        .component-links li a:hover {
          text-decoration: none; }

Comments

Code is written and maintained by people. Ensure your code is descriptive, well commented, and approachable by others. Great code comments convey context or purpose. Do not simply reiterate a component or class name. Be sure to write in complete sentences for larger comments and succinct phrases for general notes. Use single line comments for consistency, eg. // this is a single line comment

Variables

  • Use obvious and non-abbreviated names for variables, ie. $padding-base-vertical
  • Place all variables inside of the nxp_variables.scss file (unless specifically scoped to a component)
  • Use existing variables when possible, ie. ($brand-primary instead of #ffa700)

Extends

Due to possible complications with the compiled CSS, try to limit the use of @extends. Here is a helpful article on when to use @extends and when to use @include: CSS Wizardry.

Mixins

A mixin lets you make groups of CSS declarations that you want to reuse throughout your site. You can even pass in values to make your mixin more flexible, although it is not required. When creating mixins, it is helpful to set default values. This makes their usage easier and less likely to break on comipiling if a parameter is left out.

  • Mixins start with the @mixin directive
  • Provide a name, and variables within parenthesis if applicable
  • Set default values by using a colon
  • Separate multiple variables by a comma
  • Include CSS rules inside of curly braces, and use variables in the declared locations
  • When setting variable defaults use the variable name, colon, and value
// Vertically Align anything
// -------------------------------------------------------
@mixin vertical-align($position: relative, $background: $white) {
  position: $position;
  top: 50%;
  transform: translateY(-50%);
  background-color: $background;
}

// Usage
.image {
  @include vertical-align(relative, $nxp-orange);
  // OR
  @include vertical-align($background: $nxp-orange);
  // additional css styles go here
}

Math Operators

For improved readability, wrap all math operations in parentheses with a single space between values, variables, and operators. Forwidth: $variable - 20px;

When using variables inside of functions, you'll need to interpolate the variable. An example is a calc()

NXP Web uses jQuery and Bootstrap's javascript frameworks. Follow the previous links for complete documentation. Don’t always depend on javascript. What if javascript was turned off? Remember that this is what search engines see. Below is a set of guidelines to follow when creating new javascript functions and components:

Syntax

  • Use soft tabs with two spaces, they're the only way to guarantee code renders the same in any environment
  • Nested elements should be indented once (two spaces)
  • Camel-case variable names - var variableName = 'variable'
  • Acronyms should be camel-cased as well. - httpXmlResponse
  • Constants are all caps, seperated by underscores - CONSTANT_NAME
  • Class names are camel-cased with a leading capital letter. - ClassName()
  • Function names are also camel-cased (with the addition of the acronym rule). - makePostRequest()
  • Always use single quotes for strings ie. var person = 'John Doe';

Formatting

  • Do not place javascript code among html as this blocks the page
  • Writing markup in a JavaScript files makes the content harder to find, harder to edit, and less performant, avoid it whenever possible
  • Place script loaders and javascript at bottom of pages
  • Avoid inline code for events (eg. <a onclick="doSomething()" href="#">Click!</a>)
  • Run JSLint/JSHint to validate code
  • Use dependencies to load scripts
  • Don't leave console debugging messages in your production code
//  Template for creating javascript functions
//  Put common code in blocks like this

(function($){
  'use strict';
    try{
        // PUT CODE HERE
    } catch(e){
      console.error('ERROR STATEMENT::',e);
    }
})(jQuery);

Web Tools

Component Structure

Now that you understand the CSS Naming Conventions, and SCSS Nesting, you are ready to start creating modular components.

  • Start with a short, concise component name
  • Include class on the outer-most wraper
  • It may be necessary to add a -wrapper suffix or similar modifier for functional reasons, but should not include any specific component styles
    • For example, if your component is set to display: flex;, and it uses pseudo content (like :before or :after), then you may run into some display issues (see Flexbugs Min Height)
<div className="component-wrapper band cool-grey-xxxlight">
  <article className="component">
    <h1 className="component-title">Title</h1>
    <div className="component-description">
      <p>This is a description</p>
    </div>
    <ul className="component-list">
      <li><a href="#">Item</a></li>
    </ul>
  </article>
</div>

The simple example above provides an approach to building modular components. Since all important modules are prefixed with the component class, we are able to apply sass styles utilizing the & ampersand in order to keep specificity low and styles targeted to this specific component. Notice how the li and a elements do not have classes. These items are scoped to the component-list, since an li would not be found outside of the ul.

// scss
.component {
  ... // component styles

  &-wrapper { ... }

  &-title { ... }

  &-description { ... }

  &-list {
    li { ... }
    a { ... }
  }
}

// CSS output
.component { ... }
.component-wrapper { ... }
.component-title { ... }
.component-description { ... }
.component-list { ... }
  .component-list li { ... }
  .component-list a { ... }

Extending Components

What if you want something more complicated to go inside of the li? Perhaps a Bootstrap Media Object? The best approach may be to add a class of component-item to the li, as well as a new top-level component class such as media. Then you can target that Media Object through the use of compound classes such as .component-item.media.

<div className="component-wrapper band cool-grey-xxxlight">
  <article className="component">
    <h1 className="component-title">Title</h1>
    <div className="component-description">
      <p>This is a description</p>
    </div>
    <ul className="component-list">
      <li className="component-item media">
        <div className="media-left">
          <a href="#">
            <img className="media-object" src="" alt="" />
          </a>
        </div>
        <div className="media-body">
          <h4 className="media-heading">Media Heading</h4>
          <p className="media-text">Some text.</p>
        </div>
      </li>
      <li className="component-item">...</li>
      <li className="component-item">...</li>
    </ul>
  </article>
</div>

Component Modifiers

Great! We have a set of nice modular components that we can place together for fully functional components. What about when we need variations? Maybe we want every other media item in the above example to have a colored background. In order to accomplish this, you can use a modifier class. A couple of quick comments regarding modifier classes:

  • When possible, add the class to the most immediate parent to the modified item (component-list in this case)
  • Note: depending on the desired result, the most immediate parent may be the main component item
  • When possible, modifier classes should use is or has prefixes (such as is-striped or has-stripes) to indicate these classes are not intended to be used by themselves
<div className="component-wrapper band cool-grey-xxxlight">
  <article className="component">
    <h1 className="component-title">Title</h1>
    <div className="component-description">
      <p>This is a description</p>
    </div>
    <ul className="component-list is-striped">
      <li className="component-item media">
        <div className="media-left">
          <a href="#">
            <img className="media-object" src="" alt="" />
          </a>
        </div>
        <div className="media-body">
          <h4 className="media-heading">Media Heading</h4>
          <p className="media-text">Some text.</p>
        </div>
      </li>
      <li className="component-item">...</li>
      <li className="component-item">...</li>
    </ul>
  </article>
</div>

Component Example

The current Key Topic Cards uses the structure and modifiers described above. This component follows the naming convention, and allows us to create styles with very low specificity since they are all prefixed with the key-topic class. Additionally, this component has a modifier class of has-columns which determines if the card links should be shown in one column, or split into two. Since this modifier should impact all cards in the component, the modifier class is placed on the key-topic-list element and not the key-topic-links.

Note: This is a work in progress. Perhaps the two class should have been has-two.

Key Topic Cards

Smart Things

This is a short paragraph for the body of the Key Topic Card.

<div className="key-topic">
  <section className="key-topic-list two has-columns">
    <article className="key-topic-item">
      <figure className="key-topic-img">
        <img className="img-responsive" src="http://via.placeholder.com/720x405" />
      </figure>
      <section className="key-topic-content">
        <h2 className="key-topic-title">Smart Things</h2>
        <div className="key-topic-description">
          <p>This is a short paragraph for the body of the Key Topic Card.</p>
        </div>
      </section>
      <ul className="key-topic-links">
        <li><a href="#0">Link 1</a></li>
        <li><a href="#0">Link 2</a></li>
        <li><a href="#0">Link 3</a></li>
      </ul>
    </article>
    <article className="key-topic-item">
      <figure className="key-topic-img">
        <img className="img-responsive" src="http://via.placeholder.com/720x405" />
      </figure>
      <section className="key-topic-content">
        <h2 className="key-topic-title">Smart Things</h2>
        <div className="key-topic-description">
          <p>This is a short paragraph for the body of the Key Topic Card.</p>
        </div>
      </section>
      <ul className="key-topic-links">
        <li><a href="#0">Link 1</a></li>
        <li><a href="#0">Link 2</a></li>
        <li><a href="#0">Link 3</a></li>
        <li><a href="#0">Link 4</a></li>
      </ul>
    </article>
  </section>
</div>