CSSの最近のブログ記事

iTunes でおなじみの検索ボックス スタイル

勉強しないとだめなのについ掃除を始めちゃう、そんな気分なので、こんなの preview.png を CSS で再現しちゃう。

こうしちゃう

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
  <head>
    <title>検索ボックス</title>

    
    <style type="text/css">
      #search input.word
      {
        margin: 0;
        padding: 0.4em 0.4em 0.4em 24px;
        width: 16em;
        border: 1px solid silver;
        background-color: white;
        background-image: url("search.gif");
        background-position: 4px center;
        background-repeat: no-repeat;
      }

      #search input.active
      {
        color: black;
      }

      #search input.passive
      {
        color: gray;
      }
    </style>
    
    <script type="text/javascript">
      this.onload = function ()
      {
        var word = this.document.forms.search.word;
        
        word.onfocus = function ()
        {
          if (this.value == this.defaultValue)
          {
            this.value = '';
            this.className = 'word active';
          }
        }
        
        word.onblur = function ()
        {
          if (this.value == '')
          {
            this.value = this.defaultValue;
            this.className = 'word passive';
          }
        }
        
        word.onkeydown = function (event)
        {
          var e = event || window.event;
          
          if (e.keyCode == 13)
          {
            if (this.value != '')
            {
              this.form.submit();
            }
          }
        }
        
        word.onfocus();
        word.onblur();
      }
    </script>
  </head>

  
  <body>
    <form id="search" action="#dummy">
      <p>
        <input type="text" name="word" value="検索キーワードを入力して下さい" class="word" tabindex="1" accesskey="F" />
      </p>
    </form>

  </body>
</html>

こうなった

サンプルはこちらです。

問題点

  • CSS のサポートが控え目なブラウザでは控え目なスタイルに。
  • JavaScript を切ってたら Firefox 等で送信できない。これは type="submit" な INPUT 要素を追加して CSS で見えなくするべきかしら?

更に問題点

間に合わなくなった。

現在の状態

UL, OL 要素は入れ子にする事が出来ます。この時、項目数や入れ子が多くになるにつれて、項目同士の親子・兄弟関係が見辛くなるかもしれません。
fig1.png

親兄弟関係を表す線を入れる

そこで、項目同士の関係を表すを入れます。線の表現は CSS でやりたいと思います。その為にルートとなるリスト要素に treeView というクラス名を付け、各リストの最後の LI 要素にも last というクラス名を割り振ります。
fig2.png

<ul class="treeView">
  <li>2005年
    <ul>
      <li>9月</li>
      <li>10月</li>
      <li>11月</li>
      <li class="last">12月</li>
    </ul>
  </li>
  <li class="last">2006年
    <ul>
      <li>1月</li>
      <li>2月</li>
      <li>3月</li>
      <li>4月
        <ul>
          <li>1日</li>
          <li>3日</li>
          <li>4日</li>
          <li>20日</li>
          <li class="last">28日</li>
        </ul>
      </li>
      <li>5月</li>
      <li class="last">6月</li>
    </ul>
  </li>
</ul>

適用する CSS は以下の通りです。

.treeView
{
  background-color: white;
  
  font-family: "ヒラギノ角ゴ Pro W3", Osaka, Tahoma, Verdana, "MS UI Gothic", "MS Pゴシック", sans-serif;
  font-size: small;
  color: black;
}

.treeView,
.treeView ul,
.treeView ol
{
  margin: 0 0 0 20px;
  padding: 0;

  background-image: url("line_vertical.png");
  background-repeat: repeat-y;
}

.treeView li
{
  margin: 0;
  padding: 0;
  
  background-image: url("line_diverge.png");
  background-repeat: no-repeat;

  text-indent: 20px;
  line-height: 160%;

  list-style-type: none;
  list-style-position: outside;
}

.treeView li.last
{
  background-color: white;
  background-image: url("line_terminal.png");
}

項目最後の要素にクラス名を振るのが大変

更新が多い部分で用いる場合、クラス名を手作業で振り直すのはかなりの作業量です。許されるなら JavaScript でクラス名を割り振ります。

function setTreeViewStyle(list)
{
  list.className = "treeView";
  
  setTreeViewItemStyle(list);
}

function setTreeViewItemStyle(list)
{
  var items = list.childNodes;
  var marked = false;
  
  for (var i = items.length - 1; i >= 0; i--)
  {
    var element = items[i];
    
    if (element.tagName && element.tagName.toLowerCase() == "li")
    {
      if (!marked)
      {
        element.className = "last";
        marked = true;
      }

      var subItems = element.childNodes;
      
      for (var j = subItems.length - 1; j >= 0; j--)
      {
        var element = subItems[j];
        
        if (element.tagName)
        {
          switch (element.tagName.toLowerCase())
          {
            case "ul":
            case "ol":
              setTreeViewItemStyle(element);
              
              break;
          }
        }
      }
    }
  }
}

実際に利用する場合は以下のようにします。

<body onload="setTreeViewStyle(document.getElementById('tree'));">
  <ul id="tree">
    <li>2005年
    <ul>
      <li>9月</li>
      <li>10月</li>
      ...後略

こんな過去ログの索引があるとする

<ul>
<li><a href="#Y2000">2000年</a>
<ul>
<li><a href="#Y2000M1">1月</a></li>
<li><a href="#Y2000M2">2月</a></li>
<li><a href="#Y2000M3">3月</a></li>
<li><a href="#Y2000M4">4月</a></li>
<li><a href="#Y2000M5">5月</a></li>
<li><a href="#Y2000M6">6月</a></li>
<li><a href="#Y2000M7">7月</a></li>
<li><a href="#Y2000M8">8月</a></li>
<li><a href="#Y2000M9">9月</a></li>
<li><a href="#Y2000M10">10月</a></li>
<li><a href="#Y2000M11">11月</a></li>
<li><a href="#Y2000M12">12月</a></li>
</ul>
</li>
<li><a href="#Y2001">2001年</a>
<ul>
<li><a href="#Y2001M1">1月</a></li>
<li><a href="#Y2001M2">2月</a></li>
<li><a href="#Y2001M3">3月</a></li>
<li><a href="#Y2001M4">4月</a></li>
<li><a href="#Y2001M5">5月</a></li>
<li><a href="#Y2001M6">6月</a></li>
<li><a href="#Y2001M7">7月</a></li>
<li><a href="#Y2001M8">8月</a></li>
<li><a href="#Y2001M9">9月</a></li>
<li><a href="#Y2001M10">10月</a></li>
<li><a href="#Y2001M11">11月</a></li>
<li><a href="#Y2001M12">12月</a></li>
</ul>
</li>
</ul>

見た目はこんな感じ。うーん、縦に長すぎる。
fig1.png

水平に並べてスペースを縮めたい

全部インライン要素として表示させちゃう。ちなみに LI 要素の display は 'list-item' なので、'inline' に変えてしまう事で list-style-type や list-style-position などの指定は無効になる…のかな。

ul,
li
{
	display: inline;
	margin: 0;    /* デフォルトの margin をクリア。 */
	padding: 0;    /* デフォルトの padding をクリア。 */
}

fig2.png

飾り付けてそれらしく

ul,
li
{
	display: inline;
	margin: 0;
	padding: 0;
}

body
{
	line-height: 200%;
}

a
{
	padding: 0.2em 1em;

	border-right: 1px solid silver;
	border-bottom: 1px solid silver;

	background-color: #FFF0E0;

	font-weight: bold;
	text-decoration: none;
}

ul ul a
{
	background-color: #F8F8F8;
}

fig3.png

Ajax なチャット

| | コメント(2)

Ajax の習作、RO風のチャット。
ajaxchat.png

サンプルは こちら。ソースコードは こちら
自由に使いねい。エラーが出たら教えてくれい。
動作確認 (Win32) Internet Explorer 5.5/6.0 Netscape 7.1 Firefox 1.0.4 Opera 8.01

従来のチャットと何が違うのか?
画面偏移がない
湖に浮かぶ白鳥が泳ぐように、見えない場所でがんばるのが Ajax の役目。

Ajax はクライアントとサーバーの関係を変える物ではない?
クライアントの要求を細かく処理していく。待たせない。

なんとなくかっこいい?
空賊連合よりはかっこいい。豚も言っている。

将来性は?
タダで作れるところがポイント。お金があるなら Flash 等のリッチクライアントを使用すべし。

document.styleSheets

| | コメント(0)

ページ内でスタイルシートを動的に変更する。こんな話題があったので調べてみた。

LINK 要素で取り込まれた CSS は、document オブジェクトの styleSheets オブジェクトでアクセスする事が出来る。ただし Opera については該当するオブジェクトがない(?)。

たとえば現在読み込まれている CSS ファイルを知るには、以下のように書く。

var styleSheets = document.styleSheets;

for (var i = 0, iMax = styleSheets.length; i < iMax; i++)
{
	var styleSheet = styleSheets[i];

	alert(styleSheet.href);
}

このサンプルは こちら

この href プロパティを変更してやれば動的に CSS を読み込みに行き、結果的に変更できる。ただし Opera ではこの手法は使えないので、選択したスタイルシートをクッキーやクエリに憶えさせておき、リロード時に LINK 要素を動的に生成する事で対応するのが一般的な模様。

さらに、個々の CSS ルールを知るには以下のようにする。

var styleSheets = document.styleSheets;
var report = "";

for (var i = 0, iMax = styleSheets.length; i < iMax; i++)
{
	var styleSheet = styleSheets[i];
	var rules = styleSheet.rules || styleSheet.cssRules;
	
	// ファイルを取得
	report += "[" + styleSheet.href + "]" + "\n";
	
	for (var j = 0, jMax = rules.length; j < jMax; j++)
	{
		var rule = rules[j];
		var styles = rule.style;
		
		// セレクタを取得
		report += "[" + rule.selectorText + "]" + "\n";

		// プロパティ : 値 を取得
		for (var property in styles)
		{
			var value = styles[property];
			
			// 値がなければ省略
			if (value == "")
			{
				continue;
			}

			report += property + ":" + value + "\n";
		}
	}
}

// ウィンドウが大きすぎた場合 F4 で閉じる
alert(report);

サンプルは こちら処理が重いので注意!

書き直し

| | コメント(3)

Dr.blog で頂いたテンプレートだが、文章構造やCSSが少しばかりいじり難かったので、デザインはそのままで全て書き直すことにした。

CSS でレイアウトをするのはあまり経験がなかったので、基本に戻り練習してみる。以下の簡単な文章を用意し、ヘッダ・フッタ・メニュー・本文のレイアウトを考えてみる。


<html>
	<body>
		<h1>ヘッダー</h1>

		<ul>
			<li>ここにお品書き1</li>
			<li>ここにお品書き2</li>
			<li>ここにお品書き3</li>
		</ul>

		<p>
			ここに本文
		</p>

		<address>
			著作権表示
		</address>
	</body>
</html>

H1 要素がヘッダー、UL 要素がメニュー、P 要素が本文、ADDRESS 要素がフッターと考える。これらは全てブロック要素なので、いかにこのブロックを積み上げるかでレイアウトを決めていくのだ。


*
{
	margin: 0;
	padding: 0;
}

h1
{
	text-align: center;
	
	background-color: #E0F0FF;
}

ul
{
	float: left;
	width: 30%;

	background-color: #FFFFE0;
}

p
{
	float: left;
	width: 70%;

	background-color: #F0FFF0;
}

address
{
	clear: left;

	background-color: #FFF0F0;
}

こうすると以下のようになる。
よくある2カラムのスタイルだ。
2colum.png
メニューと本文の左右を入れ替えたければ P 要素と UL 要素の回り込みを float: left; から float: right; とし、ADDRESS 要素の回り込み解除を clear: left; から clear: right; とするだけでいい。

また、お品書きをヘッダの下へ横一列に並べて、その下に本文としたい場合は以下のようにする。


*
{
	margin: 0;
	padding: 0;
}

h1
{
	text-align: center;
	
	background-color: #E0F0FF;
}

ul
{
	background-color: #FFFFE0;
}

ul li
{
	float: left;

	background-color: #FFFFF0;
	
	list-style-type: none;
	list-style-position: outside;
}

p
{
	clear: both;

	background-color: #F0FFF0;
}

address
{
	background-color: #FFF0F0;
}

flat.png

文章構造をいじる事なく、CSS 一つ変更するだけで見た目が大きく変わる。CSS とはやればやるほど実に面白い物だ。

現在(2005/06/30)の MovableType 用のテンプレートは Dr.Blog 様で配布している物を利用させて頂いている。
青と白と黒の組み合わせが好みに合っていてかっこいいのだ。
不満は LI 要素内のインライン要素がセンタリングされてしまう点。
箇条書きがセンタリングされるのは見辛い、と思うのだ。

まずは文章構造は確認。
Netscape 付属の Composer で見るとこうなっている。

本文に当たる構造は以下のようになっている事が分かる。 body > div#container > table > tr > td > div#center > div#content > p

次に該当箇所の CSS を確認。

#center
{
	float: left;
	text-align: center;
	width: 500px;
	overflow: hidden;
}

そのまんま、text-align: center; が子要素に継承されていた様子。
そして P 要素など、その都度 text-align: left; とされている。
ぱっと見、デフォルトでセンタリングされている箇所はヘッディングとテーブルのキャプションぐらいな物だが、何か隠された意図があるのかしら…。

この箇所をコメントアウトし、ついでに気になる部分も修正して今回は終了。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちCSSカテゴリに属しているものが含まれています。

前のカテゴリはActionScript 3.0です。

次のカテゴリはHTMLです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.12