不使用
是否可以实现类似
的效果?标签?

发布于 2024-08-20 15:58:13 字数 797 浏览 6 评论 0原文

我个人喜欢

标签,因为它如何绘制一个框并放置 < /a> 在它的顶部,越过边界。像这样。

我想要实现的目标的示例图像

但是, fieldset 元素是为了组织表单,使用它进行通用设计并不比使用表格进行通用设计更好。所以,我的问题是......如何使用另一个标签获得相同的结果?必须在(或任何其他标签)下删除边框将使用),并且由于可能存在“复杂”的主体背景图像,因此我无法仅将图例的背景颜色设置为与下面的元素相匹配。

我希望它无需 JavaScript 即可工作,但 CSS3 和基于 XML 的格式(例如 SVG 或 XHTML)也可以。

I personally like the <fieldset> tag because of how it draws a box and puts the <legend> at the top of it, over the border. Like this.

example image of what I'm trying to achieve

However, the fieldset element was made to organize forms, and using it for general design is no better than using tables for general design. So, my question is... how can I achieve the same result using another tag? The border has to be erased under the <legend> (or whatever other tag will be used), and since there could be a "complex" body background image, I can't afford to just set the background-color of the legend to match the one of the element under.

I'd like it to work without JavaScript, but CSS3 and XML-based formats (such as SVG or XHTML) are fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

戈亓 2024-08-27 15:58:13

演示 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>

Demo jsBin link

.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>

×眷恋的温暖 2024-08-27 15:58:13

不,这真的不可能。 甚至浏览器制造商自己也在努力解决这个问题。

当然,我无法抗拒不管怎样,尝试一下吧。我花了很多时间在这上面,Anonymous 同时提出了一个与我的非常相似的“解决方案”(他的 test1)。但我的不需要固定宽度的“图例”。

不过,这段代码显然有点破解,我不知道它在复杂的网站上表现如何。我也同意 Anonymous 的观点,即使用字段集进行分组并不像使用表格进行布局那么糟糕。字段集是为元素分组而设计的,尽管在 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 figurefigcaption 元素。这些似乎是您的示例中使用的最佳元素。

不过,这仅适用于问题的语义部分,因为我认为这些元素的渲染方式与字段集/图例不同。更不用说当前的浏览器可能还不支持这些元素。

No, it isn't really possible. Even browser makers themselves are struggling with that.

Of course, I couldn't resist having a go at it anyway. And I spent so much time on that, that Anonymous came up with a "solution" rather similar to mine in the mean time (his test1). But mine doesn't need the fixed width "legend".

This code is evidently a bit of a hack, though, and I don't know how well it'll fare in complex sites. I also agree with Anonymous that using a fieldset for grouping isn't nearly as bad as using tables for layout. Fieldsets were designed for grouping elements, though in HTML they're really only supposed to be used for grouping form controls.

.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>

As a side note, you might also want to have a look at the HTML5 figure and figcaption elements. Those seem to be the best elements to use in your example.

That's only for the semantic part of the issue, though, since I don't think those elements are rendered the same as a fieldset/legend. Not to mention that current browsers probably don't support these elements yet to begin with.

寂寞笑我太脆弱 2024-08-27 15:58:13

但是,这是为了组织
形式,并将其用于一般设计
并不比使用表格更好
总体设计

这是错误的。使用表格进行布局的主要问题是几乎没有布局映射到表格数据。第二个问题是,那些不映射到表格数据的数据都不是表格数据,而有些则不是。也就是说,标记的语义与页面的语义不匹配。此外,实际上,表格的布局机制通常使自定义样式和纯文本浏览变得痛苦或不可能。

现在,fieldset 显然具有对表单字段进行分组的意图。为外观选择元素几乎总是表明这是一个糟糕的选择。然而,对于这个具体的例子,我认为包含列表的 fieldset+legend 几乎没有缺点(事实上,我唯一能想到的是一个 scaper,它天真地将 fieldset 解释为发出表单信号,然后浪费用户的时间进行枚举它的内容不同;但我不知道有什么实际作用)。主要原因是 form 元素服务于包含输入的功能和语义目的,而 fieldset 从早期起就具有特殊的、不可再现的视觉效果。此外,如果字段集中的视觉元素以任何方式起作用,那么从语义上讲,字段集确实再次包含一组交互式小部件,这就是原始点。

我的建议是如果你愿意就使用它。我不会,但不是因为语义方面的考虑:我宁愿不依赖特殊效果,并且一般会避开形式而不是功能。

无论如何,这里有一些值得咀嚼的东西:

<!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>

However, it was made to organize
forms, and using it for general design
is no better than using tables for
general design

This is mistaken. The main problem with using tables for layout is that almost no layouts map to tabular data. The second problem is that none of those that don't map to tabular data are tabular data, and some of those that do aren't. That is, the semantics of the markup wouldn't match those of the page. In addition, pragmatically, tables' layout mechanism usually makes custom styling and text-only browsing painful or impossible.

Now, fieldset clearly has the intent of grouping form fields. And choosing an element for its appearance is almost always a sign it's a bad choice. However, for this specific example I would argue that a fieldset+legend containing a list has almost no disadvantages (in fact, the only one I can think of is a scaper which naively interprets fieldset as signalling a form and then wasting the user's time enumerating its contents differently; but I know of nothing which actually does this). The main reason for this is that the form element serves the functional and semantic purpose of containing inputs, while fieldset has possessed since the early days had special, non-reproducable visual effects. In addition, if the visual elements in the fieldset are in any way functional, semantically the fieldset does again contain a set of interactive widgets, which was the original point.

My advice is to use it if you want to. I wouldn't, but not because of semantic considerations: I prefer not to rely on special effects, and eschew form over function in general.

Anyway, here's something to chew on:

<!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>

输什么也不输骨气 2024-08-27 15:58:13

这里有一个可能的解决方案,重点是简单性(如果您可以稍微放松对透明背景的要求)。没有额外的元素。

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>

Here a possible solution with a focus on simplicity (if you can loose your requirement for transparent background a bit). No additional elements.

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>

朮生 2024-08-27 15:58:13

如果您还需要使用 border-radius :

body {
  font-family: monospace;
}

.not-a-fieldset {
  border: 3px solid blue;
  border-top: none;
  padding: 0 16px 16px;
  margin: 28px 0 0;
  border-radius: 4px;
}

.not-a-legend {
  font-size: 20px;
  margin: 0 -19px;
  overflow: hidden;
  transform: translate(0, -13px);
}

.not-a-legend > span {
  float: left;
  padding: 0 8px;
  line-height: 24px;
}

.not-a-legend::before,
.not-a-legend::after {
  content: '';
  height: 8px;
}

.not-a-legend::before {
  border-top: 3px solid blue;
  border-left: 3px solid blue;
  border-top-left-radius: 4px;
  float: left;
  margin: 10px 0 0;
  width: 8px;
}

.not-a-legend::after {
  border-top: 3px solid blue;
  border-right: 3px solid blue;
  border-top-right-radius: 4px;
  position: relative;
  display: block;
  left: 0;
  top: 10px;
  overflow: hidden;
}
<section class="not-a-fieldset">
  <h1 class="not-a-legend">
    <span>Legend</span>
  </h1>
  
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</section>

If you need to use border-radius as well:

body {
  font-family: monospace;
}

.not-a-fieldset {
  border: 3px solid blue;
  border-top: none;
  padding: 0 16px 16px;
  margin: 28px 0 0;
  border-radius: 4px;
}

.not-a-legend {
  font-size: 20px;
  margin: 0 -19px;
  overflow: hidden;
  transform: translate(0, -13px);
}

.not-a-legend > span {
  float: left;
  padding: 0 8px;
  line-height: 24px;
}

.not-a-legend::before,
.not-a-legend::after {
  content: '';
  height: 8px;
}

.not-a-legend::before {
  border-top: 3px solid blue;
  border-left: 3px solid blue;
  border-top-left-radius: 4px;
  float: left;
  margin: 10px 0 0;
  width: 8px;
}

.not-a-legend::after {
  border-top: 3px solid blue;
  border-right: 3px solid blue;
  border-top-right-radius: 4px;
  position: relative;
  display: block;
  left: 0;
  top: 10px;
  overflow: hidden;
}
<section class="not-a-fieldset">
  <h1 class="not-a-legend">
    <span>Legend</span>
  </h1>
  
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</section>

べ繥欢鉨o。 2024-08-27 15:58:13

我相信你已经知道答案了。

您有两个选择,提供自己的边框(这是很多不必要的工作)或定位一个遮挡边框的元素(这样做的问题是您只能有纯色背景色,但也许这样就可以了)。

据我所知,您无法在每个浏览器中很好地进行此练习。不过,我喜欢你的风格,这是正确的方法,但可能不是你能够以令人满意的方式解决的问题。

我对这些主题的一般看法是,您不应该尝试使用网络做一些需要 A)过度努力或 B)一开始并不完全明显的标记解决方案的事情。网络有其局限性,您最好遵守这些限制,而不是试图解决这些限制。

所以我不得不问,

有什么问题吗?

I believe you already know the answer.

You have 2 options, provide your own border (that's a lot of unnecessary work) or position an element with occludes the border (the problem with that is that you can only have a solid background color, but maybe that's fine).

To my knowledge there's not anything you can do to make this workout nicely in every browser out there. I like your style though, it's the right approach but probably not a problem you'll be able to solve in a satisfying manner.

My general opinion on these topics is that you should not try and do things with the web that requires A) excessive effort or B) a markup solution which is not entirely obvious to begin with. The web has limitations and you would do well to ad-her to them rather than trying to work around those limitations.

So I'm forced to ask, what's the problem with <legend/>?

山田美奈子 2024-08-27 15:58:13

我得到了一个合理的结果。

    <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>

I got a reasonable result.

    <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>

ゃ人海孤独症 2024-08-27 15:58:13

我稍微更新一下匿名者的提议:

<!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>

I update a little bit the propostion of Anonymous to that:

<!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>
迷爱 2024-08-27 15:58:13

使用 ::before 伪元素生成模拟

的上边框,然后将模拟

元素放置在具有 z-indexposition 属性的 ::before 块。最后,在模拟字段集的顶部使用渐变和纯色停止点,将线性渐变的顶部颜色设置为透明,以便假字段集后面的任何背景都将可见。

Use ::before pseudoelement to generate the top border of the emulated <fieldset>, then position the emulated <legend> element over the ::before block with z-index and position properties. Lastly, use gradient and a solid color-stop on the top of the emulated fieldset, setting the top color of the linear gradient to transparent so whatever background is behind the fake fieldset will be visible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文