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:
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:
class
id, name
data-*
src, for, type, href, value
title, alt
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:
<inputtype="text"disabled/>
CSS
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:
Scss Extends@extends
Extends CSS declarations from other classes or placeholders. Try to limit the use of @extend due to the issues with cascading
Scss Mixins@include
Mixins allow the ability to run a preset block of code while passing in varaibles specific to the application
Component Specific Variables
Next comes any component specific variables, which is helpful when working with if, each, for and whiledirectives
Positioning (position, top, right, …)
These declarations can remove an element from the normal flow of the document and override box model related styles
Box Model (display, float, width, …)
Box model declarations come next as they dictate a component's dimensions and placement
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
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.
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
SCSS
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.
<articleclassName="component"><h2className="component-title">Title</h2><sectionclassName="component-text"><p>Some Text goes here.</p></section><ulclassName="component-links"><li><ahref="#">Link</a></li></ul></article>
/* 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
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()
Javascript
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>)
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);
Tools
Web Tools
CSS Tricks: An online blog with tons of information around CSS
Can I Use is a website which shows you which browsers support certain HTML/CSS properties
W3C Validators for HTML and CSS check your web pages or code files for errors
JSHint and JSLint are online tools to help with javascript errors and potential problems
Browserstack is an online testing platform that allows you to choose various OS and browser versions for browser testing websites (account required)
Flexbugs is a resource for troubleshooting Flex issues
Components
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)
<divclassName="component-wrapper band cool-grey-xxxlight"><articleclassName="component"><h1className="component-title">Title</h1><divclassName="component-description"><p>This is a description</p></div><ulclassName="component-list"><li><ahref="#">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.
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.
<divclassName="component-wrapper band cool-grey-xxxlight"><articleclassName="component"><h1className="component-title">Title</h1><divclassName="component-description"><p>This is a description</p></div><ulclassName="component-list"><liclassName="component-item media"><divclassName="media-left"><ahref="#"><imgclassName="media-object"src=""alt=""/></a></div><divclassName="media-body"><h4className="media-heading">Media Heading</h4><pclassName="media-text">Some text.</p></div></li><liclassName="component-item">...</li><liclassName="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
<divclassName="component-wrapper band cool-grey-xxxlight"><articleclassName="component"><h1className="component-title">Title</h1><divclassName="component-description"><p>This is a description</p></div><ulclassName="component-list is-striped"><liclassName="component-item media"><divclassName="media-left"><ahref="#"><imgclassName="media-object"src=""alt=""/></a></div><divclassName="media-body"><h4className="media-heading">Media Heading</h4><pclassName="media-text">Some text.</p></div></li><liclassName="component-item">...</li><liclassName="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.
<divclassName="key-topic"><sectionclassName="key-topic-list two has-columns"><articleclassName="key-topic-item"><figureclassName="key-topic-img"><imgclassName="img-responsive"src="http://via.placeholder.com/720x405"/></figure><sectionclassName="key-topic-content"><h2className="key-topic-title">Smart Things</h2><divclassName="key-topic-description"><p>This is a short paragraph for the body of the Key Topic Card.</p></div></section><ulclassName="key-topic-links"><li><ahref="#0">Link 1</a></li><li><ahref="#0">Link 2</a></li><li><ahref="#0">Link 3</a></li></ul></article><articleclassName="key-topic-item"><figureclassName="key-topic-img"><imgclassName="img-responsive"src="http://via.placeholder.com/720x405"/></figure><sectionclassName="key-topic-content"><h2className="key-topic-title">Smart Things</h2><divclassName="key-topic-description"><p>This is a short paragraph for the body of the Key Topic Card.</p></div></section><ulclassName="key-topic-links"><li><ahref="#0">Link 1</a></li><li><ahref="#0">Link 2</a></li><li><ahref="#0">Link 3</a></li><li><ahref="#0">Link 4</a></li></ul></article></section></div>
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.
Tip: configure your editor to provide you with shortcuts to output agreed-upon comment patterns.