CSS Coding Standards - spthemes/best-practices GitHub Wiki

Organizing

Stylesheets in third-party themes are encouraged (but not required) to match StudioPress-style organizing strategies. This helps users feel like your theme is "familiar" when purchasing, and is a good user experience decision. Generally, this means:

  • Including a Table of Contents.
  • Minifying third-party CSS blocks, like Normalize.css styles.
  • Positioning media queries all together and at the bottom, instead of in-line.

An example to follow and use as a reference is the Genesis Sample theme's stylesheet.

Structure

  • Use hard tabs, not spaces, to indent each property.
  • Add two blank lines between sections and one blank line between blocks in a section and subsections.
  • Each selector should be on its own line, ending in either a comma or an opening curly brace. Property-value pairs should be on their own line, with one tab of indentation and an ending semicolon. The closing brace should be flush left, using the same level of indentation as the opening selector.

Correct:

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

Incorrect:

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

Selectors

With specificity, comes great responsibility. Broad selectors allow us to be efficient, yet can have adverse consequences if not tested. Location-specific selectors can save us time, but will quickly lead to a cluttered stylesheet. Exercise your best judgement to create selectors that find the right balance between contributing to the overall style and layout.

  • Use lowercase and separate words with hyphens when naming selectors. Avoid camelcase and underscores.
  • Use human readable selectors that describe what element(s) they style.
  • Attribute selectors should use double quotes around values.
  • Refrain from using over-qualified selectors, div.container can simply be stated as .container.
  • Use classes over ids.
  • Group selectors by specificity (element, class, id) and then by alphabetical order.

Correct:

a,
button,
input:focus,
input[type="button"],
input[type="reset"],
input[type="submit"],
textarea:focus,
.button,
.gallery img,
#my-section a {
	-webkit-transition: all 0.1s ease-in-out;
	-moz-transition:    all 0.1s ease-in-out;
	-ms-transition:     all 0.1s ease-in-out;
	-o-transition:      all 0.1s ease-in-out;
	transition:         all 0.1s ease-in-out;
}

Incorrect:

.commentForm { /* Avoid camelcase. */
    margin: 0;
}
 
.comment_form { /* Avoid underscores. */
    margin: 0;
}
 
div.comment_form { /* Avoid over-qualification. */
    margin: 0;
}
 
.c1-xr { /* What is a c1-xr?! Use a better name. */
    margin: 0;
}
 
input[type=text] { /* Should be [type="text"] */
    line-height: 110% /* Also doubly incorrect */
}

Properties

Similar to selectors, properties that are too specific will hinder the flexibility of the design. Less is more. Make sure you are not repeating styling or introducing fixed dimensions (when a fluid solution is more acceptable).

  • Properties should be followed by a colon and a space.
  • All properties and values should be lowercase, except for font names and vendor-specific properties.
  • Use hex code for colors, or rgba() if opacity is needed. Avoid RGB format and uppercase, and shorten values when possible: #fff instead of #FFFFFF.
  • Use shorthand (except when overriding styles) for background, border, font, list-style, margin, and padding values as much as possible. (For a shorthand reference, see CSS Shorthand.)

Correct:

.selector-1 {
    background-color: #fff;
    display: block;
    margin: 0;
    margin-left: 20px;
}

Incorrect:

.selector-1 {
    background:#FFFFFF;
    display: BLOCK;
    margin-left: 20PX;
    margin: 0;
}

Property Ordering

Properties should be listed in alphabetical order.

Example:

.overlay {
    background: #fff;
    color: #777;
    padding: 10px;
    position: absolute;
    z-index: 1;
}

Vendor Prefixes

Vendor prefixes should also be listed alphabetically with prefixes (-webkit-) listed above the unprefixed property. Values should be lined up using spaces.

Example:

.sample-output {
    -webkit-box-shadow: inset 0 0 1px 1px #eee;
    -moz-box-shadow:    inset 0 0 1px 1px #eee;
    box-shadow:         inset 0 0 1px 1px #eee;
}

Values

There are numerous ways to input values for properties. Follow the guidelines below to help us retain a high degree of consistency.

  • Space before the value, after the colon
  • Do not pad parentheses with spaces
  • Always end in a semicolon
  • Use double quotes rather than single quotes, and only when needed, such as when a font name has a space.
  • Font weights should be defined using numeric values (e.g. 400 instead of normal, 700 rather than bold).
  • 0 values should not have units unless necessary, such as with transition-duration.
  • Line height should also be unit-less, unless necessary to be defined as a specific pixel value.
  • Use a leading zero for decimal values, including in rgba().
  • Multiple comma-separated values for one property should be separated by either a space or a newline, including within rgba(). Newlines should be used for lengthier multi-part values such as those for shorthand properties like box-shadow and text-shadow. Each subsequent value after the first should then be on a new line, indented to the same level as the selector and then spaced over to left-align with the previous value.

Correct:

.class { /* Correct usage of quotes */
    background-image: url(images/bg.png);
    font-family: "Helvetica Neue", sans-serif;
    font-weight: 700;
}
 
.class { /* Correct usage of zero values */
    font-family: Georgia, serif;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5),
                 0 1px 0 #fff;
}

Incorrect:

.class { /* Avoid missing space and semicolon */
    background:#fff
}
 
.class { /* Avoid adding a unit on a zero value */
    margin: 0px 0px 20px 0px;
}
 
.class {
    font-family: Times New Roman, serif; /* Quote font names when required */
    font-weight: bold; /* Avoid named font weights */
}

Media Queries

Media queries allow us to gracefully degrade for different screen sizes. Be sure to test above and below the break-point you are targeting.

  • Keep media queries grouped by media at the bottom of the stylesheet.
  • Rule sets for media queries should be indented one level in.

Example:

@media all and (max-width: 699px) and (min-width: 520px) {
 
        /* Your selectors */
}

Commenting

  • Long comments should manually break the line length at 80 characters.
  • A table of contents should be utilized for longer stylesheets, especially those that are highly sectioned.
  • Section/subsection headers should have newlines before and after. Inline comments should not have empty newlines separating the comment from the item to which it relates.

For sections and subsections:

/* Section Title
---------------------------------------------------------------------------------------------------- */

/* Subsection Title
--------------------------------------------- */
 
.selector {
    float: left;
}

For inline:

/* This is a comment about this selector */
.another-selector {
    position: absolute;
    top: 0 !important; /* I should explain why this is so !important */
}

Best Practices

  • If you are attempting to fix an issue, attempt to remove code before adding more.
  • Target the element you want to use as opposed to “finding it” through its parents. Example: Use .highlight on the element as opposed to .highlight a (where the selector is on the parent).
  • Do not restate default property & value combinations (for instance display: block; on block-level elements).