Appearance
Frontend Standards
General
- No commented out code
- Avoid magic numbers
- Avoid inline css
- Always look to the design system for guidance
- Mobile first CSS
- Think accessibly
HTML
- Prefer semantic tags whenever possible
- Always use self closing tags where possible
- New line for each attribute if more than 1
- 2 spaces per indent
- Inner contents of a tag should be on a new line
CSS
- Prefer css variables whenever possible
- Use postcss for css tools like nesting & browser compatibility
- Use CSS Modules for scoping, and scope to a $s . CSS modules is preferable to scoped because it doesn’t change the selection strength, and is more robustly scoped.
vue
<div class="$s.my-component">
...
<style module="$s">- Always use design system variables instead of hardcoding values for things like color, spacing, etc
- ❗️Never override the styles of a UI component from the design system. Instead, raise the issue to design or an architect so that it can be addressed in the design system.
- Use a combination of BEM and Suitcss
css
.card {}
.card__header {}
.card__header-title {}
/* Create new classes for modifiers. These do not override styles,
but rather define them differently */
.button--variant-primary {}
.button--variant-secondary {}
.button--variant-muted {}
/* Create override classes for states */
.button.disabled {}
.button.loading {}
.button.error {}- use kebab case in your classes
- use
__to separate elements - use
-to separate sub elements - use
--to separate modifiers - use boolean guidelines for naming states and nest them under the selector they’re affecting
- prefix modifiers if that modifier has several options
/* Bad */
.my-component--primary {}
.my-component--secondary {}
.my-component--small {}
.my-component--large {}
/* Good */
.my-component--variant-primary {}
.my-component--variant-secondary {}
.my-component--size-small {}
.my-component--size-large {}Javascript
When used all together, these rules allow you to write very concise code that is self documenting
- Use clear function names like
submitForm()vshandleClick() - Use clear variable names like
elementHeightvsh - If comments feel necessary, look to the function or variable names to see if they can be made more clear first
- Booleans should be affirmative and singular if possible or begin with is or has
javascript
// Bad
notEnabled
isFullwidth
labelPresent
// Good
disabled
fullwidth // doesn't need an "is-" to make sense
hasLabel- Use arrow functions over for loops
- Include only one return per function
- Use ternary operators whenever possible, if it does not add complexity (avoid nested ternary operators or complex boolean logic)
javascript
// Bad
if (someBool) {
resultString = 'foo'
} else {
resultString = 'bar'
}
// Good
resultString = someBool ? 'foo' : 'bar'- Use template literals to do string concatenation
javascript
// Bad
return prefix + 'some string' + suffix
// Good
return `${prefix} some string ${suffix}`Vue
- Always use single file components (SFC)
- Group code in a SFC by concern, with all the data and methods for each functional concern together rather than grouping all data, then all computed then all methods etc
- Use kebab case for imported components
// Bad
<CiButton />
// Good
<ci-button />- Prefer simple props to object props whenever possible
// Bad
<avatar options="{image: '', name: '', profileUrl: ''}" />
// Good
<avatar image="" name="" profile-url="" />- Prefer computed props for event propagation
// Bad
let someValue = '' as string
function updateValue() {
someValue = newValue;
emits('myEvent', newValue)
}
// Good
let someValueData = '' as string
const someValue = computed({
get () {
return someValueData;
},
set (val: string) {
someValueData = val;
emits('myEvent', val)
}
})
function updateValue() {
...
someValue.value = newValue;
}- Always use component class name that follows the
CiComponentNamenaming scheme
// Bad
export default {
name: 'Modal'
}
// Good
export default {
name: 'CiModal'
}Vuex
- Only write simple mutations
- Getters can be provided when digging into arrays/objects is necessary in multiple places
- Prefer object of objects to array of objects, for easier getting
Components
- Components should each have a singular concern
- Components should be broken down into multiple components or shared helpers if they become too complex
- A component that is universal and not specific to a feature or application should go in the design system