ラベル、テキストボックス、ボタンをいい感じに並べてみる。

いい感じとは、左端にラベル、右端にボタン、真ん中にテキストボックスを置いてブラウザの幅が変更されると真ん中のテキストボックスが伸縮するような物を作ってみる。

hoge

2パターン作ったんだけど、どっちがいいんだろう。

CSS display:tableを使う方法

HTMLはこんな感じ。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <link rel="Stylesheet" type ="text/css" href="style.css" >
    </head>
<body>
    <div id="container">
        <div id="label-div" class="table-cell"><span id="label">ラベル</span></div>
        <div id="textbox-div" class="table-cell"><input id="textbox"></div>
        <div id="btn-send-div" class="table-cell"><button id="btn-send">送信</button></div>
    </div>
</body>
</html>

CSSはこんな感じ。

#container {
    display: table;
    width: 100%;
}

.table-cell {
    display: table-cell;
    padding: 4px;
}

#label-div {
    width: 1%;
    white-space: nowrap;
}

#textbox-div {
    width: 100%;
}

#btn-send-div {
    width: 1%;
    white-space: nowrap;
}

#label {
    vertical-align:middle;
}
#textbox {
    width: 100%;
    box-sizing: border-box;
}
  • コンテナのdivは、display:table、幅は100%でめーいっぱいにしてる。
  • 子要素は、display:table-cell、paddingを指定する。
  • ラベル、ボタン共通に指定するのは、width:1%、white-space:nowrapを指定する。
    • width:1% は実質コンテンツのサイズが1%以上になるんでコンテンツのサイズになる。テキストボックスで100%指定していて合計で100%を越えるけどこのあたりは自動調整されるようだ。
    • white-space:nowrap は、折返ししないようにする。これがないとwidthで1%にしているので折り返されて表示される。ちょうど縦に1文字ずつ並ぶような感じになる。
  • テキストボックス、テキストボックスを含むdivでwidth:100%を指定してテキストボックスにはbox-sizing:border-boxを指定する。
    • テキストボックスを含むdivでwidth:100%でラベルやボタンの1%と合わせて100%越えるし実際ラベルやボタンは1%より大きくなっているけどこのあたりは調整されて、ラベル、ボタンの幅を除いた目いっぱいになるように調整される。
    • テキストボックスのbox-sizing:border-boxはwidthの範囲を「ボーダーまでを含んだものだよ。」と指定している。デフォルトはコンテンツの幅になるんで、指定しないとはみ出したような感じになる。(幅の認識が違うんでそーなる)

CSS display:flexを使う方法

HTMLはこんな感じ。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <link rel="Stylesheet" type ="text/css" href="style.css" >
    </head>
<body>
    <div id="container">
        <span id="label" class="item">ラベル</span>
        <input id="textbox" class="item">
        <button id="btn-send" class="item">送信</button>
    </div>
</body>
</html>

CSSはこんな感じ。

#container {
    display: flex;
    width: 100%;
    align-items: center;
    flex-wrap: wrap;
}

.item {
    margin: 4px;
}

#label {
    white-space: nowrap;
}

#textbox {
    flex-grow: 1;
}

#btn-send {
    white-space: nowrap;
}
  • コンテナのdivは、display:flex、幅は100%でめーいっぱいにしてる。
    • align-items:centerで、内部要素を縦方向中央にして、flex-wrap:wrapで内部要素を折り返すようにしている。tableで実現した場合と違い幅が狭くなると折り返して配置されるようになる。(tableで同じことができるかはよくわかんない(^^;))
  • 各要素はmargin:4pxでマージンを指定している。
  • ラベル、ボタンはwhite-space:nowrapで折り返しなしにしている。
  • flex-growでコンテナ内の要素の比率を指定する。テキストボックスは1、ラベル、ボタンはデフォルト値(0)にしているので、ボタン、ラベルは0なので余った部分がテキストボックスの幅になる。

flexの方がシンプルだしいいような気がする。