Semántica y estructura de pares nombre-valor

77

Esta es una pregunta con la que he estado luchando durante un tiempo. ¿Cuál es la forma correcta de marcar pares de nombre / valor?

Me gusta el elemento <dl>, pero presenta un problema: no hay forma de separar un par de otro, no tienen un contenedor único. Visualmente, el código carece de definición. Semánticamente, sin embargo, creo que este es el marcado correcto.

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

En el código anterior, es difícil compensar correctamente los pares visualmente, tanto en código como renderizado. Si quisiera, por ejemplo, pero un borde alrededor de cada par, eso sería un problema.

Podemos señalar tablas. Se podría argumentar que los pares nombre-valor son datos tabulares. Eso me parece incorrecto, pero veo el argumento. Sin embargo, el HTML no diferencia el nombre del valor, excepto en la posición o con la adición de nombres de clases.

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

Esto tiene mucho más sentido desde un punto de vista visual, tanto en código como en CSS. Diseñar el borde antes mencionado es trivial. Sin embargo, como se mencionó anteriormente, la semántica es difusa en el mejor de los casos.

¿Pensamientos, comentarios, preguntas?

Editar / Actualizar Quizás esto era algo que debería haber mencionado explícitamente en relación con la estructura, pero una lista de definiciones también tiene el problema de no agrupar semánticamente los pares. El orden y la frontera implícita entre una ddy dtes fácil de entender, pero todavía se siente un poco fuera de mí.

Ryan Kinal
fuente
Re: su edición / actualización: si desea asegurarse absolutamente de que no hay ambigüedad sobre las relaciones semánticas entre los nodos, siempre puede ser realmente detallado y hacer <dt id = "key1"> Name </dt> <dd about = "# key1 "> Valor 1 </dd> <dd about =" # key1 "> Valor 2 </dd>, pero algunos lo llamarían exageración. ;)
lucideer
También debe preguntar sobre el CSS. Por ejemplo, <dl>sería no es tan malo, pero es difícil de estilo para mostrar los pares en línea (como en la tabla)
takeshin
Ha habido muchas buenas respuestas, especialmente en el lado del código, pero todavía dudo un poco acerca de casi todas. Esto se debe solo a que cada solución es un toma y daca. Pronto marcaré una de las respuestas actuales como la mejor para este hilo, pero sepa que es una decisión difícil.
Ryan Kinal
¡El de @ Danny Lin fue el indicado! Semántica y estilo con facilidad gracias a la especificación mejorada. stackoverflow.com/a/50313363/792888
EvilDr

Respuestas:

57

Gracias por esta interesante pregunta. Hay algunas cosas más a considerar aquí.

¿Qué es un par? Dos elementos juntos. Entonces necesitamos una etiqueta para esto. Digamos que es pairetiqueta.

 <pair></pair>

El par contiene la clave y el valor correspondiente:

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

Luego, necesitamos enumerar los pares:

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

Lo siguiente a considerar es la visualización de los pares. El diseño habitual es el tabular:

key value
key value

y el separador opcional, que suele ser dos puntos:

key : value
key : value

Los dos puntos se pueden agregar fácilmente a través de CSS, pero esto ciertamente no funcionará en IE.

El caso descrito anteriormente es el ideal. Pero no hay un marcado HTML válido que se ajuste fácilmente a esto.


Para resumir:

dles semánticamente más cercano, para casos simples de clave y valor, pero es difícil aplicar estilos visuales (por ejemplo, para mostrar los pares en línea o para agregar un borde rojo a un par solo suspendido). El caso que más se adapta dles el glosario. Pero este no es el caso que discutimos.

La única alternativa que puedo ver en este caso es usar table, así:

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

Uno mas:

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

o:

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

o, cuando las claves pueden estar vinculadas:

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

Los pares de clave y valor generalmente se almacenan en la base de datos, y esos generalmente almacenan datos tabulares, por lo que la tabla encajaría mejor en mi humilde opinión.

¿Qué piensas?

tomando
fuente
4
Respuesta muy completa. Me gusta cómo mostraste tu línea de pensamiento. +1
Ryan Kinal
y algo como esto: <ul> <li><div class="key">key</div><div class="value">value</div></li> </ul>con que podemos tener claves y valores arbitrarios (un valor podría ser otra lista, una imagen, etc.)
Enrique
Además, para la solución de tabla, tal vez pueda usar la <col class="key"/>etiqueta. De todos modos, creo que la solución de la tabla no es buena, ¿qué pasa si podemos mostrar la clave y el valor en diferentes líneas?
Enrique
2
Creo (bueno, casi lo ) <strong>debería ser reemplazado por de <b>acuerdo con la semántica de HTML5.
Andreas Rejbrand
1
Esta pregunta es la mejor en Google. ¿Podría considerar actualizar su respuesta para reflejar la entrada de @Danny Lin con respecto al uso de divs dentro dl? Esto resuelve el problema de la semántica y el estilo, evitando así el ruido de <b>y <strong>: stackoverflow.com/a/50313363/792888
EvilDr
21

Siguiendo la especificación (y más detalles ) proporcionado por Alexandr Antonov: uso dl, dt, dd, y opcionalmentediv .

Una combinación de dl, dty ddes semánticamente correcta para pares clave-valor:

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

Para facilitar el diseño o el análisis, divse pueden usar s como hijos de dlpara agrupar los pares clave-valor (y marcas dty ddnietos de 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>

Danny Lin
fuente
Excelente respuesta, y en mi humilde opinión debería aceptarse la respuesta, especialmente dado el ejemplo incluido en la especificación que se ajusta perfectamente a esta pregunta. CSS Grid también sería una forma bastante sorprendente de formatear esto de manera simple y efectiva.
EvilDr
12

XHTML 2 introduce la capacidad de agrupar términos y definiciones utilizando el dielemento

<!-- 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> Mejora en las listas de definiciones

Desafortunadamente, sin embargo, XHTML 2 está muerto y HTML5 no tiene di elementos

Entonces, puedes combinar ul > licon 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>
Yukulélé
fuente
7
Oh hombre. Guau. Quiero el <di>elemento. Lo quiero ahora. Lástima que no pueda tenerlo. ¡Gracias por la informacion sin embargo!
Ryan Kinal
2
Según especificaciones, divasume el papel de di. Vea mi respuesta para más detalles.
Danny Lin
6

Creo que una lista de definiciones probablemente sea una mala idea. Semánticamente, se utilizan para las definiciones. Otras listas de valores-clave a menudo difieren de los títulos y descripciones de las definiciones.

A tablees una forma de hacerlo, pero ¿qué pasa con una lista desordenada?

<ul>
    <li class="key-value-pair">
        <span class="key">foo</span>
        <span class="value">bar</span>
    </li>
</ul>
gpmcadam
fuente
2
Las listas de definiciones pueden estar un poco mal nombradas a este respecto, pero no están destinadas exclusivamente a las definiciones (serían de un caso de uso bastante limitado si lo fueran): la especificación W3C. que los define en realidad tiene un ejemplo de su uso para marcar un diálogo.
Lucideer
Pensando en ello desde un punto de vista orientado a objetos, supongo que lo que estoy buscando es "una lista desordenada de pares nombre-valor", pero no estoy seguro de que esta sea la mejor respuesta (por ahora). +1
Ryan Kinal
1
Esta es una especie de enfoque de microformato, pero en la representación del navegador o el lector de pantalla predeterminados, obtendrá foo bar, como foo barsin ninguna etiqueta. Uno de los tramos debe tener más de un tramo. <strong>¿ Quizás ? Entonces el segundo no es necesario.
toma el
3
En la especificación actual de HTML5 , dl ha sido renombrado como una lista de descripción que hace que su uso aquí parezca más correcto.
Eric Bock
3

Esta no es mi solución preferida, pero es un abuso inteligente del elemento semántico:

Utilice un nuevo <dl>por <dt>/ <dd>par:

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

Un ejemplo con CSS flotantes y borde rojo al pasar el mouse:

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>

Iiridayn
fuente
Interesante. Esto funcionaría si no es necesario que sea una lista de elementos relacionados ... aunque supongo que uno PODRÍA encapsular cada uno <dl>en un<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>

Los usé <dl> <dt> <dd>y los diseñé con cuadrícula.

Michiel Bruggenwirth
fuente
2

es difícil compensar correctamente los pares visualmente, tanto en código como renderizado. Si quisiera, por ejemplo, pero un borde alrededor de cada par, eso sería un problema.

Otros antes que yo se han ocupado (creo que bastante bien) del problema de proporcionar una definición visual en el código. Lo que deja el problema del renderizado y CSS. Esto se puede hacer con bastante eficacia en la mayoría de los casos. La mayor excepción es colocar un borde alrededor de cada conjunto de dt / dds, lo que ciertamente es extremadamente complicado, quizás imposible de diseñar de manera confiable.

Podrías hacerlo:

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

Lo que funciona para PARES de valor-clave, pero presenta problemas si tiene varios dds dentro de un "conjunto" como:

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

Sin embargo, dejando a un lado las limitaciones de estilo de los bordes, hacer cualquier otra cosa para asociar conjuntos (fondos, numeración, etc.) es bastante posible con CSS. Aquí hay una buena descripción general: http://www.maxdesign.com.au/articles/definition/


Otro punto que creo que vale la pena señalar, si está buscando un estilo óptimo de listas de definiciones para proporcionar separación visual, las funciones de numeración automática de CSS ( counter-incrementy counter-reset) pueden ser bastante útiles: http://www.w3.org/TR/ CSS2 / generate.html # contadores

lucideer
fuente
2

Por supuesto, puede usar elementos HTML personalizados . ( especificación ) Son HTML5 completamente válidos.

Desafortunadamente, la compatibilidad con el navegador no es tan buena, pero si rara vez nos preocupamos por aspectos tan sencillos como la compatibilidad con el navegador cuando se trata de semántica. :-)

De una manera que podrías representarlo:

Después de registrar su nuevo elemento de fantasía así:

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

Escribe el marcado así:

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

La única condición que tienen los elementos HTML personalizados es que necesitan un guión en ellos. Por supuesto, ahora puede ser súper creativo ... si está construyendo un almacén de repuestos para automóviles, con listas de repuestos y números de serie:

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

¡No puedes ser mucho más semántico que eso!

Sin embargo, existe la posibilidad de que haya ido demasiado lejos semantic-shangri-la-la(un lugar real) y podría sentir la tentación de escalarlo a algo un poco más genérico:

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

O quizás esto (si tuviera que peinar y mostrar la clave visualmente)

<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>
Armstrongest
fuente
Muy interesante. Puedo investigar esto la próxima vez que necesite pares.
Ryan Kinal
1

Hmm. dt/ ddsuena mejor para esto y es posible compensarlos visualmente, aunque estoy de acuerdo en que es más difícil que para una mesa.

En cuanto a la legibilidad del código fuente, ¿qué tal si lo ponemos en una línea?

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

Estoy de acuerdo en que no es 100% perfecto, pero ya que puedes usar espacios para la sangría:

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

podría ser la forma más agradable.

Unicron
fuente
El problema es que bajo la especificación, un dtpuede tener más de uno ddque puede ser o no lo que se desea.
Armstrongest
1

Excepto por el <dl> elemento, ha resumido prácticamente todas las opciones de HTML: limitadas.

Sin embargo, no está perdido, queda una opción: usar un lenguaje de marcado que se pueda traducir a HTML. Una muy buena opción es Markdown.

Con una extensión de tabla que proporcionan algunos motores de rebajas, puede tener un código como este:

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

Esto significa que, por supuesto, necesita un paso de compilación para traducir Markdown a HTML.

De esta manera, obtiene un marcado significativo (tabla para datos tabulares) y código mantenible.

Florian Margaine
fuente
1
Entonces terminas con una mesa nuevamente, pero es más trabajo llegar allí. Esto no parece que resuelva ningún problema en absoluto.
pydsigner
0

¿Qué tal si colocas una línea en blanco entre cada par?

Esto no requiere un manejo especial para valores largos.

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

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

    <dt>Name</dt> 
    <dd>Value</dd> 
</dl> 
Philip Smith
fuente
Los caracteres de espacio en blanco no tienen ningún significado semántico en HTML. 1 plaza o múltiples espacios, retornos de carro CR, taby saltos de línea LFesencialmente todo se traducen en un espacio. Quizás sea más atractivo visualmente para un humano que lee el código, pero no imparte ningún significado semántico.
Armstrongest
0

¿Qué pasa con el uso de listas?

Ordenado:

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

O utilícelo <ul>para una lista desordenada y omita el value="index"bit.

Dave Sag
fuente
0

La línea de la especificación :

Los grupos de nombre-valor pueden ser términos y definiciones, temas y valores de metadatos, preguntas y respuestas, o cualquier otro grupo de datos de nombre-valor .

Asumo uso de elementos <dl>, <dt>y <dd>.

Alexandr Antonov
fuente
2
Gracias por vincular a la especificación. Sí, la especificación permite pares de nombre-valor, pero el dlelemento puede ser difícil de mostrar visualmente, ya que no hay un contenedor para cada key/ valuepar. Su uso original fue probablemente para enumerar elementos del glosario o entradas de diccionario, que tienen 1 término y múltiples definiciones.
Armstrongest
-1

Me gusta la idea de Unicron de ponerlos todos en una línea, pero otra opción sería sangrar el valor debajo del nombre de la definición:

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

De esta manera puede ser un poco más agradable a la vista en definiciones ridículamente largas (aunque si estás usando definiciones ridículamente incorrectas, quizás una lista de definiciones no sea lo que realmente quieres después de todo).

En cuanto a la representación en pantalla, un margen inferior grueso aplicado al dd es una gran separación visual.

hollsk
fuente