名称-值对的语义和结构

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、问题?

编辑/更新 也许这是我应该明确提到的与结构有关的事情,但定义列表也存在没有对这些对进行语义分组的问题。 dddt 之间的顺序和隐含边界很容易理解,但我仍然觉得它们有点偏离。

【问题讨论】:

Re:您的编辑/更新 - 如果您想绝对确保节点之间的语义关系没有歧义,您总是可以变得非常冗长并执行
Name dt>
Value 1
Value 2 但有些人会称之为矫枉过正。 ;) 您还应该询问 CSS。例如。 &lt;dl&gt; 还不错,但很难设置内联显示对的样式(如表格中) 已经有很多好的答案,尤其是在代码方面,但我对几乎所有答案都有些犹豫。这只是因为每个解决方案都是一个让步。我将很快将当前答案之一标记为最适合此线程,但要知道这是一个艰难的决定。 @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 还有这样的事情:&lt;ul&gt; &lt;li&gt;&lt;div class="key"&gt;key&lt;/div&gt;&lt;div class="value"&gt;value&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; whit 我们可以有任意键和值(一个值可以是另一个列表、图像等) 另外,对于表格解决方案,也许您可​​以使用&lt;col class="key"/&gt; 标签。反正我觉得table的方案不好,如果能把key和value分在不同的行显示会怎样? 我相信(嗯,几乎知道&lt;strong&gt; 应该根据 HTML5 语义替换为 &lt;b&gt; 这个问题在谷歌中排名第一。您能否考虑更新您的答案以反映@Danny Lin 关于在dl 中使用divs 的意见?这解决了语义和样式的问题,从而避免了&lt;b&gt;&lt;strong&gt;的噪音:***.com/a/50313363/792888【参考方案2】:

按照 Alexandr Antonov 提供的specification(和further details):使用dldtdd,以及可选的div

dldtdd 的组合对于键值对来说在语义上很好:

<dl>
    <dt>Key1</dt>
    <dd>Value1</dd>
    <dt>Key2</dt>
    <dd>Value2</dd>
</dl>

为了更轻松地进行样式设置或解析,divs 可以用作 dl 的子代以对键值对进行分组(并使 dtdd 成为 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 &gt; lidl &gt; dt + dd 结合起来:

<ul>    
    <li>
        <dl>
            <dt>Name</dt>
            <dd>John</dd>
        </dl>
    </li>
    <li>
        <dl>
            <dt>Age</dt>
            <dd>25</dd>
        </dl>
    </li>
</ul>

【讨论】:

天哪。哇。我想要&lt;di&gt; 元素。我现在就想要。可惜我拿不到。不过,感谢您提供的信息! 根据规范,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一样,根本没有任何标签。其中一个跨度需要超过一个跨度。也许&lt;strong&gt;?那么第二个就不需要了。 在当前的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>

我使用&lt;dl&gt; &lt;dt&gt; &lt;dd&gt; 并用网格设置样式

【讨论】:

【参考方案6】:

这不是我喜欢的解决方案,但它是对语义元素的巧妙滥用:

为每个&lt;dt&gt;/&lt;dd&gt; 对使用一个新的&lt;dl&gt;

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

【讨论】:

有趣。如果不需要是相关项目的列表,这将起作用......尽管我想一个可以将每个 &lt;dl&gt; 封装在 &lt;li&gt;【参考方案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-incrementcounter-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】:

除了&lt;dl&gt; 元素,您几乎总结了 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 个空格或多个空格、回车符CRtab 和换行符LF 基本上都转换为空格。对于阅读代码的人来说,它可能更具视觉吸引力,但它没有赋予任何语义含义。【参考方案12】:

使用列表怎么样?

已订购:

<ol>
  <li title="key" value="index">value</li>
  …
</ol>

或者将&lt;ul&gt; 用于无序列表,并跳过value="index" 位。

【讨论】:

【参考方案13】:

来自spec的线路:

名称-值组可以是术语和定义、元数据主题和值、问题和答案,或任何其他名称-值数据组。

我假设使用元素 &lt;dl&gt;&lt;dt&gt;&lt;dd&gt;

【讨论】:

感谢您链接到规范。是的,规范确实允许名称-值对,但 dl 元素在视觉上显示可能很麻烦,因为每个 key/value 对都没有容器。它最初的用途可能是列出具有 1 个术语和多个定义的词汇表项目或字典条目。【参考方案14】:

我确实喜欢 Unicron 将它们全部放在一行的想法,但另一种选择是缩进定义名称下方的值:

<dl>
    <dt>Name</dt>
       <dd>Value</dd>
    <dt>Name</dt>
       <dd>Value</dd>
</dl>

这种方式在冗长的定义中可能会更容易一些(尽管如果您使用的定义非常错误,那么定义列表可能并不是您真正想要的)。

至于在屏幕上的渲染,加在 dd 上的粗底边距是足够的视觉分离。

【讨论】:

以上是关于名称-值对的语义和结构的主要内容,如果未能解决你的问题,请参考以下文章

自然和医学图像的深度语义分割:网络结构

html5语义化标签使用规范

语义化的HTML结构到底有啥好处

HTML语义化是啥意思?

潜在语义分析的介绍

说说语义化