Last updated February 12, 2015. Created on January 14, 2013.
Edited by LewisNyman, emma.maria, lolandese, pfrenssen. Log in to edit this page.

Table of Contents

Whitespace
Comments
Format
Miscellaneous
Practical Example

Terminology

For those unfamiliar with CSS terminology, these are the concise terms used in these standards.

selector {
  property: value;
}

A rule set (also called a rule) consists of a selector followed by a declaration block.

The selector consists of everything up to (but not including) the first left curly brace ({).

A declaration block starts with a left curly brace ({) and ends with the matching right curly brace (}). In between there must be a list of zero or more semicolon-separated (;) declarations.

A declaration consists of a property name, followed by a colon (:), followed by a value.

Whitespace

Indentation

Do not use tabs for indentation. They lead to inconsistent display of the source code, since many text editors and most text viewers (like web browsers) cannot have their “tab size” configured.

Use 2 spaces for each level of indentation, the same standard as Drupal’s PHP and JavaScript code.

  • Declarations (property/value pairs) should be indented one level relative to their selector.
  • Rulesets within a media block or a media query should be indented one level relative to the media statement.
  • Comments should be indented the same amount as the declaration or ruleset they describe.
@media print {
  /* This line is indented with 2 spaces, 2 spaces x 1 level of indentation. */
  .example {
    /* This line is indented with 4 spaces, 2 spaces x 2 levels of indentation. */
    padding: 0;
  }
}

Blank lines

  • In general, do NOT separate each ruleset by a blank line.
  • If a ruleset has a proceeding Doxygen-style or single-line-style comment that describes it, place a blank line before the comment.
  • If two rulesets have no interleaving blank line, they must be logically related. If they are not logically related to each other, add a blank line and a comment describing the second ruleset.
/* A comment describing the ruleset. */
.selector-1,
.selector-2,
.selector-3[type="text"] {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  display: block;
  margin: 0;
  font-family: Times, "Times New Roman", sans-serif;
  color: #333;
  background: #fff;
  background: linear-gradient(#fff, rgba(0, 0, 0, 0.8));
}

/**
* A longer comment describing this ruleset. Note
* the blank line before the docblock.
*/
.selector-4,
.selector-5 {
  background-color: lime;
}

/* This logical grouping of rulesets has no interleaving blank lines. */
.profile {
  margin: 16px 0;
  margin: 1rem 0;
}
.profile__picture {
  float: right; /* LTR */
}

Line endings

There MUST NOT be any whitespace (spaces or tabs) at the end of lines. This means blank lines should also not contain any spaces or tabs. Inconsistent trailing whitespace can add lines to diffs/patches and makes changes harder to notice.

All text files should end with a single blank line. This makes git commits easier to read since it's clearer what is being changed when lines are added to the end of a file and it avoids the verbose \ No newline at end of file warning in patches.

Files should be formatted with Unix line endings (a newline character, denoted as \n or LF), which is also the default in Mac OS X. Do not use Windows line endings (a carriage return plus a newline, denoted as \r\n or CRLF).

Tip: configure your editor to “show invisibles”. This will allow you to eliminate end-of-line whitespace, eliminate unintended blank-line whitespace, and avoid polluting commits.

Drupal 8 includes an EditorConfig file in its root directory to help maintain these whitespace conventions.

Comments

Well commented code is extremely important. Take time to describe components, how they work, their limitations, and the way they are constructed. Don't leave others guessing as to the purpose of uncommon or non-obvious code.

To stay consistent with the rest of Drupal's code base, we borrow some of the CSS comment styles from the Doxygen and comment formatting conventions for PHP files.

File comments

Each file should start with a comment describing what the file does. For example:

/**
* @file
* Short description describing the file.
*
* The first sentence of the long description starts here and continues on this
* line for a while finally concluding here at the end of this paragraph.
*/

Note that a blank line should follow a file comment. And keep line-lengths to 80 columns, when possible. For more information, see the PHP file comment standards.

Multi-line comments

When describing a ruleset or set of rulesets, any comment that requires 2 or more lines (wrapped to 80 characters) must follow the Doxygen comment style (also called a “docblock”).

/**
* Short description using Doxygen-style comment format.
*
* The first sentence of the long description starts here and continues on this
* line for a while finally concluding here at the end of this paragraph.
*
* The long description is ideal for more detailed explanations and
* documentation. It can include example HTML, URLs, or any other information
* that is deemed necessary or useful.
*/
.example-rule {
}

Place the comment on the line immediately above the ruleset (or rulesets) it describes. Place a blank line before the docblock comment. See the Doxygen and comment formatting conventions for more info.

Single-line comments

When describing a property or ruleset, any comment that can be written inside the 80 character line length limit can use a simple CSS comment style.

.example {
  /* Override the default margins. */
  margin: 0;
}

/* This is a variant of the .example component. */
.example--item {
  display: inline;
}

Place the comment on the line immediately above the property or ruleset it describes. The comment should be indented the same amount as the property or ruleset it describes.

If the comment is describing a ruleset, place a blank line before the comment.

Styling for Right-To-Left Languages

It is common for RTL language websites to have their designs flipped in the left/right direction. For direction specific property/values, add the comment /* LTR */ on the same line preceded by a single space. In Drupal 6 and 7, the inclusion of a separate RTL stylesheet is automated. In Drupal 8, follow with an additional ruleset containing the inverse property/values, beginning with the attribute selector [dir="rtl"].

Example Rulesets for Drupal 6 and Drupal 7
[example.css]

.example-rule {
  float: left; /* LTR */
  margin-right: 24px;
  margin-right: 1.5rem; /* LTR */
  padding: 0 4px;
  padding: 0 0.25rem;
}

[example-rtl.css]

.example-rule {
  float: right;
  margin-left: 24px;
  margin-left: 1.5rem;
  margin-right: 0;
}

Example Rulesets for Drupal 8
[example.css]

.example-rule {
  float: left; /* LTR */
  margin-right: 24px;
  margin-right: 1.5rem; /* LTR */
  padding: 0 4px;
  padding: 0 0.25rem;
}
[dir="rtl"] .example-rule {
  float: right;
  margin-right: 24px
  margin-left: 1.5rem;
  margin-right: 0;
}

  • when you use the keywords, 'left' or 'right' in a property, e.g. float: left;
  • where you use unequal margin, padding or borders on the sides of a box, e.g. margin-left: 1rem; or padding: 0 0 0 2rem;
  • where you specify the direction of the language, e.g. direction: ltr;

Format

Our CSS formatting ensures the code is easy to read, easy to clearly comment, minimizes the chance of accidentally introducing errors, and results in useful Git diffs and blames.

Rulesets

  • Use one selector per line when a ruleset has a group of selectors separated by commas.
  • The opening brace ({) of a ruleset’s declaration block should be on the same line as the selector (or the same line as the last selector in a group of selectors.) The opening brace should include a single space before it.
  • Place the closing brace (}) of a ruleset in the same column as the first character in the selector of the ruleset.
  • Include one declaration per line in a declaration block.
  • Each declaration should be indented one level relative to its selector.
Example Ruleset
.selector-alpha,
.selector-beta {
  counter-reset: section;
  text-transform: small-caps;
}

Properties

  • In a declaration, the property name should be immediately followed by a colon, then a single space, and then the property’s value.
  • Include a semi-colon at the end of all declarations, including the last declaration in a declaration block.
  • When hex values are used for colors, use lowercase and, if possible, the shorthand syntax, e.g. #aaa. Colors may be expressed with any valid CSS value, such as hex value, color keyword, rgb() or rgba(). Note that IE8 does not support all color syntaxes and will require a fallback value.
  • For property values that require quotes, use double quotes instead of single quotes, e.g. font-family: "Arial Black", Arial, sans-serif; and content: " ";.
  • If a property does not require quotes (e.g. url(), do not add them. This means background-image: url(path/image.png) instead of background-image: url("path/image.png")
  • Use rem units preceded by px units for a safe fallback, unless it creates an undesired effect.
  • Quote attribute values in selectors, e.g. input[type="checkbox"].
  • Where allowed, avoid specifying units for zero-values, e.g. use margin: 0; instead of margin: 0px;.
  • Include a space after each comma in comma-separated property or function values.
  • Do not use spaces around the parentheses in a function, e.g. color: rgba(0, 0, 0, 0.8);
Example Properties
display: block; Basic syntax
color: #fff
color: #df7dcf
Use shorthand syntax for hexadecimal colors when possible
Always use lowercase
font-family: "Frutiger Ultra" Use double quotes instead of single quotes
text-shadow: 0 0 2px #ddd Do not attach units to zero-values
font-size: 24px;
font-size: 1.5rem;
Use rem units preceded by px units for a safe fallback, unless it creates an undesired effect.
color: rgba(0, 136, 18, 0.8) Spaces MUST follow commas in property or function values

Declaration order

The declarations in a ruleset should be ordered so that the purpose of the declaration block is most obvious. Clarity should be the guiding principle. We can help to achieve this goal by placing structurally important properties before others: positioning, box model, then other properties.

  1. Positioning properties include: position, float, clear, top, right, bottom, left, direction, and z-index.
  2. Box model properties include: display, [(max|min)-]height, [(max|min)-]width, margin, padding, border and their various longhand forms (margin-top, etc.) Plus box-sizing.
  3. Other declarations.

Within each of the above groups, properties can be grouped alphabetically or grouped with like properties next to each other, e.g. putting font and text properties next to each other. Drupal’s coding standards are purposefully vague here because there is no consensus on this issue (as of 2013), but we respect each other’s abilities and preferences.

Vendor prefixed properties should be directly before their non-prefixed version. This allows the official version of the property to override any inconsistencies in the vendor-prefixed versions once those browsers implement the official property. If browser bugs or cross-browser issues necessitate any deviation from this ordering, it should be clearly documented.

Again, the order of properties is meant to reinforce the purpose of the ruleset. As such, it is much more important to add comments to the ruleset then to worry about property ordering.

.selector {
  /* Positioning declarations */
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
  /* Box model declarations */
  display: inline-block;
  width: 100%;
  padding: 10px;
  padding: 0.625rem;
  border: 1px solid #333;
  /* Other declarations */
  background: #000;
  color: #fff;
  font-family: sans-serif;
  font-size: 18px;
  font-size: 1.125rem;
}

Tools like CSScomb may help with automating the order of properties (CSScomb settings for Drupal).

Exceptions and slight deviations

Large blocks of single declarations can use a slightly different, single-line format. In this case, a space should be included after the opening brace and before the closing brace.

.selector-1 { width: 10%; }
.selector-2 { width: 20%; }
.selector-3 { width: 30%; }

Long, comma-separated property values—such as collections of gradients or shadows—can be arranged across multiple lines in an effort to improve readability and produce more useful diffs.

.selector {
  background-image:
    linear-gradient(#fff, #ccc),
    linear-gradient(#f3c, #4ec);
  box-shadow:
    1px 1px 1px #000,
    2px 2px 1px 1px #ccc inset;
}

Media Queries

Media queries should be written in the same style as ruleset. Any containing rulesets are indented by two spaces.

  • One space between the media feature and the value.
  • All values to be written in rems unless it is inappropriate.
  • Add the pixel value in a comment directly after the the opening brace.
@media screen and (min-width: 28.125rem) { /* 450px */
  #page {
    margin-left: 20px;
    margin-left: 1.25rem;
    margin-right: 20px;
    margin-right: 1.25rem;
  }
}

Miscellaneous

@charset statements

Character set statements (like @charset "UTF-8";) are only valid if they are at the very top of a CSS file. Since Drupal’s CSS aggregator combines multiple CSS files into one file, Drupal will strip all @charset statements so that the aggregated file remains valid CSS.

This means CSS files MUST NOT include any @charset statements. The default encoding for CSS files is UTF-8. Any CSS comments or content property values MUST be encoded with UTF-8.

Practical example

An example of various conventions.

/**
* @file
* Layouts for this theme.
*/

/**
* Column layout with horizontal scroll.
*
* This creates a single row of full-height, non-wrapping columns that can be
* browsed horizontally within their parent.
*
* Example HTML:
*
* <div class="grid">
*   <div class="cell cell-3"></div>
*   <div class="cell cell-3"></div>
*   <div class="cell cell-3"></div>
* </div>
*/

/**
* Grid container
*
* Must only contain '.cell' children.
*/
.grid {
  height: 100%;
  /* Remove inter-cell whitespace */
  font-size: 0;
  /* Prevent inline-block cells wrapping */
  white-space: nowrap;
}

/**
* Grid cells
*
* No explicit width by default. Extend with '.cell-n' classes.
*/
.cell {
  position: relative;
  display: inline-block;
  overflow: hidden;
  box-sizing: border-box;
  height: 100%;
  /* Set the inter-cell spacing */
  padding: 0 10px;
  padding: 0.625rem;
  border: 2px solid #333;
  vertical-align: top;
  /* Reset white-space */
  white-space: normal;
  /* Reset font-size */
  font-size: 16px;
  font-size: 1rem;
}

/* Cell states */
.cell.is-animating {
  background-color: #fffdec;
}

/* Cell dimensions */
.cell-1 { width: 10%; }
.cell-2 { width: 20%; }
.cell-3 { width: 30%; }
.cell-4 { width: 40%; }
.cell-5 { width: 50%; }

/* Cell modifiers */
.cell--detail,
.cell--important {
  border-width: 4px;
}

 


The text of this guideline was originally based on the Principles of writing consistent, idiomatic CSS by Nicolas Gallagher.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

Dragan Eror’s picture

I am one of those who do NOT like this kind of order for declarations, I prefer alphabetical order (it is more specific with only one rule). Beside that, this looks very clear. Great work, thanks John.

P.S. I would like to see similar thing for SCSS.

Fr0s7’s picture

I agree with nearly everything in this draft. It is an excellent start. Nice work!

That being said, I'd like to propose a couple of changes:

Color Values

I've found that that using shorthand and keyword color values leads to search-and-replace problems. To alleviate most of the pain, it would make sense to steer the formatting towards a uniform pattern as much as possible.

I propose that this single bullet point:

  • When hex values are used for colors, use lowercase and, if possible, the shorthand syntax, e.g. #aaa. Colors may be expressed with any valid CSS value, such as hex value, color keyword, rgb() or rgba(). Note that IE8 does not support all color syntaxes and will require a fallback value.

... be changed to this:

  • Hex values will always be used instead of color keywords, eg. '#ffffff' will be used instead of 'white'.
  • Hex values will be used whenever possible. rgb() and rgba() values will be used only when necessary (such as in gradients), and must include a fallback value for IE8 support.
  • Hex values will always use a 6-character value, rather than shorthand 3-character value. eg. '#ffffff' will be used instead of '#fff'.

Selector Naming

This document is meant strictly for formatting, but somewhere in our CSS standards, I'd like to see guidelines or recommendations for semantic selector naming. eg. '.author' versus '.style-14'. Furthermore, it would be good to set standard naming conventions for variant classes. eg. '.box' as a base class, and '.box-inset' that extends (rather than overrides) the base class.

Separation of Concerns

In several of the examples in this document, the properties for layout, containers, and content are all set in a single class. While this is certainly allowed in a browser, it misses the point of what some are calling "object oriented CSS". That's a misleading name, but the idea could best be described as a "separation of concerns". When done properly, markup objects should fall neatly into the category of "layout", "container", or "content".

  • Layouts address the "grid" or how elements on the page are positioned.
  • Containers describe boxes or other framing within layout regions.
  • Content is simply the text, image, and media markup.

The idea is that our CSS and markup should be architected in such a way that removing a container from a layout does not change the design of the container. Likewise, removing content from a container should not change the formatting of the content. These things should be kept logically separate. In this way, content is not strictly dependent on its container, and a container is not strictly dependent on its layout. In doing so, the markup and CSS become extremely elegant and flexible, while selectors remain simple, semantic, and minimal.

Again, this point is probably not meant for this formatting document, but I feel that the examples provided in this document should at least properly demonstrate this separation of concerns. I would be happy to provide these examples.

Anthony Pero’s picture

Seems pretty straightforward. I'm sure eventually I will get used to doing it this way instead of "my way".

Would like to second Fr0s7's suggestion regarding color values. If we use all hex values whenever possible, and always use 6 digits, it will be much easier for others to come behind us and perform a search and replace to change colors.

Anthony Pero
Project Lead
Virtuosic Media
http://www.virtuosic.me/

JohnAlbin’s picture

I've found that that using shorthand and keyword color values leads to search-and-replace problems.

Lol! That's true. The original text came from Nicolas's text, which I reworded. I didn't feel strongly about anything except lowercase for hex values.

Hex values will always use a 6-character value, rather than shorthand 3-character value. eg. '#ffffff' will be used instead of '#fff'.

I don't see why that would be better then the opposite (“if possible, the shorthand syntax, e.g. #aaa”). The shorthand syntax is… shorter. So less bytes in the CSS file. It's just as readable.

On your selector naming and separation of concerns, I'm on the same page. It's just that the docs for those things are not on this same page. There are 4 different book pages to describe the CSS standards, those concerns are very important, which is why I wanted to highlight them in their own page. http://drupal.org/node/1887918 :-) I'm going to move some of your comments into that document because it currently needs more fleshing out.

  - John (JohnAlbin)

Anthony Pero’s picture

I don't see why that would be better then the opposite (“if possible, the shorthand syntax, e.g. #aaa”). The shorthand syntax is… shorter. So less bytes in the CSS file. It's just as readable.

I don't think "readable" is the issue. Ease of replacement is. Firebug, and I think Chrome Webmaster tools, always display the CSS in 6-digit value, regardless of what it is in the actual CSS, so when you're trying to change the color in a css file, a lot of times, at least what i do, is copy the value from Firebug and do a search and replace on it. If I copy the 6-digit value from Firebug and in the code it is the 3-digit shorthand, it won't actually find and replace.

Anthony Pero
Project Lead
Virtuosic Media
http://www.virtuosic.me/

barraponto’s picture

+1 for 6 digit hex colors. That's how Firebug shows them by default (Chrome's inspector has settings for this behavior).

As for selector semantics, that's actually a markup discussion. And although I dislike .span-14 classes, I don't see any issue with themes that sport those unsemantic classes (I just don't use them).

Capi Etheriel
Web Stategist, Developer, Designer and Scraper
Hacker Transparency Movement
http://barraponto.blog.br http://zerp.ly/barraponto

lindsayo’s picture

+1 for 6-digit hex color values. I also prefer uppercase because this is how they are presented in Chrome and Firefox inspectors and it is common to copy/paste.

sk33lz’s picture

Hex colors have shorthand variants for a reason. While it may be commonplace, not everyone copies and pastes hex values with find and replace from the browser in their editor. I believe this is a personal preference, and should be able to be done either way. The performance gains for leaving out 3 characters for every color being used in CSS that can be written in shorthand are debatable, but it is definitely a quicker way to type out hex codes manually.

Anthony Pero’s picture

I hear what you are saying, but isn't the whole point of standards to limit what is allowed even further, by providing best practices? The fact that there is a reason that shorthand notation exists is immaterial to the conversation; there is also a reason that the CSS spec doesn't enforce strict ordering rules, yet that's exactly what we are proposing to do here. The point of these standards is to make it easier for someone else to come behind you and work on a project. Having a single, agreed upon way to write color values seems like an obvious way to help that. And since a large portion of the design community uses Firebug, it seems appropriate to me to adopt Firebug's default color format.

Anthony Pero
Project Lead
Virtuosic Media
http://www.virtuosic.me/

rhache’s picture

The only thing I would change is making the declaration order alphabetical. Arbitrarily dividing properties into blocks makes some sense, but it's time consuming and everybody ends up making up their own "blocks". Pretty soon you'll have "inline", "font", "coloring" or whatever else somebody comes up with, and it's all a big mess. Not only that, but what about the ordering of the properties within each block? Alphabetical might, as you say "separate related properties" but it's less of a headache and it is far more CONSISTENT.

jessebeach’s picture

I agree.

barraponto’s picture

Consistence for consistence sake? Readability > consistence, and we can definitely make this more consistent by being very specific about the blocks (position/offsets, box-sizing/margin/padding/border, float/clear). Readability is a good reason for a patch reroll, alphabetic order not so much.

Capi Etheriel
Web Stategist, Developer, Designer and Scraper
Hacker Transparency Movement
http://barraponto.blog.br http://zerp.ly/barraponto

hachesilva’s picture

I'm with @409433 (Dragan Eror) here: alphabetized rules are much better, slightly less flexible when writing CSS but better to scan the code when done.

couturier’s picture

I think pixelwhip's comment below makes sense, so I deleted what I wrote previously.

New Update: Wow, so much commenting on the 3 vs. 6-digit hex notation! I was originally in favor of 6 because with the capacity of modern screens, most web designers are trending toward 6-digit specific tones, making 6-digit colors more frequently used than 3-digit ones. Pixelwhip favored 3 when possible for economy. However, plenty of other people are making smart arguments for consistency with 6-digits, without having to flip between 3 and 6. So, I'm reinstating my vote for 6-digit hex notation. Habitually thinking in terms of 6 digits would be easier for me, personally. The same "automatic" and "habit" reasons are why alphabetizing properties also makes sense to me. I am not a highly experienced CSS writer, so this is from a novice standpoint.

Note that D7 Bartik may still have some comment formatting and alphabetization differences with these standards. Reference this issue: http://drupal.org/node/1342054

cleaver’s picture

+1
Pretty much exactly as I would choose for myself. I especially like the logical grouping of properties.

killtheliterate’s picture

I hesitate in completely agreeing with the idea of alphabetically ordering properties, but eliminating ambiguity with a standard is a strong argument for.

learning - lots of learning.

pixelwhip’s picture

This looks great!

Section Comments

I agree with psynaptic's comments regarding section comments. I prefer the multi-line comment variation for sections, but would add 2 blank lines before and 1 blank line after. I think the extra line above would help make the file scannable.

Colors

Lowercase hex values with the shorthand when possible. Using the full 6 characters doesn't make things any easier to find and replace IMO. Consistency in implementation is what matters.

Declaration Order

I'm definitely onboard with organizing by purpose. While arguably less intuitive than straight alphabetizing, grouping by purpose helps give a better understanding of the rule set's purpose and can aid in making informed decisions when abstracting classes. I do think, this section needs more detail in order to get devs to follow it. I have some general rules that I follow, basically moving from the outside in.

Order by purpose

  1. Position (position > direction)
  2. Box Model (display > margin > border > padding > dimensions)
  3. Background (alphabetical)
  4. Typography (alphabetical)
  5. Misc (alphabetical)

Dimensions

Related dimensional declarations should be ordered clockwise starting from the top in the same way shorthand values are written.

.selector {
  border-top: 1px solid #eee;
  border-right: 1px solid #bbb;
  border-bottom: 4px solid #999;
}
karolus’s picture

I'd definitely agree about ordering declarations by purpose first--consistency is key here, and I don't think we are doing the browser engines any favors by doing this. If certain declarations are used, and others are not, alphabetical ordering may appear jumbled in some instances.

lindsayo’s picture

I like to use

.selector {
  position: relative;
  top: 1px;
  left: 2px;
}

The positioning is in top, right, bottom, left order. The directional declarations come after position: relative; because it makes it very easy to read and to know what to adjust, rather than having to hunt up and down an alphabetical list making sure you didn't miss any.

JuggoPop’s picture

The directional declarations come after position: relative; because it makes it very easy to read and to know what to adjust, rather than having to hunt up and down an alphabetical list making sure you didn't miss any

+1 Agree

jason.bell’s picture

Declaration Order

Like others I prefer alphabetical declaration ordering, but can understand the purpose-first so long as the rules and grouping are well stated in the standards. Is it worthwhile to require the declaration block comment (e.g., /* Positioning */, /* Box Model */)? And then inside of a purpose block could we at least alphabetize within to increase clarity?

.selector {
  /* Positioning */
  left: 0; 
  position: absolute;
  top: 0;
  z-index: 10;
  /* Box Model */
  box-sizing: border-box;
  display: inline-block;
  padding: 10px;
  width: 100px;
  /* Other */
  background: #000;
  color: #fff;
  font-family: sans-serif;
  font-size: 1.1em;
}

Section Comments

I find the Section Comments proposal to be laborious adding all of those "=" and offer the following for discussion and disassembly. A convention that I've used (probably picked up from CSSEdit) is to notate the beginning and end of sections. Often while the beginning of a section is noted, in the absence of a following section there is no way to determine the intended end of a section. Another benefit is being able to search on the @group "flag" to jump through major sections of the code.

/* @group Grid layout */

selector {
  property: value;
  property: value;
}

/* @end */

tstoeckler’s picture

Regarding

Separate each ruleset by a blank line.

Coming from #1848064: Allow to filter modules by arbitrary search strings on the Modules page, I would like to ask whether we should allow exceptions to that rule. See the following code:

/**
* For anything you want to show on page load only when JS is enabled.
*/
.js-show {
  display: none;
}

.js .js-show {
  display: block;
}

I think these declarations would be much clearer *without* the new-line in between. So, what to do? :-)

sun’s picture

See #1270218: [policy] CSS coding standards: Vertical spacing between selectors

In short: Current CSS standards say there should be a newline in between, but there's broad agreement that there should only be newlines between groups/sections; i.e., only add a newline before a comment. (apparently, similar to PHP code)

Daniel F. Kudwien
unleashed mind

JohnAlbin’s picture

I read through #1270218: [policy] CSS coding standards: Vertical spacing between selectors’s comments and its linked issues as well. TLDR for people who don't want to read that whole thread: A small, but significant group of contributors agreed that logical groupings of CSS rulesets should not have blank lines between them. I am, effectively, +1'ing the logical merging of that idea into this standard.

So, I agree that logical groups of CSS rulesets should not have a blank line between them. But note that if one of the rulesets in the logical group has a docblock-style comment, that comment must have a blank line before it.

I'll update the draft doc above to reflect that.

  - John (JohnAlbin)

JuggoPop’s picture

In a series of vendor-prefixed properties (or values), additional whitespace can be added after the property name and colon to allow the values of the declarations to align vertically.

  -moz-box-sizing:    border-box;
  -ms-box-sizing:     border-box;
  -webkit-box-sizing: border-box;
  box-sizing:         border-box;

What is the opinion of others in doing this where the whitespace is before the property name allowing the common parts of the property & the declarations to align vertically. This is something I started doing after seeing Paul Irish line it up that way. I have found it much easier to read as a "prefixed-block" of a property.

     -moz-box-sizing: border-box;
      -ms-box-sizing: border-box;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;

The longest prefixed property name is lined normally and the whitespace is added to the shorter ones. Thoughts?

JuggoPop’s picture

I was just looking this over again and I question the guidelines having anything "requiring" anything for a set browser fallback. I mean, imagine if the guidelines said you must provide support for IE6. Eventually (maybe not today, but at some point) IE8 will not be a large percent of the browsers in use.

So my thought to this, would be to instead "require" a declaration at the top regarding what fallbacks are in place. For example something like:

/**
* @file
* Short description describing the file.
*
* Browsers: MS (IE8-10), Opera, Moz, Webkit
*/

Just something to state what was intended at time of development. Then when the time comes to remove those additional fallbacks, various prefixes, etc. The file would be updated to remove what is not needed and the declaration updated. Intent would then be covered by reading one line and know what to expect from the code to follow.

Another issue is that fallback images are not the only thing to take into account for older browsers. If they are required "specifically" as part of the guidelines, then where do you draw the line between "required to be pixel perfect fallback" and where "the code just degrades gracefully?"

Just a thought.

jessebeach’s picture

There's an inconsistency in the practical example above.

.cell {
  position: relative;
  display: inline-block;
  overflow: hidden;
  box-sizing: border-box;
  height: 100%;
  /* Set the inter-cell spacing */
  padding: 0 10px;
  border: 2px solid #333;
  vertical-align: top;
  /* Reset white-space */
  white-space: normal;
  /* Reset font-size */
  font-size: 16px;
}

Overflow is listed between the positioning and box-model properties, although that property is listed in neither group above in the guide. It's a property that affects positioning as when an overflow-hidden box follows floated sibling boxes. The overflow-hidden box will have its rendering context reset. It might also be a box model property, since it affects how large a box is.

I'm not sure where to put overflow in this model. I'd just as soon put it in the 'other' category.

sk33lz’s picture

Well that is a load off my back. Here I was getting all worked up over having to change all my themes around few a new standard, but luckily, I have been following a similar standard when building my themes as presented here for a while now. It just seemed to make sense to do my CSS in the order that elements were received on the page, or their importance, so I could read it like a book. Looks like I have to take it a step further to each selector group and it's selector properties.

Great ideas everyone! This is why our community rocks!

skh’s picture

Most of these I agree with and personally already practice. However, I think it's worth considering the continued growth rate of preprocessors such as Sass and having standards that can can be easily transferable.

One in particular is line breaking. There should be more. When using nested selectors in preprocessors, not having line breaks can quickly make the code rather confusing and hard to follow.

After I wrote the code in here, I noticed that code tags were removing blank lines. So here's a gist.

jweedman’s picture

Line spacing in preprocessing (SASS, LESS, etc) is recommended by the language's formatting themselves. Seeing as SCSS only came about to clear up syntax issues of SASS, wouldn't it make sense to adhere to their suggestions? Not trying to be argumentative, just opening a conversation.

Nesting in SCSS - per their formatting recommendation - includes line spacing between rule sets. Also, rule sets with only one declaration are put on the same line as the selector.

Looking at "SKH's" gist makes a good visual point, that with preprocessing, line spacing makes the code that much more readable. Those are my thoughts, anyway. Hopefully we're not, both, too late to the party...

LewisNyman’s picture

I added some guidelines for media queries, some feedback would be great.

https://drupal.org/node/1887862#media-queries

cleaver’s picture

Great idea to add media queries. Regarding whether it should specify em's? Perhaps so, but we haven't touched the issue of em's versus px's. I think that issue should be addressed generally, not just for media queries.

LewisNyman’s picture

We've been discussing pixel units for some time here: https://www.drupal.org/node/2298015

I've updated the documentation to use px followed by rem values. Please post in the issue if you have an objection.