2008年9月2日火曜日

CSS と JavaScript で伸縮する領域を作成

CSS で要素の相対的な位置指定 (2) のつづき

1. 伸縮する領域を作成したい

ウェブページにおいて、

縦横に伸縮する区画

を作成したい。

例えば、以下のような影のある領域を作成し、領域内にある文字の量と、ウィンドウのリサイズに応じて、「高さ・幅」が伸縮するようにしたい。

box

 

2. 方法

a. 画像の分割

上記のデザインを Gimp を使って作成。できたものを各パーツに分割する。分割する対象は、影になっている角の部分 3 つと、影の縦・横線を最小限の長さで取り出す。

2815750125_fc2aa781bc

背景となる色については、Web ページでは CSS により指定をするので、 ColorPickerTool Color Picker Tool を使って色を確認しておく。 Foreground Color をダブルクリックして、開かられるダイアログに HTML notation が表示されるので控えておく。

 

b. 構成要素の位置関係の概略

さて、上記のように分割した画像を使って領域を作成していく。以下の図では、影の部分を緑色で示している。また、角がわかりやすくなるように、角の大きさを拡大して示した。

kaisetu2

上図は 7 つの層から構成される。

kaisetu

下の層から、

  1. 右側の影
  2. 右上の角 (ぴったり重ねる)
  3. 右下の角 (下にずらす)
  4. 下側の影 (左にずらす)
  5. 左下の影 (左にずらす)
  6. 背景の色の部分 ( 上にずらす。 JavaScript で幅を動的に設定)
  7. 文字を書く部分 (ぴったり重ねる)

DSC01623

上記の位置を考えるときは、同じ大きさの小さな紙を用意し、それぞれにパーツに必要な画像に相当するものを書き込み、いろいろと重ね方を試行錯誤する方法が理解しやすかった。 実際には、 CSS において background の transparent を指定するので、透明な紙であると仮定して考える必要がある。

これを頭の中、または絵を描くだけでは、わけがわからなくなってしまった。 ^^;

 

c. JavaScript によるリサイズ

ウィンドウのリサイズによる JavaScript の操作については、「JavaScript でブラウザのウィンドウのリサイズに合わせて HTML の要素の値を更新」を参照。

HTML の要素の幅を取得するには、element.offsetWidth – MDC によると、offsetWidth を使うようだ。

Typically, an element's offsetWidth is a measurement which includes the element borders, the element horizontal padding, the element vertical scrollbar (if present, if rendered) and the element CSS width.

 

3. ソースコード

HTML のソースを以下に示す。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional/EN">
<html>
  <head>
    <title>伸縮する領域</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <script type="text/javascript">
    <!--
    /* このページが読み込まれたときに呼出される関数 */
    function setup(){
        resizeContent();
    }
    /* ウィンドウをリサイズしたときに呼出される関数
     * id が topLeft の要素の幅を広げる
     */
    function resizeContent(){
        topRightDiv = document.getElementById("topRightCorner");
        contentDiv  = document.getElementById("topLeft");
        contentDiv.style.width = topRightDiv.offsetWidth  + 11 + "px";
    }
    -->
    </script>
    
    <style type="text/css">
    <!--
    /* 右側の縦の影のライン */
    #rightLine{
        position: relative;
        background: transparent url("rightLine.png") right repeat-y;
        
        margin: 15%;
    }
    /* 右上の角の影 */
    #topRightCorner{
        position: relative;
        background: transparent url("topRightCorner.png") top right no-repeat;
    }
    /* 右下の角の影 */
    #bottomRightCorner{
        position: relative;
        top: 10px;
        background: transparent url("bottomRightCorner.png") bottom right no-repeat;
    }
    /* 下の横の影のライン */
    #bottomLine{
        position: relative;
        left: -10px;
        background: transparent url("bottomLine.png") bottom repeat-x;
    }
    /* 左下の角の影 */
    #bottomLeftCorner{
        position: relative;
        left: -10px;
        background: transparent url("bottomLeftCorner.png") bottom left no-repeat;
    }
    /* 背景となる色を指定する領域。
     * リサイズにより、JavaScript でこの領域の幅を変更する。
     */
    #topLeft{
        position: relative;
        background-color: #dddbff;
        top: -9px;
    }
    /* 文字を表示する領域 */
    #content{
        position: relative;
        padding: 20px;
    }
    -->
    </style>
    
    </head>
    <body onresize="resizeContent()" onload="setup()">

        <div id="rightLine">
            <div id="topRightCorner">
                <div id="bottomRightCorner">
                    <div id="bottomLine">
                        <div id="bottomLeftCorner">
                            <div id="topLeft">
                                <div id="content">
                                    ウィンドウのリサイズに合わせて幅と高さが変化する領域。
                                    JavaScript でoffsetWidth により要素の幅を取得し、
                                    width に設定する。
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

    </body>
</html>

これにより、ウィンドウのリサイズによって、以下のように伸縮する。

080902-019080902-020

Windows 上の、Firefox 3, IE 7, Opera 9.5, Safari 3.1 において動作した。ただし、 Safari の動作がちょっと微妙… (+_+) 昔のブラウザだとどうなのかなぁ~

それにしても、もっと簡単な方法はないかな? (@_@;)

 

4. その後

後で気がついたが、「左下の影」を左にずらすことなく、「下側の影」にぴったりと重ねた場合、 JavaScript を利用しなくてもよいはず。

betukkai2

重ねたものを上から見ると、ちょうど大きさが納まっていることがわかる。

betukkai

しかし、この方法では、文字のある要素において、 CSS の padding を指定すると、Firefox, Opera, Safari では問題なく表示されるが、 IE で表示が崩れてしまった…。なぜだろう。

パタッ(o_ _)o~†

それにしても、CSS って指定の方法はややこしいしい、ブラウザによって微妙に動作が違うのでやだなぁ~。統一してくれ~ (+_+)

 

画像ファイル

参考サイト