IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

MediaQuery まとめ

Media Query とは

CSS3 から導入される Media Type を大幅に拡張する仕様です。

そもそも Media Type とは

Media Type とは CSS 2 系に元々ある仕様で CSS を適用するメディア(パソコンの画面、テレビ、プリンタ用紙など)を指定するときに使います。
以下の例だと、 media 属性の中に記述されている all や screen や print が Media Type です。

<link rel="stylesheet" type="text/css" href="共通の.css" media="all" />
<link rel="stylesheet" type="text/css" href="パソコンの画面の.css" media="screen" />
<link rel="stylesheet" type="text/css" href="プリンタ用紙の.css" media="print" />

以下のようにカンマで区切って複数指定することもできます。

<link rel="stylesheet" type="text/css" href="テレビとパソコンの画面の.css" media="tv, screen" />

見たことありますよね!
他にも @media ルールや @import ルールでも使うことができます。

@import url("unko.css") tv, print; /* ← これこれ! */
@media tv, screen { /* ← これこれ! */
}

というわけで、 Media Type の復習でした!
もっと Media Type の細かい仕様を知りたい人は以下をどうぞ
Media types

Media Query は Media Type の拡張

で、 Media Query の話にもどります。 Media Query は Media Type の拡張です。
書ける場所も、 Media Type と同じで、

  • link 要素の media 属性
  • @media ルール
  • @import ルール

です。
Media Type と下位互換性があるので、 Media Type は Media Query の一つと考えることもできます。

Media Query では Media Type と比べて何が出来るようになっているのか

簡単にいうと、 CSS を適用するメディアを Media Type よりも細かく指定できるようになります。
抽象的に言っても分かりにくいので、実際に見てみましょう。

<link rel="stylesheet" type="text/css" href="おっきいウィンドウ用.css" media="screen and (min-height: 600px)" />
<link rel="stylesheet" type="text/css" href="ちっちゃいウィンドウ用.css" media="screen and (max-height: 599px)" />
<link rel="stylesheet" type="text/css" href="カラーディスプレイ.css" media="screen and (color)" />
<link rel="stylesheet" type="text/css" href="白黒ディスプレイ.css" media="screen and (monochrome)" />

こんな感じです。なんとなく、わかりますね^^
and と 括弧の中 が Media Type から Media Query への新しい部分です。

Media Query の文法

では、 Media Query の文法を見てみましょう

カンマと and

まず、 Media Query も Media Type と同じようにカンマ区切りで複数指定できます。

screen and (min-height: 600px) and (min-width: 300px), screen and (min-width: 400px), print

こうすると screen and (min-height: 600px) and (min-width: 300px) と screen and (min-width: 400px) と print の、「どれかの条件を満たすメディア」という意味になります。
つまり or のような働きをする訳ですね。(Media Query には or はありません)
次に、 and で区切られます。

screen and (min-height: 600px) and (min-width: 300px)

これは、さっきの例でも出てきましたが screen で (min-height: 600px) と (min-width: 300px) の、「すべての条件を満たすメディア」という意味になります。
ここまで、カンマと and の区切りを紹介しましたが、これはあくまでも区切りです。
以下のように、ネストさせることはできません。

((A and B), ((C, D) and E))
not と only

カンマで区切られた条件には、 not と only というプリフィックスを付けることができます。

not screen and (min-height: 600px) and (min-width: 300px)

not はその名の通り、それ以降の条件の意味を逆にします。

only screen and (min-height: 600px) and (min-width: 300px)

また、 only は何もしません。ただ単に、Media Query を理解できない UA (ブラウザ)に条件判定を失敗させるためにあります。

Media Type と Media Expression

カンマと and で区切られた条件は、以下の二つの種類があります。

  • Media Type
  • Media Expression

Media Type は、CSS2.1 の時代からあった screen や tv や print や all などです。
Media Type は必ず最初に一つ必要です。つまり、 and で区切られた条件の最初は絶対 Media Type です。
以下に Media Type の一覧を示します。

  • all
  • aural
  • braille
  • handheld
  • print
  • projection
  • screen
  • tty
  • tv
  • embossed

Media Expression はさきほどから出てきている (min-height: 600px) などです。
Media Expression は必ず丸括弧で囲まれています。

Media Feature と 値

Media Expression の丸括弧の中身は、 Media Feature と値がコロンで区切られて一個ずつです。
Media Feature は min-height とかで、値が 600px とかですね。
Media Feature が決まれば、 値がとるべき値の単位や型が決まります。
また、値を省略すると 0 ではない値という意味になります。(つまり、 (color) と書くと「(color:0) 以外」という意味)
以下に Media Feature の一覧を示します。

  • width, min-width, max-width
    • view port の横幅、つまりウィンドウの横幅 (css の長さの単位を使える)
  • height, min-height, max-height
    • view port の高さ、つまりウィンドウの高さ (css の長さの単位を使える)
  • device-width, min-device-width, max-device-width
    • バイスの横幅、つまりディスプレイの横幅 (css の長さの単位を使える)
  • device-height, min-device-height, max-device-height
    • バイスの高さ、つまりディスプレイの高さ(css の長さの単位を使える)
  • device-aspect-ratio, min-device-aspect-ratio, max-device-aspect-ratio
  • color, min-color, max-color
    • 256bit カラーなら 8 、 8bit カラーなら 3 というように bit を二進数で表したときの桁。カラーデバイスじゃないなら 0
  • color-index, min-color-index, max-color-index
    • バイスのカラールックアップ表のエントリーの数(??)
  • monochrome, min-monochrome, max-monochrome
    • 256bit モノクロなら 8 、 8bit モノクロなら 3 というように bit を二進数で表したときの桁。モノクロデバイスじゃないなら 0
  • resolution, min-resolution, max-resolution
    • 解像度(dpi、 dpcm という単位を使う)
  • scan
    • プログレッシブか、インタレースか(テレビだけ)
  • grid
    • グリッドの幅を指定する

ちなみに、 min- max- は以上、以下という意味です。たとえば、 (min-height: 300px) だと「ウィンドウの高さが 300px 以上」という意味。

ブラウザの実装状況

現在、 Media Query は以下の環境で、使うことができます。

Firefox では、 3 系も含めて使えませんでした><
IE でも使えません><

JavaScript での扱い

JavaScript では、 Media Type は MediaList オブジェクトで扱いますが、 Media Query はどのようになっているのでしょうか。
少し調べてみたところ、 DOM 2 Style の次期仕様である CSSOM の Editor's Draft に書きかけの項がありました。
CSS Object Model (CSSOM)
ここを見る限りでは、文字列にシリアライズ する方法はかなり細かく決まっているみたいですね。
今のところは、データ構造としては扱えなくて、MediaList の appendMedium メソッドで文字列を突っ込んだり、item メソッドシリアライズされた文字列を取得したりする感じになるのかな。
ちょっと残念

仕様

詳しい仕様はこちら、
Media Queries

まとめ

Media Query についてまとめてみました。

明日は、 1000 人スピーカプロジェクトの第四回カンファレンスです!

いよいよ、明日ですね!参加者の皆様!
忘れてないですよね><

基調講演

今回の基調講演は、「デベロッパーズサミット」の運営をしている、翔泳社の岩切さんにお願いしています。
岩切さんならではの苦労話やアドバイスなどが聞けるのではないでしょうか^^

スピーカ陣は以下の方々です(敬称略)

  • hogelog 「Wannabe ProgrammerからReal Programmerにいたるまで」
  • jj1bdx 「Learning Erlang - from a Prolog dropout's perspective」
  • isocchiWiiリモコン、赤外線がうまくいかない。フツーにASについて話します」
  • kuzuha 「タイトル未定」
  • Issm 「タイトル未定」
  • earth2001y 「おっぱいシミュレータではじめる有限要素法入門〜ポロリもあるよ〜」
  • ranha 「ゆとりでも作るOSとエミュレータ
  • sugamasao 「ハゲでもわかるメール基礎講座」
  • inajobCGIを書くのが面倒な人のためのJavaScript
  • daisuke_m 「タイトル未定」
  • Pgf2 「算術の話しを誤魔化しつつ適当に」
  • syou6162 「統計の話とかしようと思います」

今回は、Erlang から「おっぱいシミュレータ」まで幅広いジャンルの講演が聞けそうですね!とても楽しみです!

当日は、 ustream で生放送されます

明日の 13:00 〜 17:00 に、以下の URL へアクセスしてください。
http://www.ustream.tv/channel/1000speakers
会場への質問も ustream からのチャットで受け付けています。
直接参加できない方も、ぜひ ustream からご参加ください。

これまでの雰囲気はニコニコ動画で見ることもできます。

XPathGraph のテクニック

XPathGraph とは

http://xpath.kayac.com/
URL と XPath を指定すると URL の先をスクレイピングしてグラフを作ってくれるサービスです。

このエントリでは、どのような手順で XPath を組み立てていけばいいかをよくあるパターンで解説します。

0. 値の元となる要素を探す

<div class="hoge">1,234,567</div>
//div[@class="hoge"]

1. カンマを外すなど、純粋な数値に変換する

1,234,567
translate(//div[@class="hoge"], ",", "")

translate 関数は、第一引数の div を文字列に変換し、カンマを空の文字に置換します(つまり、カンマを削ります)

2. 演算する

1234567
translate(//div[@class="hoge"], ",", "") div 1000

div は割り算の演算子です。 div によって、translate の結果の文字列が数値に変換されます。

3. 小数点を消す

1234.567
floor(translate(//div[@class="hoge"], ",", "") div 1000)

floor 関数によって小数点は切り捨てられます。XPathGraph では 1.2 は 12 としてグラフにされてしまうので、必ず割り算をしたときは小数点を切り捨てるようにしておきましょう。

4. 完成!

1234

あとは、毎日グラフをチェックしてニヤニヤしましょう。

DOM 2 Style の JavaScript オブジェクト

CSS のデータを扱う JavaScript を書きたくて作った

いろいろと使えそうなので晒しておきます
まだ、インタフェースだけですよ><

var JSCSS = {};

// http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet
JSCSS.StyleSheet = function(type, disabled, ownerNode, parentStyleSheet, href, title, media) {
    this.type = type;
    this.disabled = disabled;
    this.ownerNode = ownerNode;
    this.parentStyleSheet = parentStyleSheet;
    this.href = href;
    this.title = title;
    this.media = media;
};
JSCSS.StyleSheet.prototype = {
    type : null,
    disabled : null,
    ownerNode : null,
    parentStyleSheet : null,
    href : null,
    title : null,
    media : null,
    constructor: JSCSS.StyleSheet
};

// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet
JSCSS.CSSStyleSheet = function(type, disabled, ownerNode, parentStyleSheet, href, title, media, ownerRule, cssRules) {
    JSCSS.StyleSheet.apply(arguments, this);
    this.ownerRule = ownerRule;
    this.cssRules = cssRules;
};
JSCSS.CSSStyleSheet.prototype = new JSCSS.StyleSheet(null, null, null, null, null, null, null);
JSCSS.CSSStyleSheet.prototype.ownerRule = null;
JSCSS.CSSStyleSheet.prototype.cssRules = null;
JSCSS.CSSStyleSheet.prototype.insertRule = function(rule, index) {
    this.cssRules.splice(index, 0, rule);
    return index;
};
JSCSS.CSSStyleSheet.prototype.deleteRule = function(index) {
    this.cssRules.splice(index, 1);
};
JSCSS.CSSStyleSheet.prototype.constructor = JSCSS.CSSStyleSheet;

// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSRuleList
JSCSS.CSSRuleList = function() {
    var self = [];
    self.item = JSCSS.CSSRuleList.prototype.item;
    self.constructor = JSCSS.CSSRuleList;
    return self;
};
JSCSS.CSSRuleList.prototype = {
    item: function(index) {
        return this[index];
    }
}


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSRule
JSCSS.CSSRule = function(type, cssText, parentStyleSheet, parentRule) {
    this.type = type;
    this.cssText = cssText;
    this.parentStyleSheet = parentStyleSheet;
    this.parentRule = parentRule;
};
JSCSS.CSSRule.prototype = {
    UNKNOWN_RULE: 0,
    STYLE_RULE: 1,
    CHARSET_RULE: 2,
    IMPORT_RULE: 3,
    MEDIA_RULE: 4,
    FONT_FACE_RULE: 5,
    PAGE_RULE: 6,
    type: null,
    cssText: null,
    parentStyleSheet: null,
    parentRule: null,
    constructor: JSCSS.CSSRule
};
JSCSS.CSSRule.UNKNOWN_RULE = JSCSS.CSSRule.prototype.UNKNOWN_RULE;
JSCSS.CSSRule.STYLE_RULE = JSCSS.CSSRule.prototype.STYLE_RULE;
JSCSS.CSSRule.CHARSET_RULE = JSCSS.CSSRule.prototype.CHARSET_RULE;
JSCSS.CSSRule.IMPORT_RULE = JSCSS.CSSRule.prototype.IMPORT_RULE;
JSCSS.CSSRule.MEDIA_RULE = JSCSS.CSSRule.prototype.MEDIA_RULE;
JSCSS.CSSRule.FONT_FACE_RULE = JSCSS.CSSRule.prototype.FONT_FACE_RULE;
JSCSS.CSSRule.PAGE_RULE = JSCSS.CSSRule.prototype.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleRule
JSCSS.CSSStyleRule = function(type, cssText, parentStyleSheet, parentRule, selectorText, style) {
    JSCSS.CSSRule.apply(arguments, this);
    this.selectorText = selectorText;
    this.style = style;
};
JSCSS.CSSStyleRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSStyleRule.prototype.selectorText = null;
JSCSS.CSSStyleRule.prototype.style = null;
JSCSS.CSSStyleRule.prototype.constructor = JSCSS.CSSStyleRule;
JSCSS.CSSStyleRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSStyleRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSStyleRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSStyleRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSStyleRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSStyleRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSStyleRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSMediaRule
JSCSS.CSSMediaRule = function(type, cssText, parentStyleSheet, parentRule, media, cssRules) {
    JSCSS.CSSRule.apply(arguments, this);
    this.media = media;
    this.cssRules = cssRules;
};
JSCSS.CSSMediaRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSMediaRule.prototype.media = null;
JSCSS.CSSMediaRule.prototype.cssRules = null;
JSCSS.CSSMediaRule.prototype.insertRule = function(rule, index) {
    this.cssRules.splice(index, 0, rule);
    return index;
};
JSCSS.CSSMediaRule.prototype.deleteRule = function(index) {
    this.cssRules.splice(index, 1);
};
JSCSS.CSSMediaRule.prototype.constructor = JSCSS.CSSMediaRule;
JSCSS.CSSMediaRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSMediaRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSMediaRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSMediaRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSMediaRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSMediaRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSMediaRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSFontFaceRule
JSCSS.CSSFontFaceRule = function(type, cssText, parentStyleSheet, parentRule, style) {
    JSCSS.CSSRule.apply(arguments, this);
    this.style = style;
};
JSCSS.CSSFontFaceRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSFontFaceRule.prototype.style = null;
JSCSS.CSSFontFaceRule.prototype.constructor = JSCSS.CSSFontFaceRule;
JSCSS.CSSFontFaceRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSFontFaceRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSFontFaceRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSFontFaceRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSFontFaceRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSFontFaceRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSFontFaceRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPageRule
JSCSS.CSSPageRule = function(type, cssText, parentStyleSheet, parentRule, selectorText, style) {
    JSCSS.CSSRule.apply(arguments, this);
    this.selectorText = selectorText;
    this.style = style;
};
JSCSS.CSSPageRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSPageRule.prototype.selectorText = null;
JSCSS.CSSPageRule.prototype.style = null;
JSCSS.CSSPageRule.prototype.constructor = JSCSS.CSSPageRule;
JSCSS.CSSPageRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSPageRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSPageRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSPageRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSPageRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSPageRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSPageRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSImportRule
JSCSS.CSSImportRule = function(type, cssText, parentStyleSheet, parentRule, href, media, styleSheet) {
    JSCSS.CSSRule.apply(arguments, this);
    this.href = href;
    this.media = media;
    this.styleSheet = styleSheet;
};
JSCSS.CSSImportRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSImportRule.prototype.href = null;
JSCSS.CSSImportRule.prototype.media = null;
JSCSS.CSSImportRule.prototype.styleSheet = null;
JSCSS.CSSImportRule.prototype.constructor = JSCSS.CSSImportRule;
JSCSS.CSSImportRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSImportRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSImportRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSImportRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSImportRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSImportRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSImportRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;

// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSCharsetRule
JSCSS.CSSCharsetRule = function(type, cssText, parentStyleSheet, parentRule, encoding) {
    JSCSS.CSSRule.apply(arguments, this);
    this.encoding = encoding;
};
JSCSS.CSSCharsetRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSCharsetRule.prototype.encoding = null;
JSCSS.CSSCharsetRule.prototype.constructor = JSCSS.CSSCharsetRule;
JSCSS.CSSCharsetRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSCharsetRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSCharsetRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSCharsetRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSCharsetRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSCharsetRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSCharsetRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSUnknownRule
JSCSS.CSSUnknownRule = function(type, cssText, parentStyleSheet, parentRule) {
    JSCSS.CSSRule.apply(arguments, this);
};
JSCSS.CSSUnknownRule.prototype = new JSCSS.CSSRule(null, null, null, null);
JSCSS.CSSUnknownRule.prototype.constructor = JSCSS.CSSUnknownRule;
JSCSS.CSSUnknownRule.UNKNOWN_RULE = JSCSS.CSSRule.UNKNOWN_RULE;
JSCSS.CSSUnknownRule.STYLE_RULE = JSCSS.CSSRule.STYLE_RULE;
JSCSS.CSSUnknownRule.CHARSET_RULE = JSCSS.CSSRule.CHARSET_RULE;
JSCSS.CSSUnknownRule.IMPORT_RULE = JSCSS.CSSRule.IMPORT_RULE;
JSCSS.CSSUnknownRule.MEDIA_RULE = JSCSS.CSSRule.MEDIA_RULE;
JSCSS.CSSUnknownRule.FONT_FACE_RULE = JSCSS.CSSRule.FONT_FACE_RULE;
JSCSS.CSSUnknownRule.PAGE_RULE = JSCSS.CSSRule.PAGE_RULE;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
JSCSS.CSSStyleDeclaration = function(cssText, parentRule) {
    this.cssText = cssText;
    this.parentRule = parentRule;
};
JSCSS.CSSStyleDeclaration.prototype = {
    cssText: null,
    parentRule: null,
    length: 0,
    item: function(index) {
        return this[index];
    },
    getPropertyValue: function(propertyName) {
        return this[propertyName];
    },
    getPropertyCSSValue: function(propertyName) {
        return this.cssValues[propertyName];
    },
    removePropertyCSSValue: function(propertyName) {
        delete this.cssValue[peropertyName];
        // TODO: length
        // TODO: return 
    },
    getPropertyPriority: function(propertyName) {
        return this.cssPriority[propertyName];
    },
    setPriority: function(propertyName, value, priority) {
        // TODO
    },
    constructor: JSCSS.CSSStyleDeclaration
};


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValue
JSCSS.CSSValue = function(cssText, cssValueType) {
    this.cssText = cssText;
    this.cssValueType = cssValueType;
};
JSCSS.CSSValue.prototype = {
    CSS_INHERIT: 0,
    CSS_PRIMITIVE_VALUE: 1,
    CSS_VALUE_LIST: 2,
    CSS_CUSTOM: 3,
    cssText: null,
    cssValueType: null,
    constructor: JSCSS.CSSValue
};
JSCSS.CSSValue.CSS_INHERIT = JSCSS.CSSValue.prototype.CSS_INHERIT
JSCSS.CSSValue.CSS_PRIMITIVE_VALUE = JSCSS.CSSValue.prototype.CSS_PRIMITIVE_VALUE
JSCSS.CSSValue.CSS_VALUE_LIST = JSCSS.CSSValue.prototype.CSS_VALUE_LIST
JSCSS.CSSValue.CSS_CUSTOM = JSCSS.CSSValue.prototype.CSS_CUSTOM


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue
JSCSS.CSSPrimitiveValue = function(cssText, cssValueType, primitiveType) {
    JSCSS.CSSValue.apply(arguments, this);
};
JSCSS.CSSPrimitiveValue.prototype = new JSCSS.CSSValue(null, null);
JSCSS.PrimitiveValue.prorotype.setFloatValue = function(unitType, floatValue) {
    // TODO
};
JSCSS.PrimitiveValue.prorotype.getFloatValue = function(unitType) {
    // TODO
};
JSCSS.PrimitiveValue.prorotype.setStringValue = function(stringType, stringValue) {
    // TODO
};
JSCSS.PrimitiveValue.prorotype.getStringValue = function() {
    // TODO
};
JSCSS.PrimitiveValue.prorotype.getCounterValue = function() {
    // TODO
};
JSCSS.PrimitiveValue.prorotype.getRectValue = function() {
    // TODO
};
JSCSS.PrimitiveValue.prorotype.getRGBColorValue = function() {
    // TODO
};
JSCSS.CSSPrimitiveValue.prototype.primitiveType = null;
JSCSS.CSSPrimitiveValue.prototype.CSS_UNKNOWN = JSCSS.CSSPrimitiveValue.CSS_UNKNOWN = 0;
JSCSS.CSSPrimitiveValue.prototype.CSS_NUMBER = JSCSS.CSSPrimitiveValue.CSS_NUMBER = 1;
JSCSS.CSSPrimitiveValue.prototype.CSS_PERCENTAGE = JSCSS.CSSPrimitiveValue.CSS_PERCENTAGE = 2;
JSCSS.CSSPrimitiveValue.prototype.CSS_EMS = JSCSS.CSSPrimitiveValue.CSS_EMS = 3;
JSCSS.CSSPrimitiveValue.prototype.CSS_EXS = JSCSS.CSSPrimitiveValue.CSS_EXS = 4;
JSCSS.CSSPrimitiveValue.prototype.CSS_PX = JSCSS.CSSPrimitiveValue.CSS_PX = 5;
JSCSS.CSSPrimitiveValue.prototype.CSS_CM = JSCSS.CSSPrimitiveValue.CSS_CM = 6;
JSCSS.CSSPrimitiveValue.prototype.CSS_MM = JSCSS.CSSPrimitiveValue.CSS_MM = 7;
JSCSS.CSSPrimitiveValue.prototype.CSS_IN = JSCSS.CSSPrimitiveValue.CSS_IN = 8;
JSCSS.CSSPrimitiveValue.prototype.CSS_PT = JSCSS.CSSPrimitiveValue.CSS_PT = 9;
JSCSS.CSSPrimitiveValue.prototype.CSS_PC = JSCSS.CSSPrimitiveValue.CSS_PC = 10;
JSCSS.CSSPrimitiveValue.prototype.CSS_DEG = JSCSS.CSSPrimitiveValue.CSS_DEG = 11;
JSCSS.CSSPrimitiveValue.prototype.CSS_RAD = JSCSS.CSSPrimitiveValue.CSS_RAD = 12;
JSCSS.CSSPrimitiveValue.prototype.CSS_GRAD = JSCSS.CSSPrimitiveValue.CSS_GRAD = 13;
JSCSS.CSSPrimitiveValue.prototype.CSS_MS = JSCSS.CSSPrimitiveValue.CSS_MS = 14;
JSCSS.CSSPrimitiveValue.prototype.CSS_S = JSCSS.CSSPrimitiveValue.CSS_S = 15;
JSCSS.CSSPrimitiveValue.prototype.CSS_HZ = JSCSS.CSSPrimitiveValue.CSS_HZ = 16;
JSCSS.CSSPrimitiveValue.prototype.CSS_KHZ = JSCSS.CSSPrimitiveValue.CSS_KHZ = 17;
JSCSS.CSSPrimitiveValue.prototype.CSS_DIMENSION = JSCSS.CSSPrimitiveValue.CSS_DIMENSION = 18;
JSCSS.CSSPrimitiveValue.prototype.CSS_STRING = JSCSS.CSSPrimitiveValue.CSS_STRING = 19;
JSCSS.CSSPrimitiveValue.prototype.CSS_URI = JSCSS.CSSPrimitiveValue.CSS_URI = 20;
JSCSS.CSSPrimitiveValue.prototype.CSS_IDENT = JSCSS.CSSPrimitiveValue.CSS_IDENT = 21;
JSCSS.CSSPrimitiveValue.prototype.CSS_ATTR = JSCSS.CSSPrimitiveValue.CSS_ATTR = 22;
JSCSS.CSSPrimitiveValue.prototype.CSS_COUNTER = JSCSS.CSSPrimitiveValue.CSS_COUNTER = 23;
JSCSS.CSSPrimitiveValue.prototype.CSS_RECT = JSCSS.CSSPrimitiveValue.CSS_RECT = 24;
JSCSS.CSSPrimitiveValue.prototype.CSS_RGBCOLOR = JSCSS.CSSPrimitiveValue.CSS_RGBCOLOR = 25;


// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValueList
JSCSS.CSSValueList = function(cssText, cssValueType, primitiveType) {
    var self = [];
    JSCSS.CSSValue.apply(arguments, self);
    for (var name in JSCSS.CSSValueList.prototype) {
        self[name] = JSCSS.CSSValueList.prototype[name];
    }
    return self;
};
JSCSS.CSSValueList.prototype = new JSCSS.CSSValue(null, null);
JSCSS.CSSValueList.prototype.item = function(index) {
    return this[index];
};
JSCSS.CSSValueList.prototype.constructor = JSCSS.CSSValueList;
JSCSS.CSSValueList.CSS_INHERIT = JSCSS.CSSValue.CSS_INHERIT
JSCSS.CSSValueList.CSS_PRIMITIVE_VALUE = JSCSS.CSSValue.CSS_PRIMITIVE_VALUE
JSCSS.CSSValueList.CSS_VALUE_LIST = JSCSS.CSSValue.CSS_VALUE_LIST
JSCSS.CSSValueList.CSS_CUSTOM = JSCSS.CSSValue.CSS_CUSTOM

// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-RGBColor
JSCSS.RGBColor = function(red, green, blue) {
    this.red = red;
    this.green = green;
    this.blue = blue;
};
JSCSS.RGBColor.prototype = {
    red: null,
    green: null,
    blue: null,
    constructor: JSCSS.RGBColor
};

// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-Rect
JSCSS.Rect = function(top, right, bottom, left) {
    this.top = top;
    this.right = right;
    this.bottom = bottom;
    this.left = left;
};
JSCSS.Rect.prototype = {
    top: null,
    right: null,
    bottom: null,
    left: null,
    constructor: JSCSS.Rect
};

// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-Counter
JSCSS.Counter = function() {
    this.identifier = identifier;
    this.listStyle = listStyle;
    this.separator = separator;
};
JSCSS.Counter.prototype = {
    identifier: null,
    listStyle: null,
    separator: null,
    constructor: JSCSS.Counter
};