web-dev-qa-db-ja.com

<fieldset>タグを使用せずに<fieldset>のような効果を達成することは可能ですか?

個人的には、 <fieldset> タグが好きです。これは、ボックスを描画し、 <legend> をその上部の境界線上に配置する方法のためです。このような。

example image of what I'm trying to achieve

ただし、fieldset要素は forms を整理するために作成されたものであり、一般的な設計に使用することは、一般的な設計にテーブルを使用することよりも優れています。だから、私の質問は...別のタグを使用して同じ結果を達成するにはどうすればよいですか?<legend>の下で境界線を消去する必要があります(または他のタグが使用される)、および「複雑な」ボディ背景画像がある可能性があるため、凡例のbackground-colorを下の要素の1つと一致するように設定する余裕はありません。

JavaScriptなしで動作するようにしたいのですが、CSS3とXMLベースの形式(SVGやXHTMLなど)は問題ありません。

49
zneak

いいえ、実際には不可能です。 ブラウザメーカー自身もそれに苦労しています。

もちろん、とにかくやってみることに抵抗することはできませんでした。そして、私はそのことに多くの時間を費やしました Anonymous は、平均的な時間で私のものにかなり似た「解決策」を思いつきました(彼のtest1)。しかし、私は固定幅の「レジェンド」を必要としません。

ただし、このコードは明らかにちょっとしたハックであり、複雑なサイトでどれだけうまくいくかはわかりません。また、グループ化にフィールドセットを使用することは、レイアウトにテーブルを使用することほど悪くないことにも匿名に同意します。フィールドセットは要素をグループ化するためにdesignedでしたが、HTMLでは実際にはフォームコントロールのグループ化にのみ使用されることになっています。

.fieldset {
  border: 2px groove threedface;
  border-top: none;
  padding: 0.5em;
  margin: 1em 2px;
}

.fieldset>h1 {
  font: 1em normal;
  margin: -1em -0.5em 0;
}

.fieldset>h1>span {
  float: left;
}

.fieldset>h1:before {
  border-top: 2px groove threedface;
  content: ' ';
  float: left;
  margin: 0.5em 2px 0 -1px;
  width: 0.75em;
}

.fieldset>h1:after {
  border-top: 2px groove threedface;
  content: ' ';
  display: block;
  height: 1.5em;
  left: 2px;
  margin: 0 1px 0 0;
  overflow: hidden;
  position: relative;
  top: 0.5em;
}
<fieldset>
  <legend>Legend</legend> Fieldset
</fieldset>

<div class="fieldset">
  <h1><span>Legend</span></h1> Fieldset
</div>

副次的な注意として、HTML5 figure および figcaption 要素もご覧ください。これらはあなたの例で使用するのに最適な要素のようです。

ただし、これらの要素がフィールドセット/レジェンドと同じようにレンダリングされるとは思わないため、これは問題のセマンティック部分のみです。言うまでもなく、現在のブラウザはおそらくこれらの要素をまだサポートしていないでしょう。

19
mercator

デモjsBinリンク

.fieldset {
  border: 1px solid #ddd;
  margin-top: 1em;
  width: 500px;
}

.fieldset h1 {
  font-size: 12px;
  text-align: center;
}

.fieldset h1 span {
  display: inline;
  border: 1px solid #ddd;
  background: #fff;
  padding: 5px 10px;
  position: relative;
  top: -1.3em;
}
<div class="fieldset">
  <h1><span>Title</span></h1>
  <p>Content</p>
</div>
45
Mathias Bynens

ただし、フォームを整理するために作成されたものであり、一般的なデザインに使用することは、一般的なデザインにテーブルを使用することよりも優れています

これは間違っています。レイアウトにテーブルを使用する場合の主な問題は、レイアウトが表形式データにほとんどマッピングされないことです。 2番目の問題は、表形式のデータにマップされないものはどれも表形式のデータではなく、そうでないものもあるということです。つまり、マークアップのセマンティクスはページのセマンティクスと一致しません。さらに、実用的には、テーブルのレイアウトメカニズムにより、通常、カスタムスタイルとテキストのみのブラウジングが苦痛または不可能になります。

現在、フィールドセットには、フォームフィールドをグループ化する意図が明確にあります。そして、その外観のために要素を選択することは、ほとんど常に悪い選択であるサインです。ただし、この特定の例では、リストを含むフィールドセット+レジェンドにはほとんど欠点はないと主張します(実際、私が考えることができる唯一のものは、フィールドセットをフォームを通知し、ユーザーの時間を浪費していると単純に解釈するスケーパーですその内容は異なりますが、実際にこれを行うものは何もありません)。これの主な理由は、フォーム要素が入力を含むという機能的および意味的な目的を果たし、初期の頃からフィールドセットには特殊で再現不可能な視覚効果があったためです。さらに、フィールドセット内の視覚要素が何らかの形で機能している場合、意味的には、フィールドセットには元のポイントであるインタラクティブなウィジェットのセットが再び含まれます。

必要に応じて使用することをお勧めします。私はそうしませんが、意味論的な考慮のためではありません。私は特殊効果に依存しないことを好み、一般的に機能よりも形式を避けます。

とにかく、ここで噛むものがあります:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>test</title><style type="text/css">

.fake_fieldset {
        border: 2px groove ButtonFace;
        border-top-width: 0;
        margin-left: 2px;
        margin-right: 2px;
        padding: .35em .625em .75em;
        margin-top: 1em;
        position: relative;
}

.fake_legend {
        margin-top: -1em;
}

.fake_legend.test1::before {
        position: absolute;
        top: 0;
        left: -1px;
        border-top: 2px groove ButtonFace;
        content: " ";
        width: 0.5em;
}

.fake_legend.test1::after {
        position: absolute;
        top: 0;
        right: -1px;
        border-top: 2px groove ButtonFace;
        content: " ";
        width: 80%;
}


.fake_fieldset.test2 {
        padding: 0;
        padding-top: 1px; /* no collapsed margin */
}

.fake_fieldset.test2 .fake_fieldset.container {
        margin: 0;
        border: 0;
}

.fake_legend.test2 {
        display: table;
        width: 100%;
}

.fake_legend.test2 span {
        display: table-cell;
}

.fake_legend.test2 span:first-child {
        width: 0.5em;
}
.fake_legend.test2 span:first-child + span {
        width: 0; /* cells stretch */
}
.fake_legend.test2 span:first-child,
.fake_legend.test2 span:last-child {
        /* the rest of this code is left as an exercise for the reader */
}


</style></head><body>

<fieldset><legend>foo</legend>bar</fieldset>

<div class="fake_fieldset test1"><div class="fake_legend test1">foo</div>bar</div>

<div class="fake_fieldset test2"><div class="fake_legend test2"><span></span><span>foo</span><span></span></div><div class="fake_fieldset container">bar</div></div>

</body></html>
6
Anonymous

ここでは、単純さに重点を置いた可能なソリューションを示します(透明な背景の要件を少し緩めることができる場合)。追加の要素はありません。

section {
  border: 2px groove threedface;
  padding: 1em;
}

section h2 {
  float: left;
  margin: -1.7em 0 0;
  padding: 0 .5em;
  background: #fff;
  font-size: 1em;
  font-weight: normal;
}
<section id=foo>
  <h2>
    Foo
  </h2>
  bar
</section>
1
untill

Anonymousの命題を少し更新します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>test</title><style type="text/css">

.fake_fieldset {
    border: 2px groove ButtonFace;
    border-top-width: 0;
    margin-left: 2px;
    margin-right: 2px;
    padding: .35em .625em .75em;
    margin-top: 1em;
    position: relative;
}

.fake_legend {
    margin-top: -1em;
}

.fake_legend.test1::before {
    position: absolute;
    top: 0;
    left: -1px;
    border-top: 2px groove ButtonFace;
    content: " ";
    width: 0.5em;
}

.fake_legend.test1::after {
    position: absolute;
    top: 0;
    right: -1px;
    border-top: 2px groove ButtonFace;
    content: " ";
    width: 80%;
}
.fake_legend.test1 div {
    z-index: 100;
    background: white;
    position: relative;
    float: left;
}


.fake_fieldset.test2 {
    padding: 0;
    padding-top: 1px; /* no collapsed margin */
}

.fake_fieldset.test2 .fake_fieldset.container {
    margin: 0;
    border: 0;
}

.fake_legend.test2 {
    display: table;
    width: 100%;
}

.fake_legend.test2 span {
    display: table-cell;
}

.fake_legend.test2 span:first-child {
    width: 0.5em;
}
.fake_legend.test2 span:first-child + span {
    width: 0; /* cells stretch */
}
.fake_legend.test2 span:first-child,
.fake_legend.test2 span:last-child {
    /* the rest of this code is left as an exercise for the reader */
}
</style></head><body>

<fieldset><legend>foo</legend>bar</fieldset>

<div class="fake_fieldset test1"><div class="fake_legend test1">foo</div>bar</div>

<div class="fake_fieldset test2"><div class="fake_legend test2"><span></span><span>foo</span><span></span></div><div class="fake_fieldset container">bar</div></div>

</body></html>
0
Mickael Dubois

あなたはすでに答えを知っていると思います。

2つのオプションがあり、独自の境界線を提供する(これは多くの不必要な作業です)か、境界線を遮る要素を配置します(それに関する問題は、単色の背景色しか持てないということですが、それで問題ないかもしれません)。

私の知る限り、このワークアウトをすべてのブラウザーでうまく行うためにできることは何もありません。私はあなたのスタイルが好きですが、それは正しいアプローチですが、満足できる方法で解決できる問題ではないでしょう。

これらのトピックに関する私の一般的な意見は、A)過度の努力またはB)初めから完全に明らかではないマークアップソリューションを必要とするWebを使用してはいけません。 Webには制限があり、これらの制限を回避しようとするのではなく、それらに固執する方がよいでしょう。

<legend />の問題は何ですか?

0
John Leidegren

::before擬似要素を使用して、エミュレートされた<fieldset>の上境界線を生成し、エミュレートされた<legend>要素を::beforeブロックとz-indexおよびpositionプロパティで配置します。最後に、エミュレートされたフィールドセットの上部にグラデーションと無地のカラーストップを使用し、線形グラデーションの上部の色を透明に設定して、偽のフィールドセットの背後にある背景が見えるようにします。

0

妥当な結果が得られました。

    <div>
      <div style='position:absolute;float:top;background-image: url("whiteSquare.jpg");height:20px;z-index:10;font-size:20px'>
            Header
        </div>
        
         <div style='position:absolute;float:top;border:1px dashed gray;width:300px;margin-top:12px;z-index:1'>
             <div style='margin-top:20px;'>
             <table>
              <tr>
                  <td>A</td>
                  <td>B</td>
                 </tr>
                 <tr>
                  <td>A</td>
                  <td>B</td>
                 </tr>
             </table>
             </div>
        </div>
    </div>
0
astronought