We Create Digital: Frontend Coding Standards
Welcome to our Frontend Coding Standards document. In the fast-paced world of web development, creating exceptional user experiences relies on consistent, well-organised code. These standards serve as a compass for our frontend team, ensuring our web applications are visually appealing, performant, and maintainable.
Our frontend coding standards cover everything from HTML, CSS, and JavaScript to accessibility and modern tooling. By adhering to these guidelines, we aim to:
- Enhance user experience and application aesthetics.
- Enable seamless collaboration and code reviews.
- Optimize performance for faster web applications.
- Prioritize accessibility for inclusivity.
- Stay updated with industry best practices.
Thank you for your commitment to these standards, and let's create amazing web applications together.
New Projects
HTML
- Use Lowercase for HTML Tags: Write HTML tags in lowercase for consistency and readability. While HTML is case-insensitive, lowercase tags are a widely accepted convention.
- Indentation and Formatting: Use consistent indentation (4 spaces) to make your code more readable. Group related elements together and use line breaks to separate different sections. To set this go to VSCode settings, search for 'Tab Size' and change to 4.
-
Use Semantic HTML: Choose HTML elements that semantically represent the content. For example, use
<header>
,<nav>
,<main>
,<section>
,<article>
,<aside>
and<footer>
elements to structure your documents logically. - Proper Nesting: Ensure that HTML tags are properly nested. Opening and closing tags should match, and elements should not overlap.
-
Attribute Quoting: Always use double quotes around attribute values ("). For example:
<a href="https://www.example.com">
. -
Use Self-Closing Tags: For void elements like images and line breaks, use the self-closing syntax (e.g.,
<img src="image.jpg" />
or<br />
) to improve clarity. - Comments: Add comments to your code to label components (if it's a large chunk of HTML - not it's own component) and sections.
-
HTML5 Doctype: Start your HTML document with the HTML5 doctype declaration:
<!DOCTYPE html>
. -
Language Attribute: Specify the language of your document using the lang attribute on the
<html>
element, like<html lang="en">
. -
Character Encoding: Include the character encoding declaration in your
<head>
to ensure proper text encoding:<meta charset="UTF-8">
. -
Title Element: Provide a descriptive and unique
<title>
element in the<head>
of your document for accessibility and SEO. -
Avoid Deprecated Elements: Avoid using deprecated HTML elements and attributes, such as
<font>
,<center>
, and inline styling with the style attribute. - Aria Roles and Attributes: When developing accessible websites, use ARIA (Accessible Rich Internet Applications) roles and attributes to enhance screen reader compatibility.
-
Responsive Design: Design and structure your HTML with responsiveness in mind, making sure your pages look good on various devices and screen sizes. In developer tools add common screen sizes to the device toolbar e.g.
- Laptop: 1440x900
- Full HD: 1920x1080
- 2K: 2560x1440
- 4K: 3840x2160.
-
Avoid Inline JavaScript and CSS: Separate your JavaScript and CSS from your HTML by using external files or in the
<head>
section if possible. Minimize the use of inline scripts and styles.
PHP, Blade & Laravel
- HTML Markup: When writing HTML within PHP use the same principals as mentioned above to keep code clean, readable and easy to work with.
- Minimize PHP Logic in Templates: Limit PHP logic in your templates to basic loops, conditionals, and variable assignments. Complex business logic should be kept in separate PHP files (usually controllers and/or composers).
- Code Reusability: Create reusable components or partials to avoid duplicating PHP and HTML code in multiple templates. Include these components where needed. Use Tailwind components (mentioned below) for single element components, use php components and partials for multi-element components.
CSS, SASS, LESS, Tailwind CSS (and Other Frameworks)
- Using Tailwind CSS: Tailwind will be used for the majority of new projects. It can be used to fulfill almost any styling need and should be used before turning to CSS, SASS or LESS.
- Tailwind Config: Replace and extend existing Tailwind classes within the Tailwind Config this is especially helpful for custom colours, shadows and breakpoints. Try to keep the modification of this file to a minimum and extend the theme rather than replace default classes.
-
Tailwind Components: If there are components which are used commonly throughout a project (like
<button>
's,<input />
's,<select>
's) create acomponents.css
file and use directives. Use Tailwinds@layer components {}
directive and include a custom class within there using the@apply
to apply Tailwind classes.
/**
* 'components.css/components.scss/components.less'
*/
@layer components {
.btn {
@apply ...Tailwind classes,
}
}
-
Tailwind Component Variants: You may need multiple variants of a particular component. If this is the case specify the static classes within the root class
.btn
then add the variable classes to their own subclass.btn.primary
,.btn.secondary
,.btn.tertiary
etc. -
Separating Out CSS: Have one main app file (
app.css
,app.scss
orapp.less
) which only imports Tailwind directives and other files which are separated out into logical sections or componenets (header.css
,footer.css
,checkout.css
,blog.css
,components.css
etc.). - Use Consistent Naming Conventions: Using meaningful and descriptive class and ID names. Use the SMACSS convention consistently throughout a project.
-
Avoid Overqualified Selectors: Avoid specifying redundant selectors like
div.container
when a class selector would suffice.container
. - Organize Styles: Group related styles together to improve code organization. Use comments to separate sections of your CSS file.
- Keep Selectors Specific: Avoid overly broad selectors that could unintentionally affect multiple elements.
-
Avoid
!important
: Minimize the use of!important
, as it can make it challenging to debug and maintain your styles. Alternatively use a more specific selector.example-app > .section > .block > .component-to-style
. -
Responsive Design: Use the Tailwind
.container .mx-auto
for responsive sections/blocks alongside breakpoints Tailwind provides. Add extra and modify existing breakpoints within thetailwind.config.js
if needed (.xs:
,.3xl:
, etc.) If not using Tailwind use@media
queries for responsive design. - Minimize Use of Inline Styles: Keep styling within CSS files and avoid inline styles in your HTML unless absolutely necessary (making an element hidden straight away when JS is loading in with Alpine.JS).
- Reduce Duplication of Styling: If there are two or more elements with identical styling but different selectors use DRY (Don't Repeat Yourself) principals. Separate classes with a comma over duplicating the same code.
.class-1,
.class-2 {
...styling
}
SASS and LESS Specific
- When To Use SASS, LESS: If the project is using Tailwind, keep SASS and LESS to a minimum and use only as an absolute last resort. If not using Tailwind or CSS make sure to use exclusively keeping all of the CSS conventions in mind and leveraging conventions like variables, mixins and extending/inheritance.
- Nesting: Leverage nesting to keep related styles together and make the code more organized. Avoid excessive nesting, which can lead to overly specific selectors and increased CSS specificity. Continue using the SMACSS naming convention
JavaScript
-
Consistent Naming Conventions: Use descriptive and meaningful names for variables, functions, objects and classes. Use
camelCase
for declared variables and functions,UpperCamelCase
for classes, andsnake_case
for variables obtained from a database. -
Use Strict Mode: Enable strict mode by including
"use strict"
; at the beginning of your JavaScript files to catch common programming mistakes. - Indentation and Formatting: Use a 4 space tab size to make your code more accessible. This can be altered in VSCode preferences. Maintain a clean and consistent code style, and consider using a code formatter like Prettier.
- Commenting: Include comments using JSDoc style comments to explain the purpose of variables, functions, classes, and complex code sections. This can be used to generate automated documentation later down the line if needed.
- ESLint or JSHint: Use linters like ESLint or JSHint to enforce coding standards and catch potential issues.
-
Modular Code & Object Orientated Programming: Organize your JavaScript code into modules containing classes for specific functionality/components to promote reusability and maintainability. Use the main
app.js
file to import these files
/**
* 'checkout.js'
*/
'use strict';
class Checkout {
variable;
constructor (variable) {
this.variable = variable;
}
processPayment() { /* ...functionality */ }
// ...Other functionality
}
export default Checkout;
/**
* 'app.js'
*/
'use strict';
import Checkout from './modules/checkout';
// ... more imports
const checkout = new Checkout(variable);
// ... more declarations
- Avoid Global Variables: Minimize the use of global variables to prevent naming conflicts and unexpected side effects.
- Destructuring: Use object and array destructuring to simplify code and make it more readable.
- Function Length: Avoid creating long functions with multiple pieces of functionality within it. Try to abstract out each piece on functionality to its own function.
class Checkout {
// ...class declaration
async processPayment(checkoutSession) {
const paymentIntent = await this.getPaymentintent();
const paymentDetails = this.getPaymentDetails();
await this.finalisePayment(checkoutSession, paymentIntent, paymentDetails);
}
// ...more functions and end of class
}
- Arrow Functions: Use arrow functions for concise anonymous functions and to preserve the context of this.
-
let
andconst
: Preferlet
andconst
overvar
for variable declarations to improve variable scoping and prevent unintended reassignments.-
let
is for variables that are allowed to change -
const
is for variables that are not allowed to change
-
- Template Literals: Use template literals (backticks) for string interpolation and multi-line strings.
const compliment = `${name} is awesome!`;
- Promises and Async/Await: Use Promises and async/await to manage asynchronous operations, enhancing code readability and error handling.
- Default Parameters: Make use of default function parameters to simplify function calls and handle missing values.
const favColour = (colour = 'blue') => {
return `My favourite colour is ${colour}`;
}
- Spread and Rest Operators: Apply the spread operator (...) for array/object copying and the rest operator for variable-length argument handling.
- Try-Catch Blocks: Wrap code that may throw exceptions in try-catch blocks to handle errors gracefully.
Legacy Projects
Legacy projects will have different style codebases to work from. Unless there is budget in the project to refactor the code, you should try to stick to the code conventions used in that particular project.
Spend some time getting accustomed to any differences that there may be in the codebase to these standards. Below are lists of where you may find differences in some of the codebases. Try to stick to our standards as much as possible unless listed below.
HTML
- Indentation and Formatting: Some projects may have a 2 space instead of 4 space tab sizing. Alter your settings depending on the project.
- Use Semantic HTML: Some older projects may not use semantic HTML as well as newer projects. Try to always use semantically correct HTML markup.
CSS, SASS, LESS, Tailwind CSS (and Other Frameworks)
-
Using Tailwind: Some projects may or may not use Tailwind. If they do, try to stick to the
config
file already in place and only add colours if necessary. If they don't try to analyse the current CSS that's already in place and stick to conventions already being used. - Separating Out CSS: It is likely that CSS would have been split out into multiple files already. Try to work within the correct CSS file for what you are working on and create new CSS files for new components/sections.
- Use Consistent Naming Conventions: There are multiple naming convetions within CSS, the most common are the SMACSS convention and the BEM convention attempt to stick to what convention is already in place.
JavaScript & jQuery
- Using Strict Mode: Stick to the conventions already in place. If there is no strict mode being used, keep it that way for any new files created.
- Indentation and Formatting: Some projects may have a 2 space instead of 4 space tab sizing. Alter your settings depending on the project.
- Commenting: Try to stick to the commenting conventions already in place.
- Modular Code, Object Orientated Programming & jQuery: There will be a large variation in how JavaScript has been written in older projects. Some may be modular whereas other may be in a single file, some may be jQuery and some may use object oriented programming. Try to stick to the conventions already in place for the particular project.
- Arrow Functions: Try to stick to the style of functions that are already in place.
// Classic function
function helloWorld() {
console.log('Hello world');
}
// Arrow function
const helloWorld = () => console.log('Hello world');
-
let
,const
andvar
: Try to stick to the conventions that are already in place. Use either:- Only
var
or -
const
andlet
- Only
-
Promises, Async/Await and then: For promises try to analyse whether the code is using
async
andawait
or.then(function(res) {})
. Stick to conventions already in place, if there is neither, stick to our code standards.