Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When building the interface, use the History API to ensure that history entries are pushed to the stack appropriately. Push entries to the stack when the user reaches points they would reasonably expect to bookmark. Avoid pushing entries so frequently that backing out of a state using the back button becomes tedious or impossible. &lt;section class="primary emphasized summary"&gt;</code>

==== Avoid unnecessary elements. Keep nesting shallow. ====

Minimize the overall depth of HTML to decrease page size, increase readability, and improve rendering speed.

==== Avoid conditional logic in views for partial display ====

==== Use view helpers for arbitrary display of content ====

See [http://stackoverflow.com/questions/6848393/drying-rails-view-partial-vs-helper This example and description from Stack Overflow]. Use Rails helpers to dynamically generate highlight dynamic HTML with widely varying elements and structure. Use Rails partials to generate more static content. Remember to demonstrate partials and helpers in the pattern portfolio.

=== CSS with Sass ===

Earthdata Search uses [http://sass-lang.com/ SCSS] to generate its CSS. It follows the guidelines for scalable CSS outlined by [http://smacss.com/book SMACSS], with key items reproduced in this document. The CI build checks CSS style using CSS Lint. Developers are strongly encouraged to read the [https://github.com/stubbornella/csslint/wiki/Rules CSS Lint rules].

==== Exercise every line of CSS in the pattern portfolio. ====

Use the Pattern Portfolio to demonstrate all styles in the application. This allows other developers to find styles that already exist instead of re-inventing the wheel, and it allows developers to ensure that new styles do not break existing styles. The CI build ensures that each style is used at least once in the portfolio.

==== Do not use id selectors (#id) ====

ID selectors indicate that a style is one-off and can only appear in one place on a page. Prefer to build reusable styles that could appear in multiple places or on multiple pages. Further, id selectors are very specific in terms of the CSS cascade, making them hard to override.

There are two exceptions to this rule: #site-header and #site-footer. These two areas of the page are typically significantly different than the rest of the site to the point where they need to override all styles, and the drawbacks of using id selectors mostly do not apply.

==== Do not use style attributes or inline styles. ====

Place all styles in CSS files. Mixing styles with HTML makes tracking, testing, and reusing styles much more difficult. Further, style attributes are incredibly specific and difficult to override.

Javascript components should also prefer to apply classes to elements rather than alter their style attributes for the same reasons.

==== Do not use <code><nowiki>!important</nowiki></code> ====

<code><nowiki>!important</nowiki></code> makes styles impossible to override unless the overriding rule also uses <code><nowiki>!important</nowiki></code>. In almost every case, using <code><nowiki>!important</nowiki></code> is unnecessary. Prefer to use selectors with higher precedence or alter overridden selectors to have lower precedence.

Very very rarely it is necessary to use <code><nowiki>!important</nowiki></code> because of third-party code. This typically happens when a third-party Javascript library adds an undesirable style attribute to an element. When given the choice between altering third-party Javascript or using <code><nowiki>!important</nowiki></code>, the latter is usually preferable. In this circumstance, document the decision. This is one reason we avoid setting style attributes, even in Javascript components.

==== Prefer selectors that describe attributes and components, not domain concepts. ====

Consider the following element:

...

<code>ul.granules</code> selects a list with very specific elements, which may only be available on one page. Any styles applied to this list are unlikely to be reusable. Adding classes that describe attributes of the list makes CSS styles more modular and reusable.

...

Here we may use different selectors to apply different attributes to the list. <code>ul.zebra</code> may add zebra striping to the rows, <code>ul.scrollable</code> may add a scroll widget, and <code>ul.selectable</code> may provide hover and selection mechanisms. Any of these attributes could be useful on lists that do not describe granules, and other lists could mix and match attributes to match their needs. Fine-grained attribute-centric class names provide for better reuse.

==== Follow SMACSS rule categories and naming conventions ====

Follow [http://smacss.com/book SMACSS] guidelines for grouping and naming CSS classes. Prefix layout classes with "l-". Prefix state classes with "is-". Do not prefix module classes. Use double dashes to indicate module subclasses, e.g. "module--subclass"

==== Minimize selector depth ====

As described by SMACSS' [http://smacss.com/book/applicability Depth of Applicability] chapter, minimize and simplify CSS selectors. Deeply nested selectors are easy to create in Sass, but they are hard to understand and create a strong coupling to the underlying HTML structure. Further, they tend to be overly-specific, causing duplication in CSS rules. Whenever possible, keep nesting 1-2 selectors deep, with 3 being the maximum.

...

==== Use fast CSS selectors where possible. ====

A large page with many CSS rules can suffer rendering performance problems that make pages feel sluggish even on modern browsers and computers. Understand [http://smacss.com/book/selectors selector performance] and follow these rules to allow pages to render quickly:

# Use child selectors
# Avoid tag selectors for common elements (div, span, p)
# Use class names as the right-most selector

==== Use variables for colors and numbers. ====

Use Sass variables to describe all colors except black and white and all numbers except 0 and 1px. This makes it easier to find usages of measurements and change them as necessary.

==== Use Sass helpers for CSS3 styles. ====

Sass and compass provide helpers for CSS3 styles that normalize experimental browser extensions, for instance

...

generates

...

 

 

Use these helpers to avoid overly-verbose CSS.

==== Target browsers with classes not CSS hacks. ====

The base site contains HTML boilerplate libraries which add CSS classes to the html and body element that detect commonly misbehaving browsers (older IE versions) and browser capabilities. Use these classes to target browsers or capabilities rather than relying on CSS hacks.

=== Javascript (Coffeescript) ===

==== Use Coffeescript ====

New project code should be written in Coffeescript. It eliminates much of the boilerplate and gotchas of Javascript, producing easier-to-read code that is more accessible to developers with all levels of front-end experience.

==== Follow polarmobile's Coffeescript style guide for code formatting ====

https://github.com/polarmobile/coffeescript-style-guide

==== Build components and modules, not one-off elements ====

Try to build Javascript components and widgets that could apply throughout the site, rather than on a single page or in a single situation. Good questions to ask when writing code is "Can I make this into a widget?" or "Can I apply this behavior to all elements with this class?". If the answer is no, perhaps the element could be described as a composition of multiple components (scrollable, zebra-striped, selectable list rather than one-off granule list)

==== Allow users to bookmark content and use the back button ====

Dynamic interfaces are great, but users should be able to bookmark their current location to return later, especially for complex search UIs like Earthdata Search. Further, we should allow the user to back up to previous states or leave the site via the back button.

When building the interface, use the [http://html5doctor.com/history-api/ History API] to ensure that history entries are pushed to the stack appropriately. Push entries to the stack when the user reaches points they would reasonably expect to bookmark. Avoid pushing entries so frequently that backing out of a state using the back button becomes tedious or impossible.