Professional Documents
Culture Documents
GUILDS CSSbestpractices 050721 1656 30
GUILDS CSSbestpractices 050721 1656 30
Status DEFINITION
3. Variables
4. Mobile-first approach
5. Naming conventions
6. Rules
7. Formatting / ordering
Pre-processor
We're using SCSS as our CSS extension language.
Some older projects may use LESS, but going forward SCSS is preferred.
http://sass-lang.com/guide
Organising/structuring
Have a logical method to organising files
Each file should have a specific purpose
ITCSS is one method to solving this
Variables
Rules
Use conventions.
Good rule is to prefix the variable with the name of the component
Prefix global variables with global
Use semantic naming
Name based on function or purpose, not how it looks
Make use of variable maps
Use this tool to name your colours. Read more
Manage z-index's in a single variable map
Separate into multiple files
Keep lowercase, hyphen-separated
Further reading
https://davidwalsh.name/sass-color-variables-dont-suck
http://thesassway.com/beginner/variable-naming
https://webdesign.tutsplus.com/articles/quick-tip-name-your-sass-variables-modularly--
webdesign-13364
Naming examples
// colors.scss
$color-flush-orange: #ff8200;
$color-valhalla: #211551;
$color-deep-koamaru: #171c8f;
$color-persian-blue: #232ad8;
// fonts.scss
$font-family-brand: "Gotham Rounded SSm A", sans-serif;
$font-family-content: "Open Sans", sans-serif;
// variables.scss
// Example of using a variable map
$global-container-padding: (
"mobile": 1.6rem,
"tablet": 2.4rem,
"desktop": 3.2rem
);
$global-border-radius: .3rem;
z-index management
// z-index layers. All z-index values have to be declared here, and use
// the get-z() function
$zindex-layers: (
"modal" : 1000,
"dimmer" : 800,
"header" : 500,
"footerSticky" : 400,
"default" : 1,
"zero" : 0,
"below" : -1
);
.header {
...
z-index: get-z("header");
}
Mobile-first approach
What is it?
Is a tenet of progressive enhancement.
Writing mobile styles first, then using min-width media queries to introduce larger-display styles
as they're needed.
The opposite would mean you write desktop-styles first then having to reset properties on small
devices, which can result in more code.
Why?
Code for larger screens is often more complex than mobile.
If your site is good on mobile, that will likely translate well up to larger devices
MQ Mixin
MQ mixin is a third-party mixin that makes media queries easy and intuitive to use. Read more
Highly recommended to use this in your project
Example
Two ways of styling the same component. Desktop-first approach having to use more lines of code.
Note: Rather than using @media (min-width: 768px) I'm using the MQ mixin, which generates the
same thing.
Mobile-first approach
.foo {
padding: 10px;
font-size: 14px;
Naming conventions
What we want is to be able to write code that is as transparent and self-documenting as possible.
Transparency means that it is clear and obvious (to others) in its intent; self-documenting means that we
don’t have to lose time to writing and reading lengthy, supplementary documentation.
What is BEM?
[block]
[block]--[modifier]
[block]__[element]
[block]__[element]--[modifier]
// Avoid this
[block]__[element]__[element]
Why BEM?
BEM naming provides three specific benefits:
Extending BEM
Javascript prefix. Signify that this piece of the DOM has some behaviour acting upon it, and
that JavaScript binds onto it to provide that behaviour. These will not have any CSS associated
with them. e.g. .js-component-name
If using ITCSS as your CSS architecture, we recommend extending BEM to BEMIT. Full
explanation here
Examples
We highly recommend reading this article for detailed examples:
https://seesparkbox.com/foundry/bem_by_example
Further reading
http://getbem.com/introduction/
https://css-tricks.com/bem-101/
Rules
Code smells in CSS - Part 1
Avoid undoing styles
Avoid magic numbers (a value used because 'it just works')
Avoid qualified selectors (styles attached to element)
Use unitless values for line-heights
Avoid brute-force CSS
Careful of wide-reaching selectors
Use !important proactively, not reactively
Don't style ID's
Avoid ambiguous class names
Code smells in CSS - Part 2
Careful with use of @extends
Avoid string concatenation for classes (useing & to concat strings in your classes)
Use full background properties instead of shorthand
Key selector appearing more than once
Key selector shouldn't appear in another file
Use flexbox
Use autoprefixer in your build process
Provide fallback support for non-supporting browsers (IE9)
Classnames should be lowercase, hyphenated, and specific
Try avoid nesting where possible (adds specificity), and limit to 3 levels deep where you cannot.
One selector per line, one rule per line
Use plenty of comments
Media queries should be declared inside a selector. Do not wrap multiple selectors inside a
media query.
This ensures each selector is only written once. Makes it easier when performing a
search as there's one source of truth for a class.
Use rem's for your units. Set it up so 1rem = 10px (example below)
Where allowed, avoid specifying units for zero-values, e.g. margin: 0;
Omit the zero from any values below one. e.g. .5rem instead of 0.5rem
Favour double-quotes over single-quotes
Calculations should be in brackets. e.g. padding: ($global__padding * 2) 3rem;
Use Stylelint and editorconfig to maintain standards
Example Stylelint setup on AustralianSuper Employer Portal
Example editorconfig setup on AustralianSuper Employer Portal
// Good
.credit-card-panel,
.my-component-name {
width: 10rem;
height: 10rem;
margin: 0;
}
// Bad
.red, .myComponentName, .my_component_name {
width: 10rem; height: 10rem;
margin: 0px;
}
Nesting
// Good
.credit-card {}
.credit-card__image {}
.credit-card__title {
.icon {}
}
// Bad
.credit-card {
.credit-card__image {}
.credit-card__title {
.icon {}
}
}
Set up 1rem = 10px
body {
font-size: 1.6rem;
}
Media queries
// Good
.foo {
...
.bar {
...
// Bad
.foo {
...
}
.bar {
...
}
.bar {
...
}
}
.bar {
...
}
}
Commenting
// GOOD:
// BAD:
.accordion__item {
display: flex;
margin: 0; // Fixes weird IE9 display issue
color: red;
appearance: none; // Remove default appearance, particularly on mobile
OS' such as iOS
Formatting / ordering
Property Ordering
Ordering properties in a consistent manner can speed up debugging and reduce errors.
Here's one way of grouping by type. Within the groups, it's not imperative that it follows this exact order, e.
g. height could come before width and vice versa
Property ordering
// Group properties by type. positioning first, then display & box model,
then other
// Ordering within the group isn't as important, just be consistent.
// https://css-tricks.com/poll-results-how-do-you-order-your-css-
properties/
.selector {
// Positioning
position: absolute;
z-index: 10;
top: 0;
right: 0;
bottom: 0;
left: 0;
// Other
background-color: $color__black;
color: $color__white;
font-family: sans-serif;
font-size: 1.6rem;
text-align: right;
}
Selector ordering
Having a consistent pattern for ordering inside a selector can help
Selector ordering
.selector {
// @extends
// @includes
// regular properties
// @media queries
// --modifiers
// parents - modified behaviour when in given parent context
// :pseudo selectors
// child selectors (ideally these wouldn't be nested inside a selector)
}
// Example
// 1. Here is an example comment
// 2. Necessary for weird Firefox bug
// 3. Necessary to override default styling of <small>
.selector {
@extend %subtle-link-transition;
@include fancyTransition("fade", 4);
position: relative;
display: inline-block; // [1]
@include mq($from: "tablet") {
padding: 0;
background-color: red;
}
&:hover {
background-color: purple;
}
&.selector--modifier {
background-color: black;
}
&.selector--is-state {
background-color: black;
}
// Child element
.small {
font-size: 1.2rem; // [3]
}
}
// Child element
.small {
font-size: 1.2rem;
}
position: absolute;
&.selector--modifier {
background-color: black;
}
&.selector--is-state {
background-color: black;
}
&:hover {
background-color: purple;
}
color: red;
@extend %subtle-link-transition;
@include fancyTransition("fade", 4);
}