web-dev-qa-db-ja.com

テーブルなしでフォームのスタイルを設定して配置するにはどうすればよいですか?

フォームフィールドを完全に揃えるために<table>sを使用することに慣れました。これは私が一般的に私のフォームを書く方法です:

<table border="0">
   <tr>
     <td><label for="f_name">First name:</label></td>
     <td><input type='text' id='f_name' name='f_name' /></td>
     <td class='error'><?=form_error('f_name');?></td>
   </tr>
</table>

私はこれが悪い習慣であることを知っています、そして私は欲しい CSS、<label>s<div>s、またはよりクリーンな方法を使用します。ただし、実際には、<table>sはフォームに対して非常にうまく機能します。すべてが正確に配置され、間隔が完璧で、すべてのエラーが互いに正確に下にあるなどです。

最近、フォームに<dt>タグと<dd>タグを使用しようとしましたが、見た目が非常に優れているという理由だけで、テーブルに戻ることになりました。

<table>sを使用せずに、この種の整列されたテーブルレイアウトを取得するにはどうすればよいですか?

30
Click Upvote

これは多くのサポートを得られないかもしれませんが、ここに私の2セントがあります:

状況によっては、テーブルは簡単レイアウト用です。 3つの列やフォームなど(純粋なcssフォームレイアウトを実行するためのいくつかの優れた提案がここにありますが、それらも無視しないでください)。

プロセスと方法論は優れた使用人を作ることができますが、マスターは貧弱です。
-「TheArt of SoftwareSecurityAssessment」のMarkDowd、John McDonald、Justin Schuh 

この引用はこの状況に非常に強く当てはまると思います。テーブルレイアウトが機能していて、アクセシビリティの問題を引き起こさず、壊れていない場合は、修正しないでください。

「あなたがすべき」、「しなければならない」、「常に」のようなフレーズ-私を怖がらせます。一粒の塩で熱狂者を連れて行ってください。

26
Gavin Miller

はい、ラベルとCSSを使用します。

<label class='FBLabel' for="FName">First Name</label>
<input value="something" name="FName" type="text" class='FBInput'>
<br>

css:

.FBLabel, .FBInput {
    display:block;
    width:150px;
    float:left;
    margin-bottom:10px;
}

参照: http://www.alistapart.com/articles/prettyaccessibleforms

テーブルを使用しない場合は、ラベルの幅を事前に知っておく必要があります。これは、多言語サイト(i18n)では問題になることがよくあります。

テーブルを使用すると、さまざまなサイズのラベルに合わせて伸縮します。 CSSだけでは、十分にサポートされた方法でそれを行うことはまだできません。

10
Damo

なぜテーブルを使いたくないのですか?彼らは今あなたのために完璧に働いているようです。アクセシビリティの問題が心配ですか?テーブルだからといって、アクセシビリティが低下するわけではありません。

純粋さのためだけに、解決された問題に対する新しい解決策を作成することからあなたに警告したいと思います。セマンティクスが心配な場合でも、とにかくどのようなセマンティクスがフォームを記述しますか?

5
Andrew Hare

私はほとんどの場合次の方法を使用しますが、これにより、すべての配置を希望どおりに正確に設定できます。ご覧のとおり、CSSとJS用のフックがたくさんあります。

<form id="login-form" action="#" method="post">
    <fieldset>
        <label id="for-email" for="email">
            <span class="label-title">Email Address <em class="required">*</em></span>
            <input id="email" name="email" type="text" class="text-input" />
        </label>

        <label id="for-password" for="password">
            <span class="label-title">Password <em class="required">*</em></span>
            <input id="password" name="password" type="password" class="text-input" />
        </label>
    </fieldset>

    <ul class="form-buttons">
        <li><input type="submit" value="Log In" /></li>
    </ul>
</form><!-- /#login-form -->
5
Mark Hurd

テーブルなしでそれを行う方法はたくさんあります。基本的なフォーマットを理解したら、テーブルと同じように簡単に操作できます。最初に遊んでみるのは面倒です。だから、あなたのためにそれをすべて理解する作業をすでに行っている他の人に目を向けてください:

私も文書化しました 私が決めた方法 先週(スニペット):

<form action="/signup" method="post">
<fieldset>
<legend>Basic Information</legend>
<ol>
<li><label for="name">Name <span class="error">*</span>
    </label><input type="text" id="name" name="name" size="30" /></li>
<li><label for="dob">Date of Birth <span class="error">*</span></label>
    <div class="inputWrapper">
    <input type="text" id="dob" name="dob" size="10" />
    <span class="note">YYYY-MM-DD</span></div></li>
<li><label for="gender">Gender <span class="error">*</span></label>
    <select id="gender" name="gender">
    <option value=""></option>
    <option value="female">Female</option>
    <option value="male">Male</option>
    </select></li>
</ol>
</fieldset>
</form>

そしてCSS:

fieldset { 
    margin: 0 0 20px 0; } 

fieldset legend { 
    font-weight: bold; 
    font-size: 16px; 
    padding: 0 0 10px 0; 
    color: #214062; } 

fieldset label { 
    width: 170px; 
    float: left; 
    margin-right:10px; 
    vertical-align: top; } 

fieldset ol { 
    list-style:none; 
    margin: 0;
    padding: 0;} 

fieldset ol li { 
    float:left; 
    width:100%; 
    padding-bottom:7px; 
    padding-left: 0; 
    margin-left: 0; } 

fieldset ol li input, 
fieldset ol li select, 
fieldset ol li textarea { 
    margin-bottom: 5px; } 

form fieldset div.inputWrapper { 
    margin-left: 180px; } 

.note { 
    font-size: 0.9em; color: #666; }

.error{ 
    color: #d00; }
3
Parrots

ここでの非テーブルベースの回答のほとんどは、事前に決定された固定幅に依存しています。これは、国際化や、ラベルに必要な幅を確認できないその他のシナリオでは問題になる可能性があります。

しかし、CSSにはdisplay: tableまさにこの理由で:

[〜#〜] html [〜#〜]

<div class="form-fields">
  <div class="form-field">
    <label class="form-field-label" for="firstNameInput">First Name</label>
    <div class="form-field-control"><input type="text" id="firstNameInput"></div>
    <div class="form-field-comment">Required</div>
  </div>
  <div class="form-field">
    <label class="form-field-label" for="lastNameInput">Last Name</label>
    <div class="form-field-control"><input type="text" id="lastNameInput"></div>
    <div class="form-field-comment">Required</div>
  </div>
</div>

[〜#〜] css [〜#〜]

.form-fields {
  display: table;
}

.form-field {
  display: table-row;
}

.form-field-label,
.form-field-control,
.form-field-comment {
  display: table-cell;
  padding: 3px 10px;
}

シンプル。

2
megaflop

本当に誰と話すかによります。純粋主義者は、テーブル要素がレイアウト用ではなかったため、CSSを使用すると言います。しかし、私にとって、それが機能する場合、なぜそれを変更するのですか?現在、レイアウトにCSSを使用していますが、まだ変更していない、または変更しないレガシーコードがたくさんあります。

2
Ziltoid

私は過去にこれをかなり効果的に使用しました:

HTML:

<fieldset>
  <p>
    <label for="myTextBox">Name</label>
    <span class="field"><input type="text" name="myTextBox" id="myTextBox" /></span>
    <span class="error">This a message place</span>
  </p>
</fieldset>

CSS:

<style type="text/css">
fieldset label, fieldset .field, fieldset .error { display: -moz-inline-box; display: inline-block; zoom: 1; vertical-align: top; }
fieldset p { margin: .5em 0; }
fieldset label { width: 10em;  text-align: right; line-height: 1.1; }
fieldset .field { width: 20em; }
</style>

唯一の本当に落とし穴は、優雅に劣化するFirefox2です。 (少しハックですが、それほど悪くはない-moz-inline-boxを参照してください)

0
Joshua Shannon

これに万能なものはありません。ただし、使用したテーブルの例は改善できます。

<table>
  <tbody>
    <tr>
      <th scope="row"><label for="f_name">First name:</label></th>
      <td>
        <input type='text' id='f_name' name='f_name' />
        <?php form_error('f_name'); ?>
      </td>
    </tr>
    <!-- ... -->
  </tbody>
</table>

エラー部分についてはあまりよくわかりません。個別の列を用意するよりも、入力の横に配置する方が理にかなっていると思います。

0
user42092

私もこの問題を抱えていましたが、左側にメニューがあるコシディル(float:leftもあります)がありました。

そう。私の解決策は:html

<div class="new">
   <form>
     <label class="newlabel">Name</label>
     <input type="text" name="myTextBox" id="myTextBox" />
   </form>
</div>

css

.new {
    display:block;
}
.newlabel {
    min-width: 200px;
    float: left;
}

フォームクラスでも機能すると思いますが、実際には「新しい」クラスにはもっと多くのフォームがありました。

0
Manasse