Вопрос по wcag, html, css, html-table, wcag2.0 – Объединение таблицы и иерархического списка в HTML

19

работаю над редизайном устаревшего набора инструментов, и яЯ смотрю на то, как лучше отображать некоторую информацию как в презентационном, так и в семантическом виде.

Данные иерархически по своей природе, но имеют свойства, которые должны быть легко видны пользователям. Желаемый макет похож на ниже.

Seq     Item Name         Min  Max  - Anything under here isn't shown
 1      Identifier         1    1     (Required)
 2      Name               1    1
  2.1    First Name        1    1
  2.2    Middle Name       -    -     (Optional but unlimted)
  2.3    Last Name         1    1
 3      Age                -    1     (Optional)

На данный момент это одна целая таблица, и отступ для последовательности (Seq) число достигается путем вставки дополнительных ячеек таблицы, чтобы отразить все вправо.

Задача, которую я имею, состоит в том, чтобы выяснить, как эффективно отображать эту информацию.

Прежде всего это табличные данные? Я бы сказал нет, так как иерархия важна, аколонны просто атрибуты элемента в каждомстрока'.

Если это не такt tabular, что это такое и как это можно сделать? Я бы лично утверждал, что это набор вложенныхUL списки - порядковый номер не является обязательным и не всегда является числом. Если это набор списков, это будет правильно делать отступы для списков, но каков наилучший способ представления коротких атрибутов?

Если это таблица, как лучше представить семантическое существование иерархии в таблице?

Я не'не знаю, чтоне так со столом. Я думаю этоЯВЛЯЕТСЯ табличные данные, потому что они поступают в строках и столбцах. Это не меняется по иерархии yunzen
Ограничена ли иерархия вашей реальной информации двумя уровнями (как в вашем примере)? Zero Piraeus
@ ZeroPiraeus Нет, это произвольная глубина, но на практике, вероятно, не более 5-8. user764357

Ваш Ответ

7   ответов
20

что информация, которую вы хотите представить, в одном отношении является табличной (s набор элементов, которые имеют идентично помеченные атрибуты), и в другой иерархической структуре (элементы имеют родителей).

К сожалениюНет механизма вложенной группировки строк таблицы в HTML:tbody может использоваться для группировки строк, но вложение это недопустимо (за исключением промежуточногоtable внутриtdчто довольно ужасно).

Это оставляет вам два варианта:

Представьте информацию с помощью вложенных списков какого-либо рода и используйте CSS, чтобы результат выглядел как таблица.

Представлять информацию в виде таблицы и полагаться на какие-либо атрибуты для представления ее иерархических отношений.

Вот несколько примеров того, как вы могли бы реализовать этот выбор:

Использование вложенных списковмы подходим)


  
    
      Seq 1
      Item Name Identifier
      Min 1
      Max 1
    
  
  
    
      Seq 2
      Item Name Name
      Min 1
      Max 1
    
    
      
        
          Seq 2.1
          Item Name First Name
          Min 1
          Max 1
        
      
      
        
          Seq 2.2
          Item Name Middle Name
          Min -
          Max -
        
      
      
        
          Seq 2.3
          Item Name Last Name
          Min 1
          Max 1
        
      
    
  
  
    
      Seq 3
      Item Name Age
      Min -
      Max 1
    
  

Это обрабатывает иерархический аспект информации, но в конечном итоге вы многократно повторяете себя, и вам придется перепрыгивать через некоторые циклы в CSS, чтобы отобразить результат в табличной форме. Это'вероятно, выполнимо при разумном использовании:first-child, но в результате выВы сделали все возможное, чтобы пометить что-то, что вы хотите представить в виде таблицы не в табличной форме, и, как результат, дали себе больше работы по приведению его в форму.

Это также делает действительно табличный характер отношений между элементами неявным, а не явным в разметке - без ссылки на визуализированный вывод, это не 'Ясно, что эти предметы всегда будут иметь одинаковое количество и вид атрибутов.

Использование вложенных списков ("умная" подход):

<dl>
  <dt>
    <ul> <li>Seq</li> <li>Item Name</li> <li>Min</li> <li>Max</li> </ul>
  </dt>
  <dd>
    <ul> <li>1</li> <li>Identifier</li> <li>1</li> <li>1</li> </ul>
  </dd>
  <dd>
    <dl>
      <dt>
        <ul> <li>2</li> <li>Name</li> <li>1</li> <li>1</li> </ul>
      </dt>
      <dd>
        <ul> <li>2.1</li> <li>First Name</li> <li>1</li> <li>1</li> </ul>
      </dd>
      <dd>
        <ul> <li>2.2</li> <li>Middle Name</li> <li>-</li> <li>-</li> </ul>
      </dd>
      <dd>
        <ul> <li>2.3</li> <li>Last Name</li> <li>1</li> <li>1</li> </ul>
      </dd>
    </dl>
  </dd>
  <dd>
    <ul> <li>3</li> <li>Age</li> <li>-</li> <li>1</li> </ul>
  </dd>
</dl>

Мы тут'повторное использованиесписки описания описать две вещи:

Отношение заголовок / подробность, например, между 'Имя элемента' а также 'Идентификатор' и т.п.

Родительско-дочерние отношения, например, между 'Название' блок иИмя' Блок.

Это'Это, конечно, более компактно, но, к сожалению, конкретные отношения между каждым заголовком и его элементами детализации в лучшем случае неявны, и без дополнительных стилей для визуальной организации информации в виде таблицы, это 'будет еще менее очевидным, когдана самом деле представлены.

Используя :table

<table>
  <thead>
    <tr>
      <th>Seq</th> <th>Item Name</th> <th>Min</th> <th>Max</th>
    </tr>
  </thead>
  <tbody>
    <tr id="100">
      <td>1 </td><th>Identifier</th> <td>1</td> <td>1</td>
    </tr>
    <tr id="200">
      <th>2</th> <th>Name</th> <td>1</td> <td>1</td>
    </tr>
    <tr id="210" data-parent="200" class="level-1">
      <th>2.1</th> <th>First Name</th> <td>1</td> <td>1</td>
    </tr>
    <tr id="220" data-parent="200" class="level-1">
      <th>2.2</th> <th>Middle Name</th> <td>-</td> <td>-</td>
    </tr>
    <tr id="230" data-parent="200" class="level-1">
      <th>2.3</th> <th>Last Name</th> <td>1</td> <td>1</td>
    </tr>
    <tr id="300">
      <th>3</th> <th>Age</th> <td>-</td> <td>1</td>
    </tr>
  </tbody>
</table>

Здесь родительские / дочерние отношения явно описываютсяdata-parent атрибут (который может быть доступен через JavaScript при необходимости), иclass=level-{n} Атрибут предоставляет хук, который может использоваться CSS:

.level-1 > th {
  padding-left: 1em;
}

В конечном итоге этоЭто вопрос личных предпочтений и удобства, но я думаю, что

 подход лучше просто потому, что он удовлетворяетэто выглядит разумно без CSS? " Эмпирическое правило намного лучше, чем любой из вышеперечисленных подходов.

Осторожно, атрибуты id не могут начинаться с цифры. Matt Sach
@MattSach Этобольше не правда в HTML5. Zero Piraeus
Ну, взорви меня пером, я понятия не имел, что изменилось. Спасибо! Matt Sach
Хороший ответ. Дляtable решение, нет лучше использоватьатрибут заголовков вместо того чтобы придумыватьdata-parent)?headers атрибут также читается программами чтения с экрана, но AFAIK он может применяться только к отдельным ячейкам (например,seq или жеitem name клетки), а не целые ряды. JohnCand
2

что вы должны использовать стол. Правда, иерархия важнее, но ее также можно отобразить, записав вручную первый столбец. Но атрибуты min, max и имя элемента не могли быть отображены в списке так же легко, как в таблице. Мое мнение: используйте таблицу и предоставьте колонку seq вручную!

2

чтобы сохранить вашу иерархическую структуру, а затем описательные списки для представления "колонны» для каждого ряда.

Например, список описания для первой строки может выглядеть примерно так:

<dl>
  <dt>Item Name</dt>
  <dd>Identifier</dd>
  <dt>Min</dt>
  <dd>1</dd>
  <dt>Max</dt>
  <dd>1</dd>
  <dt>Notes</dt>
  <dd>(Required)</dd>
</dl>

Вы должны будете использовать CSS, чтобы скрыть термины описания (так как вы нея не хочу, чтобы они отображались в каждой строке), и чтобы настроить макет так, чтобы он больше походил на таблицу.

Недостатком этого формата является то, что вы собираетесь дублировать заголовки столбцов в каждой строке. Но семантически я думаю, что это имеет смысл, и это также должно сделать содержание более значимым для программы чтения с экрана.

Мы впервые попробовали CSS, чтобы вы могли понять, как он может работать. Это, вероятно, не очень хорошо сделано, но по крайней мере этодам вам кое-что для начала.

CodePen Link

7

пользовательские атрибуты данных кtd теги:

<table id="myTable" class="table">
    <tbody><tr>
        <td data-indent="0">1</td>
        <td data-indent="0">Test</td>
        <td data-indent="0">Test 1</td>
    </tr>
    <tr>
        <td data-indent="1">1.1</td>
        <td data-indent="1">Another</td>
        <td data-indent="0">Test 1.1</td>
    </tr>
    <tr>
        <td data-indent="2">1.1.1</td>
        <td data-indent="3">Another</td>
        <td data-indent="0">Test 1.1.1</td>
    </tr>
        <tr>
        <td data-indent="2">1.1.2</td>
        <td data-indent="3">Another one</td>
        <td data-indent="0">Another test 1.1.2</td>
    </tr>
    <tr>
        <td data-indent="0">2</td>
        <td data-indent="0">Test</td>
        <td data-indent="0">Test 2</td>
    </tr>
</tbody></table>

Затем с помощью jQuery установите заполнение каждого значения ячейки в вашей таблице:

$("td")
    .css("padding-left", function (index) {
    return 10 * parseInt($(this).data("indent")) + "px";
});

Видите это работает наjsFiddle.

Однако, как я вижу, проблема в том, что вы теряете семантику иерархии. user764357
Почему бы не сделать заполнение через CSS? Вы можете сопоставить ячейки с падением через td: first-child [data-indent = "1"] или td: first-child [data-indent = "2"] и примените необходимые отступы. Lars Ebert
0

ых данных, которые также соответствуют иерархии.

Этоодин такой пример.

Однако, используя Extjs в двух очень крупных проектах, я лично рекомендую держаться от него подальше, если высобирается производить большое приложение. Хотя это может быть хорошо для одноразовой сетки, я лично считаю, что этоПлохо реализованы и могут стать более громоздкими по мере увеличения размера проекта. Тем не менее, это очень многофункциональный, поэтомупанель примеров может дать вам больше идей по сеткам (таблицам), которые могут вам помочь.

Имейте в виду, что вы всегда должны спрашивать себя "на какие вопросы пытаются ответить мои пользователи? Затем спросите себя:Какие графические устройства дают самый ясный и простой способ ответить на этот вопрос? "

Одна книга, которая действительно помогла мне с этими вопросами, былакнига дизайна приборной панели, Несмотря на то, что вы, возможно, не строите панель мониторинга, у нее есть много техник и теорий UX, которые упростили мне выбор подходящего элемента UI (по отношению к данным).

Надеюсь, это поможет ... Я

туше, сэр :-) Homer6
Никаких обид не было задумано ... по моему опытуявляется Обычно в комментариях указываются потенциальные недостатки ответа, независимо от того, дал ли комментатор ответ (со мной наверняка случилось). По второму вопросу: яваскрипт или нет, я думаю,законно критиковатьне представляет данные вообще как способ представления данных. OP явно заботится о семантической разметке, и пример, на который вы ссылаетесь, совсем не похож на. Zero Piraeus
я не уверен, что ябуду описывать (из вашего связанного примера) как семантическое представление данных ... этоявляется очень Extjs подход, хотя ;-) Я ' Zero Piraeus
я не уверенхорошая форма для критики других ответы, когда тыВыложил один из ваших собственных. Он спросил о представлении данных в веб-интерфейсе пользователя. Это значит "Только HTML? Потому что я, конечно, неСчитайте, что текущее состояние сети. Javascript - это бесценный инструмент пользовательского интерфейса. Homer6
3

использоватьtable и сделать связь / иерархию явными с естественным языкомиспользуйте элементы секционирования (соответственно заголовки, если вы используете HTML 4.01)table с колонкой, объясняющей иерархию

Если нет разметки для определения этого отношения, вы должны использовать текст. Если визуальное представление однозначно, вы можете визуально скрыть этот текст, чтобы он был доступен только для пользователей программы чтения с экрана / текстового браузера.

В вашем случае вы можете добавить столбец, который объясняет отношения строк, которые "подпункты ":

<table>

  <tbody><tr>
    <th>Seq</th> 
    <th>Relation</th> <!-- or some clever better label, -->
    <th>Item Name</th>
    <th>Min</th>
    <th>Max</th>
  </tr>

  <!-- … -->

  <tr id="2">
    <td>2</td>
    <td></td> <!-- "parent", "root", "container", empty -- whatever makes sense for your case -->
    <td>Name</td>
    <td>1</td>
    <td>1</td>
  </tr>

  <tr id="2.1">
    <td>2.1</td>
    <td>child of <a href="#2">Name</a></td>
    <td>First Name</td>
    <td>1</td>
    <td>1</td>
  </tr>

</tbody></table>

Каждый ряд может получитьid (со значением Seq или Item Name), так что эта строка может быть связанаid значения, начинающиеся с цифры, не допускаются в HTML 4.01; Вы могли бы использовать что-то вродеid="seq-2.1" там}. Если элемент является дочерним по отношению к другому элементу, вы можете указать ссылку на строку родительского элемента.

Таким образом, вы проясните для людей, и машины все еще видят, что эти строки связаны, хотя конкретная семантика этого отношения не читается машиной. Вы можете использовать тип ссылки (rel значение) здесь, если сделать смысл отношения явно понятным. В HTML 4.01 вы можете создать значение самостоятельно, в HTML5 это должно бытьзарегистрированный первый.

элементы секционирования / заголовки

Вместо использованияtable, вы могли бы использовать HTMLс изложением. {В следующем примере используетсяHTML5’секционные элементы, Если вы используете HTML 4.01, просто замените элементы секционирования наdiv (или вообще без элемента) и используйте только заголовки.}

Каждый раздел (введенный заголовком) представляет элемент. Схема заголовков (соответственно вложенность элементов секционирования) представляет иерархию ваших элементов.

Вот пример, чтобы увидеть всю структуру:

 <article>

   <h1><!-- heading for the whole data --></h1>

   <section class="item" id="1">
     <h2>Identifier</h2>
   </section>

   <section class="item" id="2">
     <h2>Name</h2>

     <section class="item" id="2.1">
       <h3>First Name</h3>
     </section>

     <section class="item" id="2.2">
       <h3>Middle Name</h3>
     </section>

     <section class="item" id="2.3">
       <h3>Last Name</h3>
     </section>

   </section>

   <section class="item" id="3">
     <h2>Age</h2>
   </section>

 </article>

каждыйsection может содержатьdl для свойств:

<section class="item" id="3">
  <h2>Age</h2>

  <dl>
    <dt>Min</dt>
    <dd>1</dd>
    <dt>Max</dt>
    <dd>1</dd>
  </dl>

</section>

В зависимости от реального значения вашего контента, вы можете использоватьcode элемент для названий элементов (например, если он описывает элементы языка разметки) и / илиdfn элемент, если следующее содержание является определением этого элемента.

2

ОБНОВЛЕНИЕ: ямы добавили использование идентификаторов и "заголовки» приписать, каким-то образом, семантически разметить иерархию.

Тот's окончательно табличные данные (вы должны действительно толкать определение "список" оправдать использование UL или DL здесь!).

Я думаю, что хороший подход будет использовать разные tbodys для группировки этих связанных строк (что-то вроде этого, он использовал здесьhttp://www.w3.org/TR/2012/WD-html5-20120329/the-table-element.html#the-table-element увидеть "стол, используемый для разметки головоломки Судоку ")

<table>
  <thead>
    <tr>
      <th id="seq">Seq</th>
      <th>Item Name</th>
      <th>Min</th>
      <th>Max</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th id="s1" headers="seq">1</th>
      <td>Identifier</td>
      <td>1</td>
      <td>1</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <th id="s2" headers="seq">2</th>
      <td>Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub">
      <th id="s2_1" headers="seq s2">2.1</th>
      <td>First Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub">
      <th id="s2_2" headers="seq s2">2.2</th>
      <td>Middle Name</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr class="sub">
      <th id="s2_3" headers="seq s2">2.3</th>
      <td>Last Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub sub">
      <th id="s2_3_1" headers="seq s2 s2_3">2.3.1</th>
      <td>Last Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr class="sub sub">
      <th id="s2_3_2" headers="seq s2 s2_3">2.3.2</th>
      <td>Last Name</td>
      <td>1</td>
      <td>1</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <th id="s3" headers="seq">3</th>
      <td>Age</td>
      <td>-</td>
      <td>1</td>
    </tr>
  </tbody>
</table>

Тогда вы можете использовать что-то вроде этого:

table { border-collapse: collapse; }
tbody { border-bottom:1px solid #000; }
tbody .sub td { padding-left: 10px; }

На самом деле, я думаю, что вы можете использовать только tbody, чтобы сгруппировать строки и оставить отдельные строки в покое.


  1
  Identifier
  1
  1


  
    2
    Name
    1
    1
  
  
    2.1
    First Name
    1
    1
  
  ...


  3
  Age
  -
  1

Для визуального представления вы можете использовать разные имена классов на каждом уровне (ямы использовали опцию в примере, но вы также можете использовать что-то вроде "level_0 ","1-й уровень", "уровень 2"и тд тоже). Coluccini
Интересно; Я не былне знаю оheadersи этохороший пример использования. Но как вы собираетесь использовать его в качестве ловушки CSS для визуального представления глубины иерархии, минуя два уровня, которые вы используете?tbody дает тебе? Zero Piraeus
С помощьюtbody чтобы элементы группы победилиработает, когда существует несколько уровней иерархии, как указано в комментариях OP. Zero Piraeus
Там'с "заголовки» атрибут, который вы можете использовать, чтобы как-то пометить иерархию. Я'Я сделаю пример и отредактирую сообщение через минуту. Coluccini

Похожие вопросы