The Case for Standards and Conventions
Create a system to build systems
After working on a handful of style guides and design systems over the years, I have come to the conclusion that it is extremely important for a team (small or large) to clearly define their own standards and conventions. Standards and conventions are a set of rules agreed upon as a team, it helps to keep the code base consistent and predictable, and it promotes less—but better—communication. When turned into a written document, it will help with on-boarding new hires and serve as criteria for code reviews. The following are my own standards and conventions (an overly simplified tl;dr version). I will use them to keep my personal projects in check.
Formatting
This is how I format code.
General
Format | Setting |
---|---|
Indentation | spaces |
Tab size | 2 spaces |
Translate tabs to spaces | Yes |
Trim trailing white space | Yes |
New line at end of file | Yes |
Quotes
File Type | Quote Style |
---|---|
.html | "double" |
.css | 'single' |
.scss | 'single' |
.js | 'single' |
.json | "double" |
.yml | none in general |
'single when forcing a string or using [email protected] characters' | |
"double when parsing escape codes" |
Cases
Name Type | Case Style |
---|---|
HTML | dash-case |
CSS custom property | var(--dash-case) |
SCSS var/function/mixin | public: dash-case |
private: _dash-case | |
JavaScript var/function | camelCase |
JavaScript class | PascalCase |
File | dash-case.extension |
Naming
This is how I name things in code.
Prefixes
Category | Prefix |
---|---|
Animation | a- |
Element | e- |
Layout | l- |
Component | c- |
Color Scheme (light/dark) | cs- |
Utility | u- |
JavaScript | js- |
Namespace
Category | Namespace |
---|---|
mikemai.net | mmn- |
Typesettings | ts- |
Acceptable Abbreviations
Actual Word | Abbr |
---|---|
Image | img |
background | bg |
Minimum | min |
Maximum | max |
Call to action | cta |
Column | col |
Column Span | colspan |
Row Span | rowspan |
API/Modifiers
Prop Type | Enum | Example |
---|---|---|
Size |
xxsmall xsmall small medium large xlarge xxlarge |
.e-mmn-heading--xxlarge : the xxlarge heading.
|
Spacing | ||
Breakpoint | ||
Tints and shades |
xxlight xlight light medium dark xdark xxdark |
.u-mmn-color-magenta-xdark : the xdark magenta in the color palette.
|
Hierarchy |
primary secondary tertiary |
.c-mmn-button--primary : the primary button.
|
Responsive behavior | [email protected][breakpoint]; |
[email protected] : starting at small breakpoint and beyond, set the cell to 100% width.
|
[email protected][breakpoint]; |
[email protected] : starting at 0px until small breakpoint, set the cell to 100% width.
|
Front-end
Type | Name | Example |
---|---|---|
HTML custom element | <namespace-element-name> | <mmn-card> |
HTML data attribute | data-namespace-attribute-name | data-mmn-uuid="rng1928" |
CSS custom property | --namespace-global-var | var(--mmn-color-magenta) |
--prefix-namespace-scoped-var | var(--c-mmn-card-border-radius) | |
CSS selector | class="prefix-namespace-block__element--modifier" | class="c-mmn-card__media--video" |
JS selector | class="js-namespace-target-selector" | class="js-mmn-card-for-ab-test" |
Conventions
This is how I write code.
HTML Elements
Element | Condition |
---|---|
<a> | It must link to an anchor on the same page or to a different page. |
Always declare the href attribute and it cannot be empty. |
|
Never use it for performing a function only. | |
<button> | It must perform a function. |
Always declare the type attribute and it cannot be empty. Otherwise it defaults to type="submit" and can be harmful to unrelated forms on the page. |
|
Never use it for linking. | |
<input type="button"> | Use <button> with the proper type attribute instead. |
<input type="reset"> | |
<input type="submit"> | |
<img> | Always declare the alt attribute. The value can be left empty if the image is decorative. |
HTML Attributes
Attribute | Condition | Example |
---|---|---|
title | In general, avoid using the title attribute on any HTML element. |
Do: <nav aria-label="Main Navigation"> <img alt="Image of a banana"> |
Don’t: <nav title="Main Navigation"> <img title="Image of a banana"> |
||
role | Never use the role attribute on a semantic element that doesn’t need it. |
Do: <div role="article"> <div role="navigation"> <div role="list"> |
Don’t: <article role="article"> <nav role="navigation"> <ul role="list"> |
SCSS/CSS Property Order
@extend;
@include;
'content',
// Display
'display',
'grid',
'grid-*',
'flex',
'flex-*',
'justify-*',
'align-*',
'place-*',
'order',
'box-sizing',
'appearance',
'visibility',
'opacity',
// Position
'position',
'top',
'right',
'bottom',
'left',
'float',
'clear',
'transform',
'z-index',
// Size
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
'overflow',
// Space
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'margin-inline-*',
'margin-block-*',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'padding-inline-*',
'padding-block-*',
// Font
'font',
'font-family',
'font-style',
'font-size',
'font-size-adjust',
'font-weight',
'font-feature-settings',
'font-kerning',
'font-stretch',
'font-synthesis',
'font-optical-sizing',
'font-language-override',
'font-variant',
'font-variant-alternates',
'font-variant-caps',
'font-variant-east-asian',
'font-variant-ligatures',
'font-variant-numeric',
'font-variant-position',
'font-variation-settings',
// Text
'list-style',
'list-style-image',
'list-style-position',
'list-style-type',
'counter-increment',
'counter-reset',
'color',
'line-height',
'text-align',
'text-indent',
'text-decoration',
'text-transform',
'text-shadow',
'letter-spacing',
'vertical-align',
'cursor',
'pointer-events',
'user-select',
// Border
'border',
'border-top',
'border-top-color',
'border-top-style',
'border-top-width',
'border-top-right-radius',
'border-top-left-radius',
'border-right',
'border-right-color',
'border-right-style',
'border-right-width',
'border-bottom',
'border-bottom-color',
'border-bottom-style',
'border-bottom-width',
'border-bottom-right-radius',
'border-bottom-left-radius',
'border-left',
'border-left-color',
'border-left-style',
'border-left-width',
'border-radius',
'border-width',
'border-style',
'border-color',
'border-image',
'border-image-outset',
'border-image-repeat',
'border-image-slice',
'border-image-source',
'border-image-width',
'box-shadow',
'outline',
// Background
'background',
'background-attachment',
'background-clip',
'background-color',
'background-image',
'background-origin',
'background-position',
'background-position-x',
'background-position-y',
'background-repeat',
'background-size',
'backdrop-filter',
// Advanced
'filter',
'clip',
'backface-visibility',
'will-change',
'transition',
'animation',
'animation-delay',
'animation-direction',
'animation-duration',
'animation-fill-mode',
'animation-iteration-count',
'animation-name',
'animation-play-state',
'animation-timing-function',