CSS Coding Standards


These standards are based on the CSS section of the official WordPress Coding Standards, but have been adapted and extended to cover the SCSS workflow and our starter theme.

Structure

  • Use tabs to indent, not spaces.
  • When targeting multiple selectors, each should be in its own line.
  • Property-value pairs should be on their own line and end with semicolon.
  • In Sass, add empty newline before each nested selector.
  • Closing brace should be indented on the same level as the opening selector. This becomes even more important when nesting elements in Sass.

Correct

.selector-1,
.selector-2,
.selector-3 {
  background: #fff;
  color: #000;
}

.selector {
  margin: 0;  

  input {
    margin: 0;
  }
}

Incorrect

// Each selector should be on a new line
.selector-1, .selector-2, .selector-3 {
  background: #fff;
  color: #000;
}

// Each property-value pair should be on a new line
.selector { background: #fff; color: #000; }

.selector {
  background: #fff // Always end with semicolon
}

.selector {
  margin: 0;
  input { // Add empty newline before nested selectors
    margin: 0;
 } // Indent must match the opening selector
}

Selectors

  • Selector names should be clear and descriptive.
  • Use lowercase and hyphens for separate words.
  • Don’t use camelcase or underscores.
  • Attribute selectors should use double quotes around values.
  • Avoid using over-qualified selectors like div.element-name.

Correct

.selector-name {
  margin: 0;
}

input[type="text"] {
  margin: 0;
}

Incorrect

.selectorName { // Avoid camelcase
  margin: 0;
}

.selector_name { // Avoid underscores
  margin: 0;
}

div.selector-name { // Avoid over-qualification
  margin: 0;
}

input[type=text] { // Wrap values in double quotes 
  margin: 0;
}

Properties

  • Properties should be followed by a colon and a space.
  • All properties and values should be lowercase.
    • Font names and vendor specific properties are an exception.
  • Use shorthand values for background, border, font, list-style, margin and padding when possible, but not for overriding styles.
  • Use hex code for colors. If opacity is needed, use rgba().
  • Shorten values when possible: use #fff instead of #ffffff.
  • Vendor prefixes such as -webkit-box-shadow and -moz-box-shadow are automatically taken care of by our starter. There is no need to explicitly set them.
  • In Sass, avoid using hex colors directly in the code. Define common colors using CSS variables (in _variables.scss in our starter) and use those variables instead.

Correct

.selector {
  color: #fff;
}

.selector {
  margin: 0;
  margin-left: 1rem;
}

// SCSS
--color-white: #fff; // Set these in _variables.scss

.selector {
  background: var(--color-white);
}

Incorrect

.selector {
  color:#fff; // Leave a space between property and value
}

.selector {
  color: #FFF; // Avoid uppercase
}

.selector {
  color: #ffffff; // Shorten values when possible
}

.selector {
  margin-left: 1rem;
  margin: 0; // Don't override with a shorthand
}

// SCSS
.selector {
  background: #fff; // Use color variables
}

Property ordering

  • Group related CSS properties together in a meaningful way rather than leaving them random. There are no absolute rules, but doing so improves readability and maintainability. Example:
    • Display
    • Positioning
    • Box model
    • Colors and Typography
    • Other
  • Within groups, order properties logically.
  • For directional properties, a common convention is toprightbottomleft. This isn’t absolute – use whatever order is meaningful to you and use it consistently.
  • Corner properties (e.g., border-radius) should follow top-lefttop-rightbottom-rightbottom-left.

Values

  • WordPress Coding Standards recommends using doublequotes instead of singlequotes for values, but this is a matter of preference. Whichever you choose, use them consistently.
  • According to WordPress Coding Standards, url() does not require quotes, but this is also a matter of preference. Use your chosen format consistently.
  • Quotes should only be used in font names that have spaces or special characters.
  • font-family should always include fallbacks, at least serif / sans-serif.
  • Font weights should be defined using numeric values (e.g. 400 instead of normal700 rather than bold).
  • 0 values should not have units unless necessary, such as with transition-duration.
  • Line height should also be unitless, unless necessary.
  • Use a leading zero for decimal values, including in rgba().
  • Lists of values within a value, like within rgba(), should be separated by a space.
  • Multiple comma-separated values for one property should be separated by either a space or a newline.
  • Newlines should be used for lengthier multi-part values such as shorthand properties like box-shadow and text-shadow, including before the first value. Values should then be indented one level in from the property.

Correct

.selector {
  font-family: "Open Sans", Arial, sans-serif;
}

.selector {
  margin: 0 0 20px 0;
}

.selector {
  font-weight: 700;
}

.selector {
  line-height: 1.5;
}

.selector {
  opacity: 0.5;
}

.selector {
  color: rgba(0, 0, 0, 0.5);
}

.selector {
  text-shadow: 0, 0, 0, rgba(0, 0, 0, 0.5);
  box-shadow:
    0 0 0 rgba(0, 0, 0, 0.5),
    1px 1px 1px rgba(0, 0, 0, 0.5);
}

Incorrect

.selector {
  font-family: Open Sans; Quotes are necessary
  font-family: "Arial"; // Quotes not necessary
  font-family: Arial; // Always set fallback;   
}

.selector {
  margin: 0px 0px 20px 0px; // Omit units on zero values
}

.selector {
  font-weight: bold; // Avoid named font weights
}

.selector {
  line-height: 1.5em; // Avoid unit on line height
}

.selector {
  opacity: .5; // Add leading zero to decimals
}

.selector {
  color: rgba(0,0,0,0.5); // Add spaces between values
}

.selector {
  box-shadow: 0 0 0 rgba(0, 0, 0, 0.5), // Put on its own line 
  0 0 0 rgba(0, 0, 0, 0.5); // Indent one level from the property 
}

Media Queries

Let’s talk about media query practices in a future session about mobile first approach.

Commenting

  • Use comments to structure your SCSS files, especially long files.
  • Each SCSS file should at least have a section title at the top describing the basic function of the file.
  • Section header comments should have a newline before (except at the beginning of document) and after.
  • Long comments should manually break the line length at 80 characters.
  • Single line comments should not have empty newline between the comment and the item it relates to.
  • In Sass, use // instead of /* for single line comments.
/**
 * Section title
 * 
 * Description of a section 
 */

/**
 * Section title (no description) 
 */

// Comment about the selector
.selector {
  display: block; // Comment on a single line
}

Best practices

  • “Magic numbers” should be avoided. These mean arbitrary values that are usually used as quick fixes on a one-off basis.
  • Avoid hard-coded pixel values, use the rem() function available in our starter with pixel values to convert to rem. If possible, use values dividable by four (eg. 8, 16, 24, 32) to produce clean rem values. Exceptions: Large layout widths, heights, and breakpoints.
  • Avoid fixed widths and heights for elements that need to scale with content or screen size; most layout elements fall into this category.
  • Avoid using percentage and viewport-based values (except 100%, 100vw and 100vh) for widths and heights as they make layouts fragile and unpredictable).
  • Always add meaningful, targetable classes to elements instead of styling generic tags like span, p, or a.
  • DOM can change over time, try to target the elements you want to use directly as opposed to “finding them” through its parents, like .highlight a.
  • Do not restate default property and value combinations (for instance display: block; on block-level elements).
  • If you are attempting to fix an issue, attempt to remove or replace code before adding more.

Good practice

.selector {
  margin-top: rem(36px); // Outputs 2.25rem
  padding: rem(44px); // Outputs 2.75rem
}

.selector {
  width: 100%;
  max-width: 768px;
}

.selector {
  height: auto;
  min-height: 300px;
}

.selector {
  max-width: 1200px;
}

Bad practice

.selector {
  margin-top: 37px; // Arbitrary pixel value
  padding: 2.7rem; // Arbitrary rem value
  width: 73%; // Arbitrary percent value  
}

.selector {
  width: 768px; // Avoid fixed pixel values
  width: 75%; // Avoid fixed pergentage values
  width: 75vw; // Avoid fixed viewport values
}

.selector {
  height: 300px; // Avoid fixed pixel values
  height: 75%; // Avoid fixed percentage values
  height: 75vh;  // Avoid fixed viewport values
}

.selector {
  max-width: rem(1200px); // Use pixels for large values 
}