CSS – Web Development Standards

This page is to illustrate SHC's coding of CSS that should be followed during the development process. Some of this document will reference Emily Lewis' article at http://msdn.microsoft.com/en-us/scriptjunkie/ff679957. We suggest reading it in its entirety, but the gems will be added and notated below.

Note: This is written assuming a basic knowledge of CSS and attributes. Attributes will not be discussed at length in this document.


Naming Conventions

CSS selector names should be simple, descriptive, and memorable. Wherever possible, create abstract names that relate to the function or the meaning of the elements the selector targets ("call-to-action" is better than "link," for example, and "submit-action" better than "submit-button"). Avoid cryptic abbreviations (though standard abbreviations, like "cta" instead of "call-to-action," are fine). Avoid names that use Javascript reserved words or the names of HTML elements. Avoid using color or position or spacing words ("link-orange," "padding-20," etc.) that would tie the name to design choices that can change over time. Avoid using ordinals tied to an element's document position, whether words or numbers ("cta-one," "link2," etc.).

Hyphenated names in all lower case are preferred to camel-case names. This follows the pattern set by the CSS standard (for example in property names, "border-bottom," and in selectors, ":first-child"). CSS is also case-insensitive, so camel-casing could in some cases lead to confusion (".myname" and ".myName" are not different selectors). In practice, hyphenating encourages the creation of memorable and predictable patterns ("device-wide," "device-narrow" in a responsive scenario) and discourages the sort of cryptic names that often crop up in camel case ("mktplBnr" instead of "marketplace-banner"). Do not use underscores in CSS names.

IDs have typically been camel-cased, to allow them to be addressed directly in Javascript (which doesn't allow hyphens in identifiers). That form of DOM access is a legacy feature that has been superseded by document.getElementById() and by the jQuery id selector. But there's no objection to camel-cased IDs, if it helps reinforce the fact of ID uniqueness, and so long as the practice is consistent within a given CSS file.

EXAMPLE:

#here-is-my-example {  
margin-left:20px;  
margin-right:20px; 
}
.here-is-my-example a{  
margin-left:20px;  
margin-right:20px; 
}
#here-is-another-example, #here-is-my-example {  
margin-left:20px;  
margin-right:20px; 
}

Multi-Line Format

For readability purposes please keep the code in a multi-line format and avoid the single line format. Attributes to a class should be indented below the class name by a tab, or 4 spaces.

EXAMPLE:

.navigation-rss-icon {
position: absolute;
left: 940px;
bottom: 0px;
}
#navigation-rss {
position: absolute;
left: 720px;
font-family: Verdana, Arial, Helvetica, sans-serif;
text-transform: uppercase;
color: #897567;
line-height: 2.5em;
}
#navigation-rss li {
display: inline;
}
#navigation-rss li a:link, #navigation-rss li a:visited {
color: #fffffe;
text-decoration: none;
padding: 0px 2px;
letter-spacing: -0.05em;
}
#navigation-rss li a:hover {
color: #eed2a1;
text-decoration: none;
}

Use of IDs

ID selectors target an elment on a page whose ID attribute is equal to the selector name. ID selectors begin with a pound character (#) and can have any name valid for an HTML ID. (Be aware that HTML 4 placed restrictions on valid IDs that no longer apply in HTML 5.) By rule, an ID can be used ONCE AND ONCE ONLY on any given HTML page. CSS behavior is not guaranteed if that rule is violated.

EXAMPLE:

#main-text {  
margin-left:20px;  
margin-right:20px; 
}
<div id="main-text">This is the main text of the page...</div>

ID selectors are the most performant available. In the example above, writing the selector as "div#main-text" would gain you nothing except a few extra bytes of file size. In general, avoid extra specifiers on IDs.


Use of Classes

A class selector in CSS targets all HTML elments whose class attribute equals the selector name, or contains that name as part of a whitespace-delimited list. Class selectors begin with a dot (.) and can have any name comformant with CSS character rules.

EXAMPLE:

The following rule creates a class called "warning," which makes the text of all elements with that class (e.g. class="warning," or class="warning and other names") bold and red.

.warning {
font-weight:bold;
color:#f00;
}

Following are a couple examples of elements of the warning class:

<h2 class="warning">WARNING</h2>
<p class="warning hostile">Don't even go there!</p>

Note: If the class selector is preceded by an element name, then that selector only applies to the specified type of element.

To illustrate, the following two rules indicate that h2 elements of the class "warning" will be underlined, while p elements of the class "warning" should not be.

h2.warning {  
color:#ff0000;  
text-decoration:underline 
} 
p.warning {  
color:#ff0000;  
font-weight:bold; 
}

Because both rules indicate that the color should be red (#f00), this should be rewritten as follows:

.warning {  
color:#f00; 
} 
h2.warning { 
text-decoration:underline; 
} 
p.warning {  
font-weight:bold; 
}

Note: The notation of two class selectors written without a space between them targets an element that has both those names in its CLASS attribute. So in terms of the HTML example, this CSS displays the same as the code above:

.warning {  
color:#f00; 
text-decoration:underline; 
} 
.warning.hostile {  
font-weight:bold; 
text-decoration:none;
}

This feature can be useful in designing more modular/semantically rich CSS.


Avoid Same ID and Class Names

Make sure when coding that you do not create an ID and a class with the same name. This creates confusion and could trip up another developer who comes along later to maintain your code.

EXAMPLE:

#shop-items a span { 
color: #666;
display: block; 
}	
.shop-items a span { 
display: block; 
position: relative;
width: 100%;  
}

Although it is technically possible to code in this manner and it will render without issue, essentially it's an obfuscation and should be avoided.


Specificity

The larger and more complex your CSS files become, or the more CSS files you start to juggle with, the greater likelihood there is of conflicts turning up. That is where specificity comes into play.

EXAMPLE:

If the selectors are the same then the latest one will always take precedence.

p { 
color: red;
} 
p { 
color: blue;
}

p elements would be colored blue because that rule came last.

Conflicts quite legitimately come up when you have nested selectors.

EXAMPLE:

div p { 
color: red; 
} 
p { 
color: blue; 
}

Based on order p elements within a div element would be colored "blue", seeing as a rule to color p elements "blue" comes last, but they would actually be colored "red" due to the specificity of the first selector. The more specific a selector, the more preference it will be given when it comes to conflicting styles.

The actual specificity of a group of nested selectors takes some calculating. Basically, you give every id selector ("#whatever") a value of 100, every class selector (".whatever") a value of 10 and every HTML selector ("whatever") a value of 1. Add them all up and you'll have the specificity value.

  • p has a specificity of 1 (1 HTML selector = 1)
  • div p has a specificity of 2 (2 HTML selectors = 1 + 1 = 2)
  • .tree has a specificity of 10 (1 class selector = 10)
  • div p.tree has a specificity of 12 (2 HTML selectors, 1 class selector = 1 + 1 + 10 = 12)
  • #baobab has a specificity of 100 (1 id selector = 100)
  • body #content .alternative p has a specificity of 112 (1 HTML selector, 1 id selector, 1 class selector, 1 HTML selector = 1 + 100 + 10 + 1 = 112)

So if all of these examples were used, div p.tree (with a specificity of 12) would win out over div p (with a specificity of 2) and body #content .alternative p would win out over all of them, regardless of the order.


z-index

Use the following as a guide in determining what z-index you should use on an element should such be required.

z-index Range Content Type Details
< 0 Background Elements Not to exceed -9999
0 - 999 Main Content, Standard Ads Standard ad tags in place with regular content
1000 - 1999 Expanding Advertising The entire expandable ad unit should be set within this range
2000 - 2999 Floating Advertising Floating Over The Page ads (OTP's)
3000 - 3999 Pop-up Elements Chat windows, message notifications See Popups
4000 - 4999 Non-anchored Floating Elements Survey recruitment panels
5000 - 5999 Layers See Layers
6000 - 6999 Tooltips See Tooltips
7000 - 7499 Expanding Site Navigation Elements Dropdown navigation, site warnings, etc.
7500 - 7999 Full-page Overlays Full-window Over-the-Page (OTP) ads and Between-the-Page (Interstitial) ads IF they cover page content
8000 - 8999 Curtains for modals See Modals
9000 - 20000 Modals See Modals

Should existing elements break these conventions - repair them as required via JIRA level initiave or project inclusion.


Shorthand CSS

Shorthand in CSS is where you define several properties of the same kind as one single property. CSS Shorthand makes development much easier and keeps your CSS clean, short & accessible.

EXAMPLE (margin):

margin:25px 50px 75px 100px;

  • top margin is 25px
  • right margin is 50px
  • bottom margin is 75px
  • left margin is 100px

margin:25px 50px 75px;

  • top margin is 25px
  • right and left margins are 50px
  • bottom margin is 75px

margin:25px 50px;

  • top and bottom margins are 25px
  • right and left margins are 50px

margin:25px;

  • all four margins are 25px

EXAMPLE (background):

background: red url(image.png) repeat top left scroll;

  • background-color: red;
  • background-image: url(image.png);
  • background-repeat: repeat;
  • background-position: top left;
  • background-attachment: scroll;

Borders, Background, Fonts, Lists, Padding and Margin should all be written in shorthand whenever possible.

Read more at http://www.dustindiaz.com/css-shorthand/ where some additional excellent examples can be found.


Comments

Comments should be used for the following:

  • Start of major sections of the style sheet (so others can pickup and easily understand / edit your work)
  • Fixes to original CSS because of problem tickets being issued (JIRA)
  • Document information: original author, creation date, late update version, and version number (optional, but very helpful)

EXAMPLE:

/*    
* Author: FED NAME HERE
* Creation Date: ##/##/####
* Version: 1.0
* Last Update Date: ##/##/####
* Jira Numbers involved in this sheet:
* E-COM-###### E-COM-###### E-COM-###### E-COM-######
* E-COM-###### E-COM-###### E-COM-###### E-COM-######
* E-COM-###### E-COM-###### E-COM-###### E-COM-######
*/

/* Carousel */
#mml-vertical .categories {
float:left;
height: 120px;
position: relative;
width: 100%;
}

Do Not Use CSS Expressions

The problem with expressions is that they are evaluated more frequently than most people expect. Not only are they evaluated when the page is rendered and resized, but also when the page is scrolled and even when the user moves the mouse over the page. Adding a counter to the CSS expression allows us to keep track of when and how often a CSS expression is evaluated. Moving the mouse around the page can easily generate more than 10,000 evaluations.

EXAMPLE:

#mml-vertical .discussion-wrap a {
max-height: 26px;
line-height: 13px;
overflow: hidden;
height: expression(this.scrollHeight > 26 ? "26px" : "auto");
} 

Create an external file whenever possible

In a HTML file, if the area where the <style> tag is rather large, please make a file and import into the particular page. Having various STYLE fragments throughout an html document slows rendering time as the browser needs to "change gears" to take on a different standard. It makes debugging / repairs less expedient, and finally, limits the use of a style to a single page where an external file can be imported as needed to many pages.

EXAMPLE:

<link type="text/css" rel="stylesheet" href="http://k.shld.net/020206/ue/home/CMBDZ_global_9958.css" />

If the .css applies to multiple pages, then creating the proper eternal CSS file is mandatory.

Finally, image references for backgrounds currently need to be in an external file. This is to assure the image is referenced via akamai rather than via www.sears.com, which helps the overall performance of the page.


Adding new CSS to a current file

When adding a new section to an already existing file, make sure to read the file and see what can and can’t be used in the file.

To avoid having irrelevant old CSS code or repetitive code in a particular file it is vital to check the entire file for similarities or replacements. This helps reduce file size, improve CSS rendering performance, remove redundant code and keep the overall site codebase cleaner.

EXAMPLE:

The following class below appears in lines 4607, 3501 of productLayoutMain.css and on line 384 in universalList.css:

a.saveToList {
border: 1px solid #FFFFFF;
display: block;
float: left;
font-weight: bold;
outline: medium none;
padding: 0 18px 0 0;
position: relative;
text-decoration: none !important;
vertical-align: middle;
}

EXAMPLE:

The following class below appears in lines 4626, 3070 productLayoutMain.css and in line 402 in universalList.css:

a.saveToList .icon {
background-position: -94px -17px;
height: 5px;
position: absolute;
right: 4px;
top: 6px;
width: 9px;
}

EXAMPLE:

The following class below appears in line 4621 and 2837 in productLayoutMain.css:

.icon {
background: url("../img/product_sprite.gif") no-repeat scroll 0 0 transparent;
display: block;
font-size: 5px;
}

Spriting

The act of combining all background images into one single master image and displaying them using background position.

CSS Sprites reduce the number of HTTP requests, saves bandwidth and overall allows the browser to load the display to the customer faster.

When to do spriting? When there are numerous small images on a single page or experience, such as bullets, icons, buttons, background images.

How to approach spriting. Choose the best approach for the situation; this is completely open to the developer. Just ensure that it is well commented and the Class Names are easy to understand.

Helpful links:
http://www.alistapart.com/articles/sprites
http://css-tricks.com/css-sprites/
http://www.websiteoptimization.com/speed/tweak/css-sprites/

EXAMPLE:

<style type="text/css">
.super-sprite{
    background: url('_sprite.gif') no-repeat;
    display:block;
}
.down-icon .super-sprite {
    background-position: -0px -5594px; 
    width: 40px; 
    height: 20px;
}
.red-exclamation-point-icon .super-sprite {
    background-position: -0px -5427px; 
    width: 40px; 
    height: 16px;
}
</style>

<ul id="spriteListExample">
 <li class="down-icon" aria-label="down"><span class="super-sprite"></span></li>
 <li class="red-exclamation-point-icon" aria-label="exclamation point"><span class="super-sprite"></span></li>
</ul>

Result:

dev_css_01


Hacks

Avoided whenever possible but sometimes inevitable. When writing a style that requires special consideration to a browser, there are a few approaches. Sears currently uses a method that involves javascript where the browser type is appended to the body tag as a class. This allows us to write our classes with specificity rather than using a conventional hack. EXAMPLE: .ie6 #content-wrapper .vertical {width:100%} Because all pages in the SHC family will have the browser name/type added to the body tag as a class, IE6 will apply the above style but no other browser will. We don't use conditionals: <!--[if condition]> HTML <![endif]--> There is no need for them as we have .ie6, .ie7 and other class selectors written to the body tag that allow us to use specificity. Avoid using !important. It makes applying fixes with specificity impossible and based on the size of our application, it's more trouble than it's worth. Instead put the fix in it's proper place, or be more specific.

Use what's already there

Writing a style when one is already available should be avoided. Semantic markup should be your guide for such though. If a selector named "address" has all the properties you're looking for but you're not writing an address, you should consider alternative naming. Min-width is set on the body of the document. Current setting is 995px which allows vertical scrollbars in all pages at 1024px resolution. Note: Html resets are loaded in a global file, there is no need to include them again.          

Post a New Comment

Your feedback will help us improve this page. If you have a comment about the content of this page, use the form below, and the Patterns Team will get back to you within a business day.

For general questions or assistance, email the Patterns Team directly.