clearfixの無いリスト要素(ul,li)ベースのフォーム(form)

リスト要素ベースのフォームを作ってみる

colissさんのこちらの紹介記事、

フォームをリスト要素で並べたスタイルシートのチュートリアル - coliss

これを見て「お!かっこいい!」と思い試してみました。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <style type="text/css">
            #comment{
                width:15em;
                height:5em;
            }
            ul,li{
                border:0;
                margin:0;
                padding:0;
                list-style:none;
            }
            li{
                clear:both;
                list-style:none;
                padding:4px 0;
            }
            textarea,
            input{
                float:left;
            }
            label{
                width:140px;
                float:left;
            }
        </style>
    </head>
    <body>
        <ul>
            <li><label>ニックネーム</label><input id="name"/></li>
            <li><label>URL</label><input id="url"/></li>
            <li><label>コメント</label><textarea id="comment"></textarea></li>
            <li><label>&nbsp;</label><input id="send" type="submit" value="send"/></li>
        </ul>
    </body>
</html>


こんな感じ。

フォームに質感を出してみる

で、どうせなら ulのbackground-color や liのborder をいれて質感だそうとしたんだけど..

/* 追加 */
ul{
    background: #ccc;
    border:solid 1px #ddd;
}
li {
    background: #eee;
    border-top: solid 1px #fff;
    border-bottom: solid 1px #e7e7e7;
    margin:0 0 1px 0;
}
IE6、IE7、IE8Beta

Safari、Opear、Firefox


こんななっちゃいます...
SafariOpera については、label や input に float がかかってるので、包括要素である li に子要素を考慮した高さが出ないためで、これを解決するには

    • li に clearfix をかける
    • li に float をかけ width:100% とし、その包括要素の ul に clearfix をかけ width を設定する

という方法が思いつきます。まず前者の li に clearfix をかける方法を試してみました。

/* 追加 */
li:after {
    content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden;
}
li{
    display:inline-block;
}
IE6、IE7

IE8 Bata


モダンブラウザは問題ありませんでしたが、IEの表示がこんな風に崩れてしまいます。(あ!IE8はinline-blockのせいか?ハックしなきゃまずかったかな?)
次に後者の li に float、ul に clearfix の方法を試してみました。

/* 追加 */
ul{
    width:450px;
    _display:inline-block;
}
ul:after {
    content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden;
}
li{
    float:left;
    width:100%;
}
IE6、IE7、IE8Beta

Safari、Opear、Firefox


モダンブラウザ、IE共に想定どうりに表示されました。めでたしめでたし。

clearfixを無くせるか?オレオレCSSフレームワーク mydesign.css への適用

ただ、clearfixは記述が冗長だし、オレオレフレームワーク(詳しくはこちら)のパーツ要素などにはあまり使用したくないなぁと思っていたところ、またまたcolissさんの記事で以下のような記述を発見。

フロートのクリア
フロート要素を包括するdivが、内包要素の全体を包んでいない場合があります。

解決方法
いろいろな解決方法がありますが、シンプルな解決方法を紹介します。
「overflow:hidden」を包括要素に指定します。
「overflow:auto」はFirefoxで問題を起こすことがあります。

IE6の場合はhasLayoutが原因なので、「height」「width」の指定や「zoom:1」を使用してください。

クロスブラウザのためのHTML/CSSのテクニック集 - coliss

え!たったこれだけで clearfix いらなくなるってこと?ほんと?
ということで私のもう一つのブログで、サンプルHTMLを作って各ブラウザで確認してみました。

サンプルページ
IE6 OK!
IE7 OK!
IE8 beta OK!
Safari(Windows) OK!
Opera OK!
Firefox2.0 OK!
Firefox3.0 OK!

できちゃったよ...
包括要素にoverflow:hiddenが許されるレイアウトなら、clearfixいらないってこと?ほんと?

クロスブラウザのためのHTML/CSSのテクニック集 - Cyokodog::Blog

問題ありませんでした。う〜ん、でもそんなうまい話あるかなぁってことでもう少し調べたところ、既にこちらの記事のコメント欄で議論されてました。

「clearfixハックは本当に必要なのか」 - MID

これを読む限り、どうやら以下に目をつむれば使用OKみたいな感じです。

    • IE5、MacIE、ネスケで表示に問題あり
    • マウスホイールを使用した場合に動作に問題が発生するケースがある

個人的には全然OKですかね。あと、overflow:autoを前提に議論されてますが、colissさんの紹介記事によると

「overflow:auto」はFirefoxで問題を起こすことがあります。

となってるので、overflow:hidden の方がいいかもしれません。heightを指定してないんであれば、overflow:autoにこだわる必要もないと思うので...
ということで、オレオレフレームワークでもclearfixやめてこちらに切り替えてこうかなと思います。こんな感じの定義を追加しました。

my-parts.css
ul.my-form{
    list-style:none;
    border:none;
    width:400px;
    zoom:1;
    overflow:hidden;
/*gap*/
    margin:1em 16px;
    padding:1px 1px 0 1px;
}
ul.my-form li{
    list-style:none;
    border:none;
    float:left;
    clear:both;
    width:100%;
/*gap*/
    margin:0 0 1px 0;
    padding:4px 0;
}
ul.my-form li .my-label-for{
    float:left;
}
ul.my-form li label{
    float:left;
    display:block;
    width:8em;
/*gap*/
    padding-left:2px;
}
使用例
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link type="text/css" rel="stylesheet" href="../lib/mydesign/mydesign.css" />
        <link type="text/css" rel="stylesheet" href="../lib/mydesign/myparts.css" />
    </head>
    <body>
        <div id="ex1">
            <ul class="my-form">
                <li><label>ニックネーム</label><input class="my-label-for" id="name"/></li>
                <li>
                    <label>URL</label>
                    <div class="my-label-for">
                        <input id="url1"/><br/>
                        <input id="url2"/>
                    </div>
                </li>
                <li><label>コメント</label><textarea class="my-label-for" id="comment"></textarea></li>
                <li><label>&nbsp;</label><input class="my-label-for my-button" id="send" type="submit" value="send"/></li>
            </ul>
        </div>
    </body>
</html>


質感を出したい場合はこんな感じの定義を追加します。

#ex1 ul.my-form{
    background:#ccc;
    _border-bottom:solid 1px #ccc;
    width:300px;
}   
#ex1 ul.my-form li{
    background:#eee;
}   
#ex1 ul.my-form li{
    border-top:solid 1px #fff;
    border-bottom:solid 1px #e7e7e7;
}   

関連記事

ちなみに包括要素に高さがでないとか、clearfixとかの話はCSS HappyLifeさんのこちらの記事が分かりやすいかと思います。

なぜ親にfloatを指定する事で背景が繰り返されるかといいますと、floatってのは浮いたような状態になっています。
浮いたような状態というのは、通常の流し込みのルールから外された浮いた存在という意味での浮いたような状態ですが、イメージとして実際に浮いていると考えていただくと分かり易いと思います。

浮いているってことは、floatを指定されたいわゆるフロートボックスの親要素にあたる#main_containerは子要素(フロートボックス)が無いものとして解釈します。子要素が無いんだから、高さが出るはずもありません。

サイドの背景画像を本文にあわせてページの最後まで表示する - CSS HappyLife

Webtech Walkerさんのとこでは、ul、dl、table を使った form のマークアップの仕方を紹介されてます。

よくある横並びのフォームですが、どのようにマークアップするのがいいのか迷います。今まではよく定義リスト(dl)を使ってマークアップしていまたのですが、他にもいろいろなマークアップがありそうなので書き出して見ました。

横並びのフォームのマークアップ - Webtech Walker