名称-值对的语义和结构
Posted
技术标签:
【中文标题】名称-值对的语义和结构【英文标题】:Semantics and Structure of Name-Value Pairs 【发布时间】:2011-03-17 21:37:45 【问题描述】:这是我一直在努力解决的一个问题。标记名称/值对的正确方法是什么?
我喜欢
- 元素,但它带来了一个问题:无法将一对与另一对分开——它们没有唯一的容器。从视觉上看,代码缺乏定义。不过,从语义上讲,我认为这是正确的标记。
<dl>
<dt>Name</dt>
<dd>Value</dd>
<dt>Name</dt>
<dd>Value</dd>
</dl>
在上面的代码中,无论是在代码中还是在渲染中,都很难在视觉上正确地偏移对。例如,如果我想在每对之间设置边框,那将是一个问题。
我们可以指向表格。可以说名称-值对是表格数据。这对我来说似乎不正确,但我看到了这个论点。但是,html 不区分名称和值,除了位置或添加类名。
<table>
<tr>
<td>Name</td>
<td>Value</td>
</tr>
<tr>
<td>Name</td>
<td>Value</td>
</tr>
</table>
从视觉的角度来看,这在代码和 CSS 中都更有意义。对上述边框进行样式设置是微不足道的。但是,如上所述,语义充其量是模糊的。
想法、cmets、问题?
编辑/更新
也许这是我应该明确提到的与结构有关的事情,但定义列表也存在没有对这些对进行语义分组的问题。 dd
和 dt
之间的顺序和隐含边界很容易理解,但我仍然觉得它们有点偏离。
【问题讨论】:
Re:您的编辑/更新 - 如果您想绝对确保节点之间的语义关系没有歧义,您总是可以变得非常冗长并执行<dl>
还不错,但很难设置内联显示对的样式(如表格中)
已经有很多好的答案,尤其是在代码方面,但我对几乎所有答案都有些犹豫。这只是因为每个解决方案都是一个让步。我将很快将当前答案之一标记为最适合此线程,但要知道这是一个艰难的决定。
@Danny Lin 就是其中之一!由于改进的规范,语义和风格轻松! ***.com/a/50313363/792888
【参考方案1】:
感谢这个有趣的问题。这里还有一些需要考虑的事情。
什么是一对?两个元素在一起。所以我们需要一个标签。
假设它是pair
标签。
<pair></pair>
该对包含键和对应的值:
<pair><key>keyname</key><value>value</value></pair>
然后,我们需要列出这些对:
<pairlist>
<pair><key>keyname</key><value>value</value></pair>
<pair><key>keyname</key><value>value</value></pair>
</pairlist>
接下来要考虑的是对的显示。 通常的布局是表格布局:
key value
key value
和可选的分隔符,通常是冒号:
key : value
key : value
可以通过 CSS 轻松添加冒号,但这在 IE 中肯定行不通。
上述案例是理想的案例。但是没有有效的 HTML 标记可以轻松适应这种情况。
总结一下:
dl
在语义上最接近,用于键和值的简单情况,但很难应用视觉样式
(例如,显示内联对或为刚刚悬停的对添加红色边框)。最适合dl
的案例是词汇表。但这不是我们讨论的情况。
在这种情况下我能看到的唯一替代方法是使用table
,如下所示:
<table summary="This are the key and value pairs">
<caption>Some notes about semantics</caption>
<thead class="aural if not needed">
<tr><th scope="col">keys</th><th scope="col">values</th></tr>
</thead>
<tbody class="group1">
<tr><th scope="row">key1</th><td>value1</td></tr>
<tr><th scope="row">key2</th><td>value2</td></tr>
</tbody>
<tbody class="group2">
<tr><th scope="row">key3</th><td>value3</td></tr>
<tr><th scope="row">key4</th><td>value4</td></tr>
</tbody>
</table>
还有一个:
<ul>
<li><strong>key</strong> value</li>
<li><strong>key</strong> value</li>
</ul>
或:
<ul>
<li><b>key</b> value</li>
<li><b>key</b> value</li>
</ul>
或者,当键可能被链接时:
<ul>
<li><a href="/key1">key1</a> value</li>
<li><a href="/key2">key1</a> value</li>
</ul>
键值对通常存储在数据库中,而那些通常存储表格数据, 所以这张桌子最适合恕我直言。
你怎么看?
【讨论】:
非常彻底的答案。我喜欢你展示你的思路的方式。 +1 还有这样的事情:<ul> <li><div class="key">key</div><div class="value">value</div></li> </ul>
whit 我们可以有任意键和值(一个值可以是另一个列表、图像等)
另外,对于表格解决方案,也许您可以使用<col class="key"/>
标签。反正我觉得table的方案不好,如果能把key和value分在不同的行显示会怎样?
我相信(嗯,几乎知道)<strong>
应该根据 HTML5 语义替换为 <b>
。
这个问题在谷歌中排名第一。您能否考虑更新您的答案以反映@Danny Lin 关于在dl
中使用div
s 的意见?这解决了语义和样式的问题,从而避免了<b>
和<strong>
的噪音:***.com/a/50313363/792888【参考方案2】:
按照 Alexandr Antonov 提供的specification(和further details):使用dl
、dt
、dd
,以及可选的div
。
dl
、dt
和 dd
的组合对于键值对来说在语义上很好:
<dl>
<dt>Key1</dt>
<dd>Value1</dd>
<dt>Key2</dt>
<dd>Value2</dd>
</dl>
为了更轻松地进行样式设置或解析,div
s 可以用作 dl
的子代以对键值对进行分组(并使 dt
和 dd
成为 dl
的孙子代):
dl display: table;
dl > div display: table-row;
dl > div > dt, dl > div > dd display: table-cell; border: 1px solid black; padding: 0.25em;
dl > div > dt font-weight: bold;
<dl>
<div>
<dt>Key1</dt>
<dd>Value1</dd>
</div>
<div>
<dt>Key2</dt>
<dd>Value2</dd>
</div>
</dl>
【讨论】:
优秀的答案,恕我直言,应该接受答案,特别是考虑到规范中包含的示例完全适合这个问题。 CSS Grid 也是一种简单有效的格式化方式。【参考方案3】:XHTML 2 引入了使用 di
元素对术语和定义进行分组的能力
<!-- Do not us this code! -->
<dl>
<di>
<dt>Name</dt>
<dd>John</dd>
</di>
<di>
<dt>Age</dt>
<dd>25</dd>
</di>
</dl>
X/HTML 5 vs XHTML 2 > Enhancement To Definitions Lists
不幸的是,XHTML 2 已死,而 HTML5 没有 di
元素
所以,您可以将ul > li
与dl > dt + dd
结合起来:
<ul>
<li>
<dl>
<dt>Name</dt>
<dd>John</dd>
</dl>
</li>
<li>
<dl>
<dt>Age</dt>
<dd>25</dd>
</dl>
</li>
</ul>
【讨论】:
天哪。哇。我想要<di>
元素。我现在就想要。可惜我拿不到。不过,感谢您提供的信息!
根据规范,div
扮演di
的角色。详情见我的回答。【参考方案4】:
我认为定义列表可能是个坏主意。从语义上讲,它们用于定义。其他键值列表通常与定义标题和描述不同。
table
是一种方法,但是无序列表呢?
<ul>
<li class="key-value-pair">
<span class="key">foo</span>
<span class="value">bar</span>
</li>
</ul>
【讨论】:
定义列表在这方面的命名可能有点不恰当,但它们并非纯粹用于定义(如果它们是,它们的用例将相当有限) - W3C 规范。定义它们实际上有一个使用它们标记对话的示例。 从面向对象的角度考虑,我想我正在寻找的是“名称-值对的无序列表”,但我不确定这是最好的答案(目前)。 +1 这是一种微格式的方法,但在默认的浏览器渲染或屏幕阅读器中,你会得到foo bar
,就像foo bar
一样,根本没有任何标签。其中一个跨度需要超过一个跨度。也许<strong>
?那么第二个就不需要了。
在当前的HTML5 spec 中,dl 已被重新命名为描述列表,这使其在此处的使用看起来更正确。【参考方案5】:
dl
display: grid;
grid-template-columns: auto auto;
dd
margin: 0
<dl>
<dt>key</dt>
<dd>value</dd>
<dt>key</dt>
<dd>value</dd>
</dl>
我使用<dl>
<dt>
<dd>
并用网格设置样式
【讨论】:
【参考方案6】:这不是我喜欢的解决方案,但它是对语义元素的巧妙滥用:
为每个<dt>
/<dd>
对使用一个新的<dl>
:
<div class="terms">
<dl><dt>Name 1</dt><dd>Value 1</dd></dl>
<dl><dt>Name 2</dt><dd>Value 2</dd></dl>
</div>
悬停时带有 css 浮动和红色边框的示例:
dt:after content:":";
dt, dd float: left;
dd margin-left: 5px
dl float: left; margin-left: 20px; border: 1px dashed transparent;
dl:hover border-color: red;
<div class="terms">
<dl>
<dt>Name 1</dt>
<dd>Value 1</dd>
</dl><!-- etc -->
<dl><dt>Name 2</dt><dd>Value 2</dd></dl>
<dl><dt>Name 3</dt><dd>Value 3</dd></dl>
<dl><dt>Name 4</dt><dd>Value 4</dd></dl>
<dl><dt>Name 5</dt><dd>Value 5</dd></dl>
<dl><dt>Name 6</dt><dd>Value 6</dd></dl>
</div>
【讨论】:
有趣。如果不需要是相关项目的列表,这将起作用......尽管我想一个可以将每个<dl>
封装在 <li>
【参考方案7】:
很难在视觉上正确偏移对,无论是在代码中还是在渲染中。例如,如果我想在每对之间设置边框,那将是一个问题。
在我之前的其他人已经(我认为很好)处理了在代码中提供视觉定义的问题。这留下了渲染和 CSS 的问题。在大多数情况下,这可以非常有效地完成。最大的例外是在每组 dt/dds 周围放置一个边框,这无疑是非常棘手的 - 可能无法可靠地设置样式。
你可以这样做:
dt,dd border:solid;
dt margin:10px 0 0 0; border-width:1px 1px 0 1px;
dd margin:0 0 10px 0; border-width:0 1px 1px 1px; padding:0 0 0 10px;
dd::before content:'→ ';
这适用于键值对,但如果您在一个“集合”中有多个 dd 则会出现问题,例如:
<dt>Key1</dt>
<dd>Val1.1</dd>
<dd>Val1.2</dd>
<dt>Key2</dt>
<dd>Val2.1</dd>
<dd>Val2.2</dd>
然而,抛开边框样式的限制不谈,使用 CSS 可以做任何其他事情来关联集合(背景、编号等)。这里有一个很好的概述:http://www.maxdesign.com.au/articles/definition/
我认为值得注意的另一点是,如果您希望优化样式定义列表以提供视觉分离 - CSS 的自动编号功能(counter-increment
和 counter-reset
)可以派上用场:http://www.w3.org/TR/CSS2/generate.html#counters
【讨论】:
【参考方案8】:当然,您可以只使用HTML Custom elements。 (spec)它们是完全有效的 HTML5。
不幸的是,浏览器支持不是那么好,但我们在处理语义时很少关心浏览器支持这样的琐事。 :-)
你可以用这样一种方式来表示它:
像这样注册你的全新花式元素后:
var XKey = document.registerElement('x-key');
document.body.appendChild(new XKey());
你这样写标记:
<ul>
<li>
<x-key>Name</x-key>
Value
</li>
</ul>
HTML 自定义元素的唯一条件是它们需要一个破折号。当然,您现在可以发挥超强的创造力……如果您正在建造一个汽车零部件仓库,并提供零件清单和序列号:
<ul>
<li>
<auto-part>
<serial-number>AQ12345</serial-number>
<short-description>lorem ipsum dolor...</short-description>
<list-price>14</list-price>
</auto-part>
</li>
</ul>
你不能得到比这更多的语义!
但是,我有可能对semantic-shangri-la-la
(一个真实的地方)走得太远,可能会想把它缩小到更通用的东西:
<ul>
<li class='auto-part' data-serial-number="AQ12345">
<p class='short-description'>lorem ipsum dolor...</p>
<p class='list-price'>14</p>
</li>
</ul>
或者这个(如果我需要设置样式并直观地显示键)
<ul>
<li class='auto-part'>
<x-key>AQ12345<//x-key>
<p class='short-description'>lorem ipsum dolor...</p>
<p class='list-price'>14</p>
</li>
</ul>
【讨论】:
非常有趣。下次我需要配对时,我可能会考虑一下。【参考方案9】:嗯。 dt
/dd
听起来最适合这个,可以在视觉上抵消它们,尽管我同意这比桌子更难。
至于源代码的可读性,放在一行怎么样?
<dl>
<dt>Name</dt> <dd>Value</dd>
<dt>Name</dt> <dd>Value</dd>
</dl>
我同意这不是 100% 完美的,但您可以使用空格字符进行缩进:
<dl>
<dt>Property with a looooooooooong name</dt> <dd>Value</dd>
<dt>Property with a shrt name</dt> <dd>Value</dd>
</dl>
这可能是最好的方式。
【讨论】:
问题在于,根据规范,dt
可以有多个dd
,这可能是也可能不是所希望的。【参考方案10】:
除了<dl>
元素,您几乎总结了 HTML 的所有选项:有限的选项。
但是,您没有迷路,还有一个选择:使用可以翻译成 HTML 的标记语言。 Markdown 是一个很好的选择。
使用某些降价引擎提供的表格扩展,您可以编写如下代码:
| Table header 1 | Table header 2 |
-----------------------------------
| some key | some value |
| another key | another value |
这意味着您当然需要一个构建步骤来将 Markdown 转换为 HTML。
这样您可以获得有意义的标记(表格数据的表格)和可维护的代码。
【讨论】:
所以你最终又得到了一张桌子,但要到达那里需要做更多的工作。这似乎根本解决不了任何问题。【参考方案11】:在每对之间放置一个空行怎么样?
这不需要对长值进行特殊处理。
<dl>
<dt>Name</dt>
<dd>Value</dd>
<dt>Name</dt>
<dd>Value</dd>
<dt>Name</dt>
<dd>Value</dd>
</dl>
【讨论】:
空白字符在 HTML 中没有任何语义意义。 1 个空格或多个空格、回车符CR
、tab
和换行符LF
基本上都转换为空格。对于阅读代码的人来说,它可能更具视觉吸引力,但它没有赋予任何语义含义。【参考方案12】:
使用列表怎么样?
已订购:
<ol>
<li title="key" value="index">value</li>
…
</ol>
或者将<ul>
用于无序列表,并跳过value="index"
位。
【讨论】:
【参考方案13】:来自spec的线路:
名称-值组可以是术语和定义、元数据主题和值、问题和答案,或任何其他名称-值数据组。
我假设使用元素 <dl>
、<dt>
和 <dd>
。
【讨论】:
感谢您链接到规范。是的,规范确实允许名称-值对,但dl
元素在视觉上显示可能很麻烦,因为每个 key
/value
对都没有容器。它最初的用途可能是列出具有 1 个术语和多个定义的词汇表项目或字典条目。【参考方案14】:
我确实喜欢 Unicron 将它们全部放在一行的想法,但另一种选择是缩进定义名称下方的值:
<dl>
<dt>Name</dt>
<dd>Value</dd>
<dt>Name</dt>
<dd>Value</dd>
</dl>
这种方式在冗长的定义中可能会更容易一些(尽管如果您使用的定义非常错误,那么定义列表可能并不是您真正想要的)。
至于在屏幕上的渲染,加在 dd 上的粗底边距是足够的视觉分离。
【讨论】:
以上是关于名称-值对的语义和结构的主要内容,如果未能解决你的问题,请参考以下文章