デフォルトのスタイルシートをオーバライドする

GWTはそのUI(ユーザインタフェース)に適用される一連のスタイルシートを「テーマ」として管理しており、〜.gwt.xml中のinherits要素で宣言することができるが、ウィザードからプロジェクトを作成した場合、デフォルトで3つのテーマが記述されており、プログラマはその中から選択することができる。

AddressBook.gwt.xmlで用意されているテーマ・スタイルシートを選択する
  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->

それぞれはモジュールとして宣言されているが、実際には中身はスタイルシートそのものであり、inheritsに記述するとGWTコンパイル時にスタイルシートがwarディレクトリの下に展開される

/**
 * The file contains styles for GWT widgets in the standard theme.
 *
 * In order to maintain cross-browser compatibility, the following syntax is
 * used to create IE6 specific style rules:
 *    .gwt-Widget {
 *      property: rule applies to all browsers
 *      -property: rule applies only to IE6 (overrides previous rule)
 *    }
 *    * html .gwt-Widget {
 *      property: rule applies to all versions of IE
 *    }
 */
body, table td, select {
  font-family: Arial Unicode MS, Arial, sans-serif;
  font-size: small;
}
:
:

このように一貫性のある基準となるスタイルシートが提供されるのは有り難いのだが、フォントファミリーが Arial Unicode MSは嫌だなあ等、書き換えたい箇所もある。 CSSの良い所の一つはその名(カスケード)の通り、スタイルを重ね合わせることができる事であり、このケースでフォントファミリを変えたい場合は同様のセレクタで違うフォントファミリを指定したスタイルシートを別個に用意して、それを元のスタイルシートよりも後で読み込むことだ。

カスケードするスタイルシートを用意する
    • AddressBook.css
body, table td, select {
  font-family: 'メイリオ', Arial, sans-serif;
  font-size: small;
}
スタイルシートをロードする

では上記のように別途用意したスタイルシートGWTのテーマをカスケード(オーバライド)するにはどうしたら良いのだろう。一番最初に思いつくのはエントリポイントに対応したHTMLにスタイルシートをリンクを記述する方法だろう。

    • AddressBook.html
<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="target-densityDpi=device-dpi, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
    <meta name="gwt:property" content="locale=ja_JP"/>
    <title>AddressBook</title>
    <script type="text/javascript" language="javascript" src="addressbook/addressbook.nocache.js"></script>
    <link rel="stylesheet" href="AddressBook.css" type="text/css">
  </head>

しかしこれはGWTでは上手くいかない。

実行してみれば分かるが、GWTはコンパイル時にhead要素の末尾に自身でinheritsしたスタイルシートを出力するからだ。同一セレクタの属性は後で読み込んだものが有効なため、期待通りにの動作にはならない(AddressBook.cssのGETに対して404が発生する)

      • AddressBook.html(実行時にhead要素の末尾にテーマのスタイルシートが適用されている)
  <head>
   <link rel="stylesheet" href="http://localhost:8080/addressbook/addressbook/gwt/standard/standard.css">
  </head>

ならばどうすれば良いのか? GWTでテーマとして選択されているスタイルシートの属性を上書きするには、HTMLには頼らずスタイルートを以下のように〜.gxt.xmlに明示的に記述することで可能である。

  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->
  <stylesheet src='AddressBook.css' /> 

このようにアプリケーション独自に宣言したスタイルシートのパスの起点はプロジェクト中の\publicディレクトリになるり、GWTコンパイルの結果、/war/addressbook/Addressbook.cssはデプロイするディレクトリ(war)配下にコピーされる。

なお、war/addressbook下にスタイルシートを静的に配置すれば良いと思いがちだが、このディレクトリ下はGWTコンパイル時に完全に書き換わるため、配置されたファイルは全て消えてしまうので注意が必要である。