Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sub-headers in Tables: Accessibility and Templating

This is hard to explain, so here is a pen where all the examples can be seen.

Which is better for accessibility?

Option 1

<table>
  <thead>
    <tr>
      <th>Thing 1</th>
      <th>Thing 2</th>
      <th colspan=2>Thing 3</th>
      <th>Thing 4</th>
      <th colspan=2>Thing 5</th>
      <th>Thing 6</th>
      <th>Thing 7</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan=2>40</td>
      <td rowspan=2>30</td>
      <th>Right</th>
      <th>Left</th>
      <td rowspan=2>50</td>
      <th>Right</th>
      <th>Left</th>
      <td rowspan=2>25</td>
      <td rowspan=2>30</td>
    </tr>
    <tr>
      <td>10</td>
      <td>20</td>
      <td>15</td>
      <td>40</td>
    </tr>
  </tbody>
</table>

Option 2

<table>
  <thead>
    <tr>
      <th>Thing 1</th>
      <th>Thing 2</th>
      <th colspan=2>Thing 3</th>
      <th>Thing 4</th>
      <th colspan=2>Thing 5</th>
      <th>Thing 6</th>
      <th>Thing 7</th>
    </tr>
    <tr>
      <th colspan=2></th>
      <th>Right</th>
      <th>Left</th>
      <th></th>
      <th>Right</th>
      <th>Left</th>
      <th colspan=2></th>   
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>40</td>
      <td>30</td>
      <td>10</td>
      <td>20</td>
      <td>50</td>
      <td>15</td>
      <td>40</td>
      <td>25</td>
      <td>30</td>
    </tr>
  </tbody>
</table>

If the sub values (Right and Left) are equal, it should display like this:

<table>
  <thead>
    <tr>
      <th>Thing 1</th>
      <th>Thing 2</th>
      <th>Thing 3s</th>
      <th>Thing 4</th>
      <th>Thing 5s</th>
      <th>Thing 6</th>
      <th>Thing 7</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>40</td>
      <td>30</td>
      <td>10</td>
      <td>50</td>
      <td>15</td>
      <td>25</td>
      <td>30</td>
    </tr>
  </tbody>
</table>
Or this:
<table>
  <thead>
    <tr>
      <th>Thing 1</th>
      <th>Thing 2</th>
      <th colspan=2>Thing 3</th>
      <th>Thing 4</th>
      <th>Thing 5s</th>
      <th>Thing 6</th>
      <th>Thing 7</th>
    </tr>
    <tr>
      <th colspan=2></th>
      <th>Right</th>
      <th>Left</th>
      <th colspan=5></th>  
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>40</td>
      <td>30</td>
      <td>10</td>
      <td>20</td>
      <td>50</td>
      <td>15</td>
      <td>25</td>
      <td>30</td>
    </tr>
  </tbody>
</table>
Or this:
<table>
  <thead>
    <tr>
      <th>Thing 1</th>
      <th>Thing 2</th>
      <th>Thing 3s</th>
      <th>Thing 4</th>
      <th colspan=2>Thing 5</th>
      <th>Thing 6</th>
      <th>Thing 7</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan=2>40</td>
      <td rowspan=2>30</td>
      <td rowspan=2>10</td>
      <td rowspan=2>50</td>
      <th>Right</th>
      <th>Left</th>
      <td rowspan=2>25</td>
      <td rowspan=2>30</td>
    </tr>
    <tr>
      <td>15</td>
      <td>40</td>
    </tr>
  </tbody>
</table>

Et cetera.

How can this be templated effectively?

Since tables are defined by horizontal row in the markup, logic to change columns needs to be sprinkled through all the trs:

Psuedo-code ERB

thing3() and thing5() return true if thing3right != thing3left

%table
  %thead
    %tr
      %th Thing 1
      %th Thing 2
      - if thing3()
        %th Thing 3
      - else
        %th{:colspan => "2"} Thing 3s
      %th Thing 4
      - if thing5()
        %th Thing 5
      - else
        %th{:colspan => "2"} Thing 5s
      %th Thing 6
      %th Thing 7
    - if !thing3() or !thing5()
      %tr.subcategory
        - if !thing3() && !thing5()
          %th{:colspan => "2"}
          %th Right
          %th Left
          %th
          %th Right
          %th Left
          %th{:colspan => "2"}
        - elsif thing3() && !thing5()
          %th{:colspan => "4"}
          %th Right
          %th Left
          %th{:colspan => "2"}
        - elsif !thing3() && thing5()
          %th{:colspan => "2"}
          %th Right
          %th Left
          %th{:colspan => "4"}
  %tbody
    %tr
      %td= @whatever.thing1
      %td= @whatever.thing2
      %td= @whatever.thing3right
      - if !thing3()
        %td= @whatever.thing3left
      %td= @whatever.thing4
      %td= @whatever.thing5right
      - if !thing5()
        %td= @whatever.thing5left
      %td= @whatever.thing6
      %td= @whatever.thing7

This works, but is very hard to use and update. It becomes exponentionally more complex with every column that has sub categories.

How can I display this data in a accessible way that can also be templated in an extensible and easy to update manner?

like image 600
bookcasey Avatar asked Mar 10 '13 22:03

bookcasey


1 Answers

If I understand correctly, you are going to want to use colspan and rowspan on the table headers; this will make them accessible and should take some of the pains you having generating them dynamically. As far as templating goes, you have an idea of what data is going to be coming back, so see if you can storyboard a few of the more common ones, then construct your template(s) from that. I modified your codepen with an example, it's all the way at the bottom.

http://codepen.io/jalbertbowden/pen/epgxs

like image 150
albert Avatar answered Oct 03 '22 01:10

albert