ivyprojectscassidydocs

Cassidy

A Css Framework For Rich Web Apps

The Docs

  • Standalone Manual (HTML)

Cassidy Documentation resources

You'll find on this page documents that will help you learn, use and develop with Tahchee.

Cassidy manual is included below for your on-line reading pleasure !

1.Introduction

Writing CSS is not always an easy task, especially when you have to think about naming and organizing your classes. Writing a simple CSS is usually an easy task, but when your site evolves, you quickly run into problems such as styles leaking from one element to another–and that's not to mention the headaches you'd have with IE-compatibility.

The goal of this document is to provide general and specific guidelines to allow people who develop rich web applications to get their CSS written right. We've analysed the CSS files of a couple of major websites, and we were surprised by the inconsistency of their CSS rules, suggesting that most of web developers grow CSS in an ad-hoc manner rather by sharing common guidelines.

1.1.Scope

The scope of this document is to propose a CSS framework that covers the following domains:

  • Basic HTML elements
  • Basic layout (columns, floating ares)
  • Basic typography
  • Widget classes (independent from the UI library you use)
  • Interaction classes (how CSS reacts to user and system-generated events)

1.2.Goals

Here are the goals we tried to follow when designing this CSS framework:

  • Easy to understand
  • Easy customization for specific uses
  • Reasonable, common defaults
  • Prevent leaking of styles
  • Clear guidelines for developers and designers

2.The Framework

The CSS framework is separated in two different layers:

  • The core, which covers basic HTML elements, layout and typography
  • The widgets, which cover styling of widgets, including their interaction

Before going into the detail fo these layers, we'll detail the naming convention which is the foundation of the CSS framework.

2.1.Naming convention

Names are important, and as the studywe made shown it, most major web sites have an inconsistent naming of their CSS rules. Inconsistencies generally lead to ambiguous naming, name clases (as CSS has no notion of namespace) and in the end, bugs which are often difficult to track… it's the usual story in software engineering anyway.

The goal of this section is to lay out a sound base on which we'll build the CSS framework. Analyzing the different types of elements that one could have in a web page, we found the following categories:

HTML Elements
These are the basic HTML elements that you use in your every day life such as <p>, <a>, <ul>, <li>, etc.
Custom elements
Instead of adding new tags, we often simply use classes to indicate new types of elements. Suppose you have a list of messages, instead of using a non-standard <message> tag, you'd use something like '<div class="message">'. These classes typically denote important element which are specific to your application.
Structure annotations
Designers usually do wireframes of the pages before they are turned into HTML pages. Wireframes are typically divided into pages, areas and sections that are then expressed as HTML divs in the resulting HTML pages.
Formatting annotations
Some of the HTML classes that we used are made solely for formatting our document. We often see a clearfix class for fixing use of floating elements, or things such as bigger, smaller, two-columns, etc.
Meta-information annotations
Sometimes we want the CSS selectors to be able to match specific elements. Since CSS selectors are not as powerful as XPath expressions, we sometimes need to annotated HTML elements with specific information. If you have a list of elements you could use odd, even to indicate wether the element has an odd or even index. Conversely, you could use classes such as first and last to qualify the first and last elements of this list.
Generic UI skinning
Many web apps provide custom skins for buttons, using the well-known “sliding doors” CSS trick. We generally use a class such as button to indicate that a particular tag is to be rendered as a button.
Specific UI skinning
While we'd want most of the buttons to look just the same, we sometimes want this specific button to look differently. This is generally because the button appears in a specific context, like a signup form. People either use the container as a rule specifier '.signup .button' or rather add another prefixed selector ('.signup-button')
Event-related UI skinning
CSS :hover selector and JavaScript allows the classes to change dynamically. We often see classes such as selected, current, dragged, dropped being used to denote elements that are involved in some kind of interaction.

Looking into the details of more advanced web applications, we also identified the following categories:

Placeholders
Modern Web 2.0 often create DOM elements on the fly and have two choices: either create all the DOM nodes directly from the JavaScript or clone an existing node, replacing the default data with the actual data. This is pretty much like client-side templates.
Interaction hooks
JavaScript-driven interaction requires that your JS code somehow hooks into the existing HTML. For instance, when you click on a specific icon, you'd like a dialog to pop-up. You can do this by directly adding the 'onclick' event in your HTML, but if you want a true MVC architecture, you'll want to rather use an HTML selector or ID to access your element.

So in essence, we have the following kind of elements:

  • HTML elements (p,'ul','li',…)
  • Domain-specific elements (.message, .user, …)
  • Generic widgets elements (.button, .dialog, …)
  • Widget instances elements (.signup, .login, …)
  • Placeholder elements (.name, .date, …)

Which can be annotated in different ways:

  • Structural annotations (.page,'.area', …)
  • Formatting annotations (.smaller,'.hidden', …)
  • Meta-information annotations (.first, .last, .empty,…)
  • Interaction annotations (.current,'.dragged','.dropped',…)
  • MVC annotations (.showThisDialog, .doThisOperation, …)

Considering names we decided to take into account the following requirements:

  • Names should be as explicit as possible: by looking at a name, you should be able to easy see what type of element it denotes.
  • Make it easy for automated search/extraction of elements belonging to the same type.
  • Ensure that the names are compact, so that classes of HTML elements do not take too much space.

And here is the naming convention we propose:

  • Formatting classes and structural annotations are lowercase, consisting of a single word.
  • Meta-information should be lowercase, consisting of a single word such as first, last, etc.
  • Domain-specific elements are lower-case, optionally prefixed by an application specific prefix (like acme, acme-message, etc).
  • Generic widget elements are lower-case prefixed by a common prefix. We suggest w as the prefix (like w-button, w-dialog).
  • When two generic elements are used within each other, like a button within a dialog, we recommend using .w-dialog .w-button as opposed to .w-dialog-button.
  • However, when qualifying a generic widget that is only found as part of another widget, you'd use the parent widget name as a prefix for the CSS class. So if our 'foo' has a 'bar' in it, we'd have 'w-foo-bar' to identify the 'bar' within that 'foo'.
  • Specific widget instances are CamelCase, because they usually correspond to a class with the same name in your JavaScript application. For instance, you could have a MessageList JavaScript class/prototype, which HTML view component would have the MessageList CSS selector.
  • Singleton widgets (like a NavigationBar) should used HTML ids instead of CSS classes (this would be #NavigationBar instead of .NavigationBar)
  • Placeholders should be mixedCase, because they often correspond to a property of an object. So imaging you have a User class with firstName and lastName properties. The CSS selectors would be .User .firstName and .User .lastName. We recommend the out- common prefix to denote that these selectors will be used as “out paramaters” by the JavaScript application. So the selector would rather be .User .out-firstName instead of .User .firstName. This makes it easier to spot and find which elements are used as placeholders.
  • Elements that are used as inputs for JavaScript widgets, such as text areas and text inputs should be also mixedCase (there is either a property or a method representing the read operation in the JS widget class), using the in- prefix to denote that they're used as input. So if you have a user signup form you'd have 'in-firstName', and 'in-lastName' classes to indicate which parts of the HTML documents should be used as inputs by the widget.
  • Elements that are used as triggers for operations, such as buttons, icons, special links, etc. should be mixedCase, prefixed by the do- prefix to denote that an operation will be trigger. Their name should be the same as the corresponding operation. If a button shows the sign up dialog, its class should be op-showSignUpDialog.
  • Event annotations should be mixedCase prefixed by on, such as on-focus, on-drag, on-drop, etc.

As you can see, we use lowercase, lower-case, mixedCase and CamelCase for different kind of elements, and we used prefixes to denote the different roles of the elements and prevent name clashes. In practice, these conventions will avoid too long CSS selectors, and allow a natural prioritization of styles:

 /* Generic widgets styles */
 .w-dialog { ... }
 .w-dialog .w-button { ... }
 
 /* Widget instances styles */
 .SignUp .w-button { ... }
 .Alert  .w-button { ... }

Here is a summary of these conventions

Elements
Specific element
lower-case
message, status, book
Widget type
w-lower-case
w-button, w-dialog, w-panel
Sub widget type
w-parent-lower-case
w-dialog-operations, w-filter-results
Widget instance
CamelCase
SignUp, NavigationBar, MessageList
Annotations
Formatting
lowercase
small, hidden, clearfix
Meta
lowercase
empty, first, last
MVC Input
in-camelCase
in-firstName, in-lastName
MVC Placeholders
out-camelCase
out-firstName, out-lastName
MVC Triggers
do-camelCase
do-addUser, do-showDialog
MVC Events
on-camelCase
on-drag, on-focus

So this was a bit long, but vital to get the foundation of our CSS framework right. The next sections will propose a list of default CSS classes, describe what they mean and when they should be used.

2.2.Core: Structure annotations

The core layout classes make it easy to express the structure of your pages, allowing to quickly shape the big areas and sections of your page, and provide hooks that the designers can use to make things pretty as soon as possible.

2.2.1.Content structure

The content of a page can be decomposed into four main types of elements:

  • page: this is the global element that contains the whole page
  • area: they denote a specific area, like navigation, overview, operations, etc.
  • section: a specific part of an area, like latest news, current article, etc.
  • group: indicates a title for a specific section/area
  PAGE
  .=============================================================.
  ||                                                           ||
  ||  AREA                                                     ||
  ||  +----------------------------------------------------+   ||
  ||  |                                                    |   ||
  ||  |                                                    |   ||
  ||  +----------------------------------------------------+   ||
  ||                                                           ||
  ||                                                           ||
  ||  AREA                                                     ||
  ||  +----------------------------------------------------+   ||
  ||  | SECTION                                            |   ||
  ||  | +------------------------------------------------+ |   ||
  ||  | |                                                | |   ||
  ||  | |                                                | |   ||
  ||  | +------------------------------------------------+ |   ||
  ||  |                                                    |   ||
  ||  | SECTION                                            |   ||
  ||  | +------------------------------------------------+ |   ||
  ||  | | GROUP                                          | |   ||
  ||  | | +--------------------+  +--------------------+ | |   ||
  ||  | | |                    |  |                    | | |   ||
  ||  | | |                    |  |                    | | |   ||
  ||  | | |                    |  |                    | | |   ||
  ||  | | +--------------------+  +--------------------+ | |   ||
  ||  | +------------------------------------------------+ |   ||
  ||  |                                                    |   ||
  ||  | SECTION                                            |   ||
  ||  | +------------------------------------------------+ |   ||
  ||  | |                                                | |   ||
  ||  | |                                                | |   ||
  ||  | +------------------------------------------------+ |   ||
  ||  +----------------------------------------------------+   ||
  ||                                                           ||
  ||  AREA                                                     ||
  ||  +----------------------------------------------------+   ||
  ||  |                                                    |   ||
  ||  +----------------------------------------------------+   ||
  ||                                                           ||
  .=============================================================.

All these elements can have the following content

  .page|area|section|group
       .header
          .title
       .body
       .footer

Where .header contains header information (generally the .title) and a '.body' that takes the content. It's good to enclose the content in a '.body' instead of putting it as a direct child of the page/area/section/group because you can set 'padding' without affecting the 'width' of the container. The same for '.header' and '.footer'.

2.2.2.Inner content layout

You'll sometimes want to layout structural elements content so that some part will be to the left or to the right. To do this, Cassidy provides the following selectors:

  • .left for left-positioned layout
  • .middle for middle/center positioned layout
  • .right positioned layout
  +-------------------------------------------------------------+
  | LEFT                    MIDDLE                       RIGHT  |
  | +-------------+ +--------------------------+ +------------+ |
  | |             | |                          | |            | |
  | |             | |                          | |            | |
  | |             | |                          | |            | |
  | |             | |                          | |            | |
  | |             | |                          | |            | |
  | |             | |                          | |            | |
  | |             | |                          | |            | |
  | +-------------+ +--------------------------+ +------------+ |
  |                                                             |
  +-------------------------------------------------------------+

2.2.3.Positioned decorations

It is sometimes useful to have add hooks for specific decorative elements. If you want to use bitmaps to style the edges of a container, you'll need the following classes to hook your style definitions:

  • .N for “north
  • .S for “south
  • .E for “east
  • .W for “west
  • .NE for “north-east
  • .NW for “north-west
  • .SE for “south-east
  • .SW for “south-west
                     NW----------N----------NE
                     |                       |
                     |                       |
                     W                       E
                     |                       |
                     |                       |
                     SW----------S----------SE

It is generally good to enclose these decorations in a containing .decoration class, so that you can easily switch them on or off:

  .decoration
     .N
     .S
     .E
     .W
     .NE
     .NW
     .SE
     .SW

2.2.4.Example

Here is a complete example of how to use the above selectors:

<body id="SiteMainPage" class="page">

  <div id="Navigation" class="area">
    <div class="body">
           ...
        </div>
  </div>

  <div id="Content" class="area">
    <div class="header">&nbsp;</div>
    <div class="body">
        
      <div class="section Articles">
        <div class="header">
           <div class="left">&nbsp;</div>
           <div class="middle">&nbsp;</div>
           <div class="right">&nbsp;</div>
        </div>
        <div class="body">
           <div class="left">&nbsp;</div>
           <div class="middle content">
	   ...
	   </div>
           <div class="right">&nbsp;</div>
        </div>
        <div class="header">
           <div class="left">&nbsp;</div>
           <div class="middle">&nbsp;</div>
           <div class="right">&nbsp;</div>
        </div>
      </div>
    
    <div class="footer">&nbsp;</div>
  </div>
</body>
/* Structural elements */
.Content .header          { ... }
.Content .body            { ... }
.Content .footer          { ... }
/* Strucutral elements layout */
.Articles .header .left   { ... }
.Articles .header .middle { ... }
.Articles .header .right  { ... }
.Articles .body   .left   { ... }
.Articles .body   .middle { ... }
.Articles .body   .right  { ... }
.Articles .footer .left   { ... }
.Articles .footer .middle { ... }
.Articles .footer .right  { ... }

2.3.Core: Formatting annotations

It is common to use a generic CSS classes to have a specific effect on the rendering elements. These are classes that will help laying out elements:

  • clear-left: clears the element to is left
  • clear-right: clears the element to its right
  • clear-both: clears both left and right sides of the element
  • absolute: the element is positioned absolute
  • relative: the element is positioned relative
  • block: the element is a block element
  • inline: the element is an inline element
  • centered: the element is centered in the parent element
  • no-list: will indicate that an <ul> padding, margin and list style type will be none.
  • clearfix: ensures that the clearing is properly made. This is a well known CSS trick to solve clearing floats.
  • hidden: an element that you don't want to show

You also may want to give more hints about the way you are going to render an element:

  • big: you'd like the element to be big (but less than 'bigger')
  • bigger: you'd like the element to be bigger/more visible
  • small: you'd like the element to be small (but less than 'smallerb')
  • smaller: you'd be the element to be smaller/more compact
  • standard: you'd like to force the standard size for this element
  • highlighted: the current element should be emphasized/highlighted
  • webdings: to use the webdings font

2.4.Core: Meta-information annotations

When you are implementing lists in HTML, you'd probably want to give hooks to style these lists in the most flexible way. Here are some classes to be used with elements placed in sets or lists:

  • first: the first element of the set/list
  • last: the last element of the set/list
  • even: elements with an even (0,2,4,6,…) indice
  • odd: elements with an odd (1,3,5,7,…) indice
  • current: the current element in the set/list
  • previous: the previous element in the set/list
  • next: the next element in the set/list

Now here are some classes that help indicate the state of the current element:

  • empty: there is nothing in this element
  • optional: indicate that something is optional (useful with forms)
  • required: indicate that something is required (useful with forms)
  • disabled: the element is disabled (it should be grayed out, or de-opacified)
  • fake: the element is only here in the HTML prototype
  • template: the element is a template to be used by the JavaScript code

2.5.Widgets: Containers

The first group of widget classes that we want to provide are classes that help organize specific widgets. These are usually called containers, because they are made to contain widgets. Here are the classes we propose:

  • w-panel to identify a panel, which is basically a zone that will contain other widgets.
  • w-group to identify a group of elements contained in a panel. This is typically what you would use to contain a set of widgets that implement a specific feature like filtering a set of results.
  • w-window thought rare, you may use windows in your web app.
  • w-dialog dialogs are windows that require direct interaction with the user

We also provide more specific containers that hold elements in different ways:

  • w-list contains elements organized as a list.
  • w-set contains elements organized as a set

Every container can of course use any of the classes mentioned before, especially the structure annotation classes such as header, body and footer, which make styling even easier.

2.6.Widgets: Interaction

The next group of widget classes that are useful are classes that allow interaction with the user, such as buttons and forms.

  • w-button for a standard button
  • w-button-disabled for a disabled standard button
  • w-button-default for a default button
  • w-button-default-disabled for a disabled default button
  • w-button-small for a small button
  • w-button-small-disabled for a disabled small button
  • w-button-small-default for a small default button
  • w-button-small-default-disabled for a disabled small default button
  • w-label for the button label (surprising, eh ?)

This may seem like a lot of classes, but buttons are actually a very, very important part of the UI, and thus deserve adequate classes to differentiate them.

Another important set of interaction elements are forms, and they have to be structured in different sections:

  • w-form to denote the starting of a form
  • w-form-description for descriptive elements within the set
  • w-form-example for an exemple/illustration in the form
  • w-form-group for a group of widgets in a form
  • w-form-group-emphasis to put the emphasis on a group within the form
  • w-form-group-optional for optional groups within the form
  • w-form-row for a row containing widgets (you can play with nested label and inputs)
  • w-form-input for inputs (wether they are actually HTML inputs or not)
  • w-form-submit denotes the button that is used to submit the form, though you'd probably use the 'w-button-*' classes listed before.

As a general principle, interaction widgets are used within containers. So you can always redefine their appearance by prefixing them with the specific or generic container class. For instance, an AlertBox buttons could be styled like:

.AlertBox w-button           { ... }
.AlertBox w-button-default   { ... }

Specific form elements (checkboxes, text areas, etc) can be styled using the existing HTML elements as selectors. You might also have a look at the interaction annotations that specify classes that allow to denote errors and the state of different fields in the form.

2.7.Widgets: Feedback

One of the cornerstone of modern application UI design is to provide good feedback when the user is doing things (but not as much as say… Windows ;). There are a number of different types of feedback widgets that you can use:

  • w-tooltip: displayed when you have your mouse over and item
  • w-hint: a tooltip that give a hint to the user about something (it's good with forms)
  • w-info: a more detailed version of the tooltip, usually with some interactive element
  • w-notification: a notification of an event
  • w-alert: an alert box (tell the user about something)
  • w-question: a question box (ask confirmation of something)

2.8.Widget: Events

Events classes denote what's currently happening for a specific widget. These classes denote the effects of user interaction, so you'll find a mix of state-related annotations and some more classic UI interaction events (minus focus and hover which have CSS pseudo-selectors for this):

  • on-select: the element was selected
  • on-deselect: the element was deselected
  • on-change: the element was changed
  • on-empty: the element was emptied

Here are the classic drag-and-drop events:

  • on-drag when an element is being dragged
  • on-dragOver when an element has an other element being dragged over
  • on-dragOverAccept when an element accepts the dragged over element
  • on-dragOverRefuse when an element refuses the dragged over element
  • on-drop when an element is dropped over an element
  • on-dropAccept when an element is dropped and accepted by the target element
  • on-dropRefuse when an element is dropped and refused by the target element

Here are generic states that can results from events (especially with forms):

  • on-error when an error happened
  • on-warn when a warning was issued
  • on-process when an element is processing something
  • on-success when everything went fine

These classes should be dynamically added and removed (after some finely tuned delay) to produce nice UI effects.

2.9.Summary

We've seen all the different parts of the Cassidy CSS framework, so here comes the time of the mandatory summary of the selectors. This will help you have all the selectors at once.

Core
Content structure
page, area, section, content, title
Content decoration
header, body, footer, left, middle, right
Layout formatting
clear-left, clear-right, clear-both, absolute, relative, centered, no-list, clearfix, hidden
Layout hints
bigger, smaller, standard, highlighted
Position meta
first, last, even, odd, current, previous, next
State meta
empty, optional,'required', 'disabled' 'fake', 'template'
Widgets
Containers
w-panel, w-group, w-window, w-dialog w-list, w-set
Forms
w-form, w-form-description, w-form-example, w-form-group, w-from-group-emphasis, w-form-group-optional, w-form-row, w-form-input, w-form-submit
Interaction
w-button[-default|-small][-disabled], w-button-label
Feedback
w-tooltip, w-hint, w-info, w-notification, w-alert, w-question
Events (state)
on-select, on-deselect, on-change, on-empty
Events (DnD)
on-drag, on-dragOver, on-dragOverAccept, on-dragOverRefuse', 'on-drop', 'on-dropAccept', 'on-dropRefuse'
Events (status)
on-error, on-warn, on-process, on-success

3.Bonus: Stuff to help you

3.1.Do not forget to…

HTML browsers do not offer all the same defaults, so it's a good idea to redefine them. Here is a list of CSS selectors that you should fill-in to have a clean base of your website:

 /* Core HTML elements */
 html                 { ... }
 body                 { ... }
 table                { ... }
 table tr td          { ... }
 ul                   { ... }
 ol                   { ... }
 ul li                { ... }
 h1                   { ... }
 h2                   { ... }
 h3                   { ... }
 /* Links */
 a:link               { ... }
 a:active             { ... }
 a:hover              { ... }
 a:visited            { ... }
 /* Forms */
 form                 { ... }
 form label           { ... }
 input[type=text]     { ... }
 input[type=password] { ... }
 input[type=button]   { ... }
 input[type=submit]   { ... }
 textarea             { ... }

Redefining this set of styles is sufficient to get a first cut at the styling of your web site.

3.2.How the others do it

Naming conventions are important to ensure consistency in any framework.

Problems with IE:

  • .A.B will apply do both A and B class elements instead of elements with both A and B classes. This means that you have to do a specific class for that.

Example: Facebook

  • Uses ids, lower_case
  • Classes are lower_case
  • Classes and subclasses are explicitly prefixed: app_switcher, app_switcher_button, app_switcher_selected
  • Subclasses prefix are sometimes compressed dashboard_header and dh_titlebar, dh_links
  • Subclasses always come after the container: .dashboard_header .dh_titlebar
  • Rarely more than two levels of selectors
  • No multiple classes

Example: LastFM

  • Uses ids, CamelCase, mixedCase, alllowercase and lower_case
  • Some ids are broken down, like LastAd_FooterLeft, LastAd_Mid, LastAd_Top
  • Subclasses are either CamelCase or mixedCase (most) or alllowercase
  • CamelCase classes are used for top-level containers sometimes corresponding to ids (.LastAd and #LastAd)
  • Classes and subclasses are usually prefixed eventPoster and eventPosterTitles
  • Some subclasses are prefixed (with compressed prefix), like .dashboardWidget, .dbwContainer
  • Two or three levels of selectors are common
  • No multiple classes

Example: Netvibes

  • Uses ids, mixedCase, or lower-case
  • Classes are mixedCase too, sometimes lower-case, rarely lower_case or lowercase
  • Classes are sometimes prefixed (#feedReader .feedContent)
  • Some classes have a compressed prefix nv-tabListNav, nv-thumbnailedList
  • Rarely more than two levels of selectors
  • No multiple classes

Example: Reddit

  • Uses ids, lowercase
  • Classes are lowercase too
  • Usually one level, two levels of selectors at most
  • No multiple classes

Example:Ext-JS

  • Uses lower-case and lowercase ids
  • Some ids are broken down, like collapsedimg_forumhome_activeusers, #collapseimg_forumhome_birthdays
  • Classes are lower-case
  • Classes are often prefixed (x-dlg-bd, x-dlg-ft, ext-mb-input, ext-mb-progress-bar, ux-startbutton-center)
  • Classes are often fully qualified (.ux-taskbuttons-scroller-left instead of .ux-taskbuttons .scroller-left)
  • Rarely more than two levels of selectors
  • No multiple classes

Example: Blueprint CSS

  • Uses lowercase ids scarcely
  • Classes are lower-case
  • No common prefix
  • Formatting-oriented classes (align-left, align-center, align-justify, etc)
  • Only one level of selectors
  • No multiple classes

Example: WYMstyle

  • Uses lower-case and sometimes lower_case ids
  • Some ids are prefixed nav-lang, nav-pri, nav-sec
  • Classes are lower-case
  • Formatting-oriented classes (float-left, float-right, force-new-line, etc)
  • Only one level of selectors
  • No multiple classes
note
Be careful when using id attributes in your HTML documents, as HTML ids will populate your browser JavaScript namespace, giving the opportunity to make name clashes. Usually, the rule is that document ids won't override global declarations in your JavaScript namespace, even if an HTML element id is declared after your global variable.
  • -

PIEPosition is Everything website