Ngữ nghĩa và cấu trúc của các cặp tên-giá trị


77

Đây là một câu hỏi mà tôi đã trăn trở trong một thời gian. Cách thích hợp để đánh dấu các cặp tên / giá trị là gì?

Tôi thích phần tử <dl>, nhưng nó đưa ra một vấn đề: Không có cách nào để tách một cặp này khỏi một cặp khác - chúng không có vùng chứa duy nhất. Về mặt trực quan, mã thiếu định nghĩa. Tuy nhiên, về mặt ngữ nghĩa, tôi nghĩ đây là cách đánh dấu chính xác.

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

Trong đoạn mã trên, rất khó để bù đắp các cặp một cách trực quan một cách chính xác, cả trong mã và kết xuất. Ví dụ, nếu tôi muốn, nhưng có một đường viền xung quanh mỗi cặp, đó sẽ là một vấn đề.

Chúng tôi có thể chỉ vào các bảng. Có thể lập luận rằng các cặp tên-giá trị là dữ liệu dạng bảng. Điều đó có vẻ không chính xác đối với tôi, nhưng tôi thấy lý lẽ. Tuy nhiên, HTML không phân biệt tên với giá trị, ngoại trừ vị trí hoặc với việc bổ sung tên lớp.

<table>
    <tr>
        <td>Name</td>
        <td>Value</td>
    </tr>
    <tr>
        <td>Name</td>
        <td>Value</td>
    </tr>
</table>

Điều này có ý nghĩa hơn nhiều từ quan điểm trực quan, cả về mã và CSS. Việc tạo kiểu cho đường viền nói trên là tầm thường. Tuy nhiên, như đã đề cập ở trên, ngữ nghĩa tốt nhất là mờ.

Suy nghĩ, bình luận, câu hỏi?

Chỉnh sửa / Cập nhật Có lẽ đây là điều tôi nên đề cập rõ ràng liên quan đến cấu trúc, nhưng một danh sách định nghĩa cũng có vấn đề là không nhóm các cặp về mặt ngữ nghĩa. Có thể dễ dàng hiểu được thứ tự và biên giới ngầm giữa a ddvà a dt, nhưng tôi vẫn cảm thấy họ hơi khó chịu.


Re: bản chỉnh sửa / cập nhật của bạn - nếu bạn muốn đảm bảo hoàn toàn không có sự mơ hồ về mối quan hệ ngữ nghĩa giữa các nút, bạn luôn có thể hiểu chi tiết và thực hiện <dt id = "key1"> Tên </dt> <dd about = "# key1 "> Giá trị 1 </dd> <dd about =" # key1 "> Giá trị 2 </dd> nhưng một số sẽ gọi đó là mức quá mức cần thiết. ;)
lucideer

Bạn cũng nên hỏi về CSS. Ví dụ như <dl>sẽ không đến nỗi tệ, nhưng rất khó để phong cách để hiển thị các cặp inline (như trong bảng)
takeshin

Đã có rất nhiều câu trả lời hay, đặc biệt là về mặt mã, nhưng tôi vẫn hơi do dự về gần như tất cả chúng. Điều này chỉ là vì mọi giải pháp đều là cho và nhận. Tôi sẽ sớm đánh dấu một trong những câu trả lời hiện tại là tốt nhất cho chủ đề này, nhưng biết rằng đó là một quyết định khó khăn.
Ryan Kinal,

@Danny Lin là một trong những! Ngữ nghĩa và phong cách dễ dàng nhờ thông số kỹ thuật được cải thiện! stackoverflow.com/a/50313363/792888
EvilDr

Câu trả lời:


57

Cảm ơn vì câu hỏi thú vị này. Có vài điều nữa cần xem xét ở đây.

Cặp là gì? Hai yếu tố với nhau. Vì vậy, chúng tôi cần một thẻ cho điều này. Giả sử nó là pairthẻ.

 <pair></pair>

Cặp chứa khóa và giá trị tương ứng:

 <pair><key>keyname</key><value>value</value></pair>

Sau đó, chúng ta cần liệt kê các cặp:

<pairlist>
     <pair><key>keyname</key><value>value</value></pair>
     <pair><key>keyname</key><value>value</value></pair>
</pairlist>

Điều tiếp theo cần xem xét, là hiển thị của các cặp. Bố cục thông thường là dạng bảng:

key value
key value

và dấu phân tách tùy chọn, thường là dấu hai chấm:

key : value
key : value

Dấu hai chấm có thể được thêm dễ dàng thông qua CSS, nhưng điều này chắc chắn sẽ không hoạt động trong IE.

Trường hợp được mô tả ở trên là một trong những lý tưởng. Nhưng không có mã đánh dấu HTML hợp lệ nào để dễ dàng phù hợp với điều này.


Tóm lại:

dllà gần nhất về mặt ngữ nghĩa, đối với các trường hợp đơn giản của khóa và giá trị, nhưng khó áp dụng các kiểu trực quan (ví dụ: để hiển thị các cặp trong dòng hoặc để thêm đường viền đỏ cho chỉ cặp được di chuột qua). Trường hợp phù hợp nhất chodl là bảng thuật ngữ. Nhưng đây không phải là trường hợp chúng ta thảo luận.

Cách thay thế duy nhất tôi có thể thấy trong trường hợp này là sử dụng table, như sau:

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

Một lần nữa:

<ul>
  <li><strong>key</strong> value</li>
  <li><strong>key</strong> value</li>
</ul>

hoặc là:

<ul>
  <li><b>key</b> value</li>
  <li><b>key</b> value</li>
</ul>

hoặc, khi các khóa có thể được liên kết:

<ul>
  <li><a href="/key1">key1</a> value</li>
  <li><a href="/key2">key1</a> value</li>
</ul>

Các cặp khóa và giá trị thường được lưu trữ trong cơ sở dữ liệu và chúng thường lưu trữ dữ liệu dạng bảng, vì vậy bảng sẽ phù hợp nhất với IMHO.

Bạn nghĩ sao?


4
Câu trả lời rất tường tận. Tôi thích cách bạn thể hiện dòng suy nghĩ của mình. +1
Ryan Kinal

và những gì về một cái gì đó như thế này: <ul> <li><div class="key">key</div><div class="value">value</div></li> </ul>whit rằng chúng ta có thể có các phím tùy ý và giá trị (giá trị có thể là một danh sách khác, một hình ảnh, vv)
Enrique

ngoài ra, đối với giải pháp bảng có thể bạn có thể sử dụng <col class="key"/>thẻ. Dù sao, tôi nghĩ rằng giải pháp bảng là không tốt, điều gì sẽ xảy ra nếu chúng ta có thể hiển thị khóa và giá trị trong các dòng khác nhau?
Enrique

2
Tôi tin rằng (tốt, gần như biết ) <strong>nên được thay thế bằng <b>theo ngữ nghĩa HTML5.
Andreas Rejbrand,

1
Câu hỏi này đứng đầu trong Google. Bạn có thể vui lòng xem xét cập nhật câu trả lời của mình để phản ánh ý kiến ​​của @Danny Lin về việc sử dụng divs trong dlkhông? Điều này giải quyết vấn đề về ngữ nghĩa và kiểu dáng, do đó tránh được tiếng ồn của <b><strong>: stackoverflow.com/a/50313363/792888
EvilDr

21

Sau khi đặc điểm kỹ thuật (và biết thêm chi tiết ) được cung cấp bởi Alexandr Antonov: sử dụng dl, dt, dd,, và tùy chọndiv .

Sự kết hợp của dl, dtddtốt về mặt ngữ nghĩa cho các cặp khóa-giá trị:

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

Để tạo kiểu hoặc phân tích cú pháp dễ dàng hơn, divs có thể được sử dụng như là con của dlđể nhóm các cặp khóa-giá trị (và tạo dtddtrở thành cháu của 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>


Câu trả lời xuất sắc và IMHO nên được chấp nhận câu trả lời, đặc biệt là với ví dụ có trong thông số kỹ thuật hoàn toàn phù hợp với câu hỏi này. CSS Grid cũng sẽ là một cách khá tuyệt vời để định dạng nó một cách đơn giản và hiệu quả.
EvilDr

12

XHTML 2 giới thiệu khả năng nhóm các thuật ngữ và định nghĩa bằng cách sử dụng diphần tử

<!-- 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 so với XHTML 2> Cải tiến cho danh sách định nghĩa

Tuy nhiên, thật không may, XHTML 2 đã chết và HTML5 không có diphần tử

Vì vậy, bạn có thể kết hợp ul > livới 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>

7
Trời ơi. Chà. Tôi muốn <di>phần tử. Tôi muốn nó ngay bây giờ. Thật tệ là tôi không thể có nó. Cảm ơn thông tin mặc dù!
Ryan Kinal

2
Theo thông số kỹ thuật, divcó vai trò của di. Xem câu trả lời của tôi để biết chi tiết.
Danny Lin

6

Tôi nghĩ rằng một danh sách định nghĩa có lẽ là một ý tưởng tồi. Về mặt ngữ nghĩa, chúng được dùng để định nghĩa. Các danh sách khóa-giá trị khác thường sẽ khác với tiêu đề định nghĩa và mô tả.

A tablelà một cách để đi, nhưng còn một danh sách không có thứ tự thì sao?

<ul>
    <li class="key-value-pair">
        <span class="key">foo</span>
        <span class="value">bar</span>
    </li>
</ul>

2
Danh sách định nghĩa có thể được đặt tên hơi kém về mặt này, nhưng chúng không hoàn toàn dành cho các định nghĩa (nếu có thì chúng sẽ thuộc trường hợp sử dụng khá hạn chế) - thông số kỹ thuật W3C. xác định chúng thực sự có một ví dụ về việc sử dụng chúng để đánh dấu một cuộc đối thoại.
lucideer

Suy nghĩ về nó từ quan điểm hướng đối tượng, tôi cho rằng những gì tôi đang tìm kiếm là "danh sách không có thứ tự các cặp tên-giá trị", nhưng tôi không chắc đây là câu trả lời tốt nhất (hiện tại). +1
Ryan Kinal

1
Đây là loại phương pháp tiếp cận vi định dạng, nhưng trong hiển thị trình duyệt hoặc trình đọc màn hình mặc định, bạn sẽ nhận được foo bar, giống như foo barkhông có bất kỳ thẻ nào cả. Một trong các nhịp cần phải lớn hơn một nhịp. Có thể <strong>? Sau đó, cái thứ hai là không cần thiết.
takehin vào

3
Trong thông số kỹ thuật HTML5 hiện tại , dl đã được đổi tên thành danh sách mô tả khiến việc sử dụng nó ở đây có vẻ đúng hơn.
Eric Bock

3

Đây không phải là giải pháp ưa thích của tôi, nhưng đó là một sự lạm dụng thông minh của yếu tố ngữ nghĩa:

Sử dụng <dl>mỗi <dt>/ <dd>cặp mới:

<div class="terms">
    <dl><dt>Name 1</dt><dd>Value 1</dd></dl>
    <dl><dt>Name 2</dt><dd>Value 2</dd></dl>
</div>

Một ví dụ với css float và viền đỏ khi di chuột:

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>


Hấp dẫn. Điều này sẽ hoạt động nếu nó không cần phải là một danh sách các mục có liên quan ... mặc dù tôi cho rằng một cái CÓ THỂ gói gọn từng mục <dl>trong một<li>
Armstrongest

3

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>

Tôi đã sử dụng <dl> <dt> <dd>và tạo kiểu cho chúng bằng lưới


2

rất khó để bù đắp các cặp một cách trực quan, cả trong mã và hiển thị. Ví dụ, nếu tôi muốn, nhưng có một đường viền xung quanh mỗi cặp, đó sẽ là một vấn đề.

Những người khác trước tôi đã giải quyết (tôi nghĩ khá tốt) với vấn đề cung cấp định nghĩa trực quan trong mã. Điều này để lại vấn đề về kết xuất và CSS. Điều này có thể được thực hiện khá hiệu quả trong hầu hết các trường hợp. Ngoại lệ lớn nhất là đặt một đường viền xung quanh mỗi tập hợp dt / dds, điều này được thừa nhận là cực kỳ phức tạp - có lẽ không thể tạo kiểu một cách đáng tin cậy.

Bạn có thể làm:

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:'→ '; }

Tính năng này hoạt động với CẶP khóa giá trị, nhưng gây ra vấn đề nếu bạn có nhiều dds trong một "bộ" như:

<dt>Key1</dt>
  <dd>Val1.1</dd>
  <dd>Val1.2</dd>
<dt>Key2</dt>
  <dd>Val2.1</dd>
  <dd>Val2.2</dd>

Tuy nhiên, hạn chế về kiểu đường viền sang một bên, bạn hoàn toàn có thể làm bất cứ điều gì khác để liên kết các tập hợp (nền, đánh số, v.v.) với CSS. Có một cái nhìn tổng quan đẹp ở đây: http://www.maxdesign.com.au/articles/definition/


Một điểm khác mà tôi nghĩ là đáng chú ý, nếu bạn đang tìm cách tối ưu hóa kiểu danh sách định nghĩa để cung cấp sự phân tách trực quan - các tính năng đánh số tự động của CSS ( counter-incrementcounter-reset) có thể khá hữu ích: http://www.w3.org/TR/ CSS2 / create.html # counters


2

Tất nhiên, bạn chỉ có thể sử dụng các phần tử Tùy chỉnh HTML . ( thông số kỹ thuật ) Chúng hoàn toàn là HTML5 hợp lệ.

Thật không may, hỗ trợ trình duyệt không phải là tuyệt vời, nhưng nếu hiếm khi chúng tôi quan tâm đến những thứ dành cho người đi bộ như hỗ trợ trình duyệt khi chúng tôi xử lý ngữ nghĩa. :-)

Một trong những cách như vậy bạn có thể thể hiện nó:

Sau khi đăng ký phần tử ưa thích hoàn toàn mới của bạn như vậy:

var XKey = document.registerElement('x-key');
document.body.appendChild(new XKey());

Bạn viết đánh dấu như vậy:

<ul>
  <li>
    <x-key>Name</x-key>
    Value
  </li>
</ul>

Điều kiện duy nhất mà các phần tử Tùy chỉnh HTML có là chúng cần có một dấu gạch ngang trong đó. Tất nhiên, bây giờ bạn có thể siêu sáng tạo ... nếu bạn đang xây dựng một kho phụ tùng ô tô, với danh sách các bộ phận và số sê-ri:

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

Bạn không thể hiểu nhiều ngữ nghĩa hơn thế!

Tuy nhiên, có khả năng là tôi đã đi quá xa semantic-shangri-la-la(một địa điểm thực) và có thể bị cám dỗ để quy mô nó trở lại một cái gì đó chung chung hơn một chút:

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

Hoặc có lẽ điều này (nếu tôi cần tạo kiểu và hiển thị chìa khóa một cách trực quan)

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

Rất thú vị. Tôi có thể xem xét điều này vào lần tới khi tôi đang cần cặp.
Ryan Kinal

1

Hừ! dt/ ddâm thanh tốt nhất cho điều này và nó tốt để bù đắp cho họ bằng mắt, mặc dù tôi không đồng ý đó là khó khăn hơn cho một bảng.

Đối với khả năng đọc mã nguồn, làm thế nào về việc đặt chúng thành một dòng?

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

Tôi đồng ý rằng nó không hoàn hảo 100%, nhưng bạn có thể sử dụng ký tự khoảng trắng để thụt lề:

<dl>
    <dt>Property with a looooooooooong name</dt>   <dd>Value</dd>
    <dt>Property with a shrt name</dt>             <dd>Value</dd>
</dl>

nó có thể là cách tốt nhất.


Vấn đề là theo thông số kỹ thuật, một dtcó thể có nhiều hơn một ddcó thể có hoặc có thể không phải là điều mong muốn.
Armstrong nhất

1

Ngoại trừ <dl> phần tử, bạn đã tổng hợp khá nhiều tùy chọn của HTML: tùy chọn giới hạn.

Tuy nhiên, bạn không bị mất, vẫn còn một tùy chọn: sử dụng ngôn ngữ đánh dấu có thể được dịch sang HTML. Một lựa chọn rất tốt là Markdown.

Sử dụng tiện ích mở rộng bảng mà một số công cụ đánh dấu cung cấp, bạn có thể có mã như sau:

| Table header 1 | Table header 2 |
-----------------------------------
| some key       | some value     |
| another key    | another value  |

Điều này có nghĩa là bạn cần một bước xây dựng để dịch Markdown sang HTML.

Bằng cách này, bạn nhận được đánh dấu có ý nghĩa (bảng cho dữ liệu dạng bảng) và mã có thể bảo trì.


1
Vì vậy, bạn lại kết thúc với một chiếc bàn, nhưng việc đến đó còn nhiều việc hơn. Điều này có vẻ như nó không giải quyết được bất kỳ vấn đề nào cả.
pydsigner,

0

Làm thế nào về việc chỉ cần đặt một dòng trống giữa mỗi cặp?

Điều này không yêu cầu xử lý đặc biệt cho các giá trị dài.

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

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

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

Các ký tự khoảng trắng không có bất kỳ ý nghĩa ngữ nghĩa nào trong HTML. 1 không gian hoặc nhiều khoảng trống, xuống dòng CR, tabvà line feed LFvề cơ bản tất cả các dịch đến một không gian. Nó có lẽ hấp dẫn về mặt thị giác hơn đối với con người khi đọc mã, nhưng nó không truyền đạt bất kỳ ý nghĩa ngữ nghĩa nào.
Armstrongest

0

Điều gì về việc sử dụng danh sách?

Đã đặt hàng:

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

Hoặc sử dụng <ul>cho danh sách không có thứ tự và bỏ qua value="index"bit.


0

Dòng từ spec :

Nhóm giá trị tên có thể là thuật ngữ và định nghĩa, chủ đề và giá trị siêu dữ liệu, câu hỏi và câu trả lời hoặc bất kỳ nhóm dữ liệu giá trị tên nào khác .

Tôi giả sử sử dụng các phần tử <dl>, <dt><dd>.


2
Cảm ơn bạn đã liên kết đến thông số kỹ thuật. Có, thông số kỹ thuật cho phép các cặp tên-giá trị, nhưng dlphần tử có thể gây rắc rối khi hiển thị trực quan, vì không có vùng chứa cho mỗi key/ valuecặp. Việc sử dụng ban đầu của nó có thể là để liệt kê các mục chú giải hoặc mục từ điển, có 1 thuật ngữ và nhiều định nghĩa.
Amstrong nhất

-1

Tôi thích ý tưởng của Unicron về việc đặt tất cả chúng trên một dòng, nhưng một tùy chọn khác sẽ là thụt lề giá trị bên dưới tên định nghĩa:

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

Cách này có thể dễ dàng hơn một chút đối với các định nghĩa dài đến mức nực cười (mặc dù nếu bạn đang sử dụng các định nghĩa sai một cách vô lý thì có lẽ sau cùng thì danh sách định nghĩa không phải là thứ bạn thực sự muốn).

Đối với việc hiển thị trên màn hình, lề dưới béo được áp dụng cho dd là rất nhiều sự phân tách trực quan.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.