Closed takenspc closed 8 years ago
This is somewhat related to https://www.w3.org/Bugs/Public/show_bug.cgi?id=29018
If there was a single row ordering that is used for the DOM APIs, for rendering and also for keyboard focus order, would that fix the problem? Any markup where the document order ends up not matching that order could be said to be invalid, which would include having tfoot before tbody.
If there was a single row ordering that is used for the DOM APIs, for rendering and also for keyboard focus order, would that fix the problem?
Yes, it will fix the problems.
However I don't think that changing the DOM APIs and the keyboard focus order depending on the rendering order is a good solution. I worry that it will be hard to define the order of rows with display:none
, display:block
, display:flex
and so on.
I think that theDOM order should be the single row ordering which is used for the DOM APIs and the keyboard focus order. Placing tfoot after tbody can achieve that. The rendering order will differ from the DOM order sometimes but match by default.
I don't mean that the DOM API or keyboard focus order would depend on the layout tree, just that the DOM API be made to match the reordering that happens in layout, and that keyboard focus order should match the DOM API.
What is the current keyboard focus order, by the way? Is it just the tr
s in tree order?
I don't mean that the DOM API or keyboard focus order would depend on the layout tree, just that the DOM API be made to match the reordering that happens in layout, and that keyboard focus order should match the DOM API.
Sorry, I misunderstood.
However please explain my concern.
I worry that reordering happens multiple times. For example, some authors use display:block
for table
and related elements on narrow screens and not on wide screens. In that case, the return value of HTMLTableElement.rows
could mutate without DOM operations.
Let's consider a following example.
var tFootBeforeTBodyTable = document.querySelector('table');
var rows = tFootBeforeTBodyTable.rows;
// rows -> [ first row of thead, ... , first row of tbody, ... , first row of tfoot]
Then the window was resized or the device orientation was changed and following styles were applied.
@media (...) {
table, tbody { display: block; }
thead, tfoot { display: none; }
}
The rows
will mutate without DOM operations.
// rows -> [ first row of thead, ... , first row of tfoot, first row of tbody]
I think this is confusing behavior.
What is the current keyboard focus order, by the way? Is it just the
tr
s in tree order?
Yes it is. AFAIK, display: table-*-group
doesn't affect keyboard focus order in the browsers.
Here is an example.
http://codepen.io/takenspc/full/NGZMpy/
Actually, the definition of HTMLTableElement.prototype.rows
depends only on the element types and not on computed style or the layout.
Even so, this is confusing, there's reordering here that tries to match the layout but doesn't really, not all of the time.
I'm quite unsure what to do about the DOM API here, it would probably be more sane if it just returned the rows in tree order with no reordering.
Making tfoot before tbody non-conforming sounds good to me, though. @sideshowbarker?
It seems a little unfortunate that we change authoring conformance requirements based on bugs in a11y tools. But I am happy to defer to our conformance checker expert @sideshowbarker.
Well, in this case it just seems like a misfeature that there should be any reordering anywhere, so if the reordering during layout is required for compat (which it probably is) it seems OK to just disallow any other order in the DOM.
Why it ever made sense to put the footers before the content I don't know, it seems like the idea might have been that headers and footers could be shown in multiple places for long tables, like some software does.
Why it ever made sense to put the footers before the content I don't know, it seems like the idea might have been that headers and footers could be shown in multiple places for long tables, like some software does.
Yeah, I believe that’s the rationale.
It seems a little unfortunate that we change authoring conformance requirements based on bugs in a11y tools.
Yeah, agreed. But as far as the behavior of the checker goes, it’s intended to help author-developers catch markup cases that might cause actual problems for end users in practice. From what @takenspc has described here, this seems like one of of those kinds of cases—that reality is that can cause problems, and we want to be able to make authors aware that it might.
So I do think it would be useful for the spec to include some requirement here to help authors avoid the problem and to guide checker developers. But that said, we could make it a “should”-level requirement rather than a “should”-level requirement. Like most document-conformance requirements, it’s a bit of judgement call. The checker behavior for a “should”-level requirement would just be a warning rather than an error, but in the end most author-devs using the checker tend to take warnings just as seriously as they do errors.
Given all that, I would tend to favor adding a statement to the spec like this:
A table should not contain a
tfoot
element before atbody
element [nor before the firsttr
element in the table?], because [user agents do not interoperability implement consistent behavior for how the resulting table is exposed to users of assistive technology such as screen readers].
And I would fine with elevating that “should” to a ”must” if we have agreement a stronger requirement is appropriate here.
So it's the content model of table that we should change. It's currently:
In this order: optionally a caption element, followed by zero or more colgroup elements, followed optionally by a thead element, followed optionally by a tfoot element, followed by either zero or more tbody elements or one or more tr elements, followed optionally by a tfoot element (but there can only be one tfoot element child in total), optionally intermixed with one or more script-supporting elements.
I think just removing the first "followed optionally by a tfoot element" part should do the trick. Is anything else needed?
That would make it "must".
We should check if it's possible to change the DOM API instead of assuming it's isn't.
SELECT page, url, body FROM [httparchive:runs.2014_08_15_requests_body]
WHERE REGEXP_MATCH(body, r'\.(tFoot\s*=|createTFoot\s*\()')
64 rows.
With response bodies: https://console.developers.google.com/m/cloudstorage/b/zcorpan/o/tfoot.csv.gzip (6.25MB)
Just page+url:
page url
http://www.corcoran.com/ http://www.corcoran.com/Content/js/Scripts?v=rrmJuNTprMRptd4DdehI8gqvrQ-wUUXVQ3H-D6-7CY41
http://www.odziez-bielizna.pl/ http://walutami.pl/widget/widget.php?currencies[]=EURPLN¤cies[]=USDPLN¤cies[]=CHFPLN¤cies[]=GBPPLN¤cies[]=EURUSD&columns[]=Name&columns[]=Bid&columns[]=Ask
http://www.fcstats.com/ http://fcstats.com/js/libs.js
http://www.filegir.com/ http://www.filegir.com/classes/sorttable.js
http://www.ddl.me/ http://en.ddl.me/js/app-v0.2.js
http://www.easywls.org/ http://www.easywls.org/client/assets/71585c3e5858ef1d/stack/en_US/SearchTemplateStack.js
http://www.codeavengers.com/ http://www.codeavengers.com/jquery/js/plugins.min.js?9.12.0
http://www.anunciando.com.co/ http://www.anunciando.com.co/anunciando/deferredjs/6855CEE52397B15519A2A0E446D69B6C/1.cache.js
http://www.ddl.me/ http://en.ddl.me/js/mocha.js
http://www.itdistri.com/ http://itdistri.com/js/sorttable.js
http://www.programma.tv/ http://www.programma.tv/3.001/b/ample-0.9.5.a.2011.10.09.js
http://www.shredderchess.net/ https://www.shredderchess.net/webclient/8AEC10A3421C67CB31376E1C75988C96.cache.html
http://www.notatek.pl/ http://notatek.pl/components/platform/platform.js
http://www.dotamax.com/ http://www.dotamax.com/static/js/sorttable.js
http://www.hockey-reference.com/ http://d2ft4b0ve1aur1.cloudfront.net/js-412/sr-hr-min.js.jgz
http://www.titanshare.to/ http://titanshare.to/nload/21E40A8F21BB42D54BD9994F93236761.cache.html
http://www.advantageaustria.org/ http://www.advantageaustria.org/components/min/g=js&1406900702
http://www.pytajnia.pl/ http://www.pytajnia.pl/js/mintAjax.js
http://www.fr.pl/ http://ecenter.pl/js/sortable.js
http://www.netstate.com/ http://www.netstate.com/includes/js/script.js
http://www.componentone.com/ http://www.componentone.com/ScriptResource.axd?d=KwlBz2fHX-Xdo4oLLmgX7xSfn5hOz_h5o61qvndM0UBYfCxtrkIBNQ-npbq52JnQLUcfGdI3t0-TshX9THhvsMmxX-sb5klij3vllh6Y4ivVEZcIf_ZERWKbIt2rO6HIz0nOiun6PzEy8cuqCI5-DAORsRYpK8D1pVyFRQKfmtlevWxp0&t=542fdfb0
http://www.vkdownload.net/ http://www.vkdownload.net/js/sortable.js
http://www.phila.gov/ http://cdn.wijmo.com/jquery.wijmo-complete.all.2.3.2.min.js
http://www.statsf1.com/ http://www.statsf1.com/include/master.js
http://www.emaluszki.pl/ http://emaluszki.pl/libs/mint.js
http://www.fifa.com/ http://js.fifa.com/components/script/require-libs/frameworks/bundle.js?v=635436162292838476
http://www.goo.gl/ http://goo.gl/gwt/A4360D16C0B7553E09A22F16D0F3584A.cache.js
http://www.pro-football-reference.com/ http://d2ft4b0ve1aur1.cloudfront.net/js-412/sr-pfr-min.js.jgz
http://www.srvusd.net/ http://cdn.schoolloop.com/1408140958/static/lib/wijmo/Wijmo.2.3.8/Wijmo-Complete/js/jquery.wijmo-complete.all.2.3.8.min.js
http://www.centralazabawek.pl/ http://www.centralazabawek.pl/scripts/mintajax.js
http://www.coinmine.pw/ http://www.coinmine.pw/pics/sorttable.js
http://www.tokinito.gr/ http://tokinito.gr/js/jquery.wijmo-pro.all.3.20131.1.min.js
http://www.wijmo.com/ http://wijmo.com/wp-content/themes/wijmov2/js/jquery.wijmo-pro.all.3.20141.34.min.js?ver=20141.34
http://www.canlifm.com/ http://canlifm.com/radyodinle/views/theme/js/sorttable.js
http://www.cooperindustries.com/ http://www.cooperindustries.com/apps/public/docroot/scripts/sorttable.js
http://www.richfaces.org/ https://www.jboss.org/.resources/jbossorg-downloads2/sorttable.js
http://www.colubris.com/ http://h17007.www1.hp.com/tridion/assets/scripts/sortableTable-hpe.js
http://www.myunfairadvantage.net/ http://cdn.wijmo.com/jquery.wijmo-pro.all.3.20133.20.min.js
http://www.barcamp.org/ http://vs1.pbworks.com/shared/statics/packed-v65464171.js
http://www.fohrcard.com/ http://www.fohrcard.com/assets/application-e4c80d88a9658a8ad6d3e7ae54370c6a.js
http://www.sports-reference.com/ http://d2ft4b0ve1aur1.cloudfront.net/js-402/sr-base-min.js.jgz
http://www.usahockey.com/ http://app-assets3.sportngin.com/javascripts/base_packaged.js?1408126954
http://www.fastenal.com/ http://www.fastenal.com/web/static/scripts/scripts-9.19.6-min.js
http://www.halotracker.com/ http://www.halotracker.com/htr.js?V=16
http://www.worldpopulationreview.com/ http://worldpopulationreview.com/js/concat.js
http://www.customelements.io/ http://customelements.io/bower_components/platform/platform.js
http://www.skyscrapercenter.com/ http://www.skyscrapercenter.com/jquery.tablesorter/sorttable.js
http://www.launchpad.net/ https://launchpad.net/+combo/rev17156/?yui/array-extras/array-extras-min.js&yui/anim-base/anim-base-min.js&yui/anim-color/anim-color-min.js&yui/anim-xy/anim-xy-min.js&yui/anim-curve/anim-curve-min.js&yui/anim-easing/anim-easing-min.js&yui/anim-node-plugin/anim-node-plugin-min.js&yui/anim-scroll/anim-scroll-min.js&lp/app/javascript/effects/effects-min.js&lp/app/javascript/expander-min.js&lp/app/javascript/lp-min.js&lp/app/javascript/foldables-min.js&lp/app/javascript/sorttable/sorttable-min.js&yui/widget-stdmod/widget-stdmod-min.js&yui/widget-position/widget-position-min.js&yui/widget-position-align/widget-position-align-min.js&yui/widget-stack/widget-stack-min.js&yui/widget-position-constrain/widget-position-constrain-min.js&yui/overlay/overlay-min.js&lp/app/javascript/overlay/overlay-min.js&yui/querystring-stringify-simple/querystring-stringify-simple-min.js&yui/io-base/io-base-min.js&yui/datatype-xml-parse/datatype-xml-parse-min.js&yui/io-xdr/io-xdr-min.js&yui/io-form/io-form-min.js&yui/io-upload-iframe/io-upload-iframe-min.js&yui/queue-promote/queue-promote-min.js&yui/io-queue/io-queue-min.js&lp/app/inlinehelp/inlinehelp-min.js&yui/json-parse/json-parse-min.js&yui/json-stringify/json-stringify-min.js&yui/querystring-parse/querystring-parse-min.js&yui/querystring-stringify/querystring-stringify-min.js&lp/app/javascript/client-min.js&lp/app/javascript/lp-links-min.js&lp/app/javascript/longpoll-min.js&lp/app/javascript/mustache-min.js&lp/app/javascript/formoverlay/formoverlay-min.js&lp/app/javascript/extras/extras-min.js&lp/app/javascript/anim/anim-min.js&lp/app/javascript/choiceedit/choiceedit-min.js&yui/dump/dump-min.js&lp/app/javascript/ui/ui-min.js&lp/app/javascript/activator/activator-min.js&yui/escape/escape-min.js&yui/plugin/plugin-min.js&lp/app/javascript/picker/picker-min.js&lp/app/javascript/client-min.js&yui/event-simulate/event-simulate-min.js&yui/async-queue/async-queue-min.js&yui/gesture-simulate/gesture-simulate-min.js&yui/node-event-simulate/node-event-simulate-min.js
http://www.esselungajob.it/ http://www.esselungajob.it/lavoraconnoi/it.esselunga.hrweb.Application/3C01EBFCC563833BAD3290D8F2214C1D.cache.html
http://www.maximintegrated.com/ http://www.maximintegrated.com/etc/designs/maximintegrated/clientlibs/common.js
http://www.browserscope.org/ http://www.browserscope.org/static/browserscope.js?v=21.375139290952075791
http://www.sportngin.com/ http://app-assets3.sportngin.com/javascripts/base_packaged.js?1408126954
http://www.goddiva.co.uk/ http://www.goddiva.co.uk/core/media/media.nl?id=175754&c=949266&h=4c34893c66ba5e166a1c&_xt=.js
http://www.polymer-project.org/ http://www.polymer-project.org/platform.js?20140808
http://www.hilltopads.net/ http://www.hilltopads.net/js/sortable.js
http://www.esselungajob.it/ http://www.esselungajob.it/lavoraconnoi/it.esselunga.hrweb.Application/3C01EBFCC563833BAD3290D8F2214C1D.cache.html
http://www.instantsoftwareonline.com/ https://apex.cherwellondemand.com/CherwellPortal/IT/Resource/Script/scripts.jquery.wijmo-complete.all.2.3.2.min.js
http://www.basketball-reference.com/ http://d2ft4b0ve1aur1.cloudfront.net/js-412/sr-bbr-min.js.jgz
We should check if it's possible to change the DOM API instead of assuming it's isn't.
As discovered by Prashant, it's not entirely interoperable right now, so I think the chances of it being possible to change are pretty good.
What should we try to measure? All cases where the rows
collection is used and there's a thead element after any tr/tbody, or where there's a tfoot before any tr/tbody?
I was talking about tFoot
setter and createTFoot()
method (if they can insert the tfoot last), not rows
.
tFoot
setter
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3776
createTFoot()
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3777
It looks like Firefox inserts them last. I suppose that makes it pretty safe to change.
OK so for this bug I suggest
tFoot
setter to always insert at the end of the table.createTFoot()
to always insert at the end of the table (when it inserts something).(Making the tfoot content model "should" makes the spec more complicated instead of simpler, which seems bad.)
In the absence of any authors actually wanting to put tfoot before tbody I agree with that plan. Personally I think in theory it could be nice ("meta stuff first, then main stuff") but I admit never having actually written a tfoot so I'm fine with the restriction.
So what about the rows
ordering in https://www.w3.org/Bugs/Public/show_bug.cgi?id=29018? Some change seems necessary, so if we change the conformance and content that results in reordering is extremely rare, shouldn't we simplify it?
Let's discuss rows in that bug.
It sounds like we have a plan: https://github.com/whatwg/html/issues/352#issuecomment-162011747
Who wants to make this change? @takenspc? @zcorpan?
Ideally when doing this people would write web platform tests for the tFoot setter and createTFoot() method.
HTML 4 defined that
It is, however, hard to implement tfoot before tbody in accessible way. There are still issues around tfoot before tbody (see issues).
On the other hand HTML Standard has allowed placing tfoot after tbody. So let's discourage authors from using tfoot before tbody and encourage authors to use tfoot after tbody (see the proposal 1 and 2).
Issues
keyboard focus order
Let's consider a following table:
In this table, the keyboard focus moves tfoot then tbody in browsers. More specifically, the focus moves as follows:
However tfoot is rendered after (usually below) tbody. It can be said that the visual order doesn't match the keyboard focus order. This could lead to confusion.
I admit that it is possible to introduce a sequential focus navigation algorithm for tables. But I belive that encouraging authors to use tfoot after tbody is more productive.
Order of Accessibility Objects
Tables with tfoot before tbody
Internet Explorer, Edge and Firefox exposed table rows to assistive technologies in following order:
while Chrome and Safari exposed rows in following order:
The difference affects reading order of screen readers. For example, NVDA + Firefox reads tfoot then tbody while NVDA + Chrome read tbody then tfoot.
Tables with tfoot after tbody
Above mentioned browsers exposed rows in following order:
Though the HTML Accessibility API Mappings may be responsible for that issue, I think that the HTML Standard should encourage authors to use tfoot after tbody.
Proposal 1
Move tfoot before tbody to the "obsolete but conforming features" from the main part of the specification.
Change the "content model" of table element as follows:
Change the "contexts in which this element can be used" of tfoot element as follows:
Add following to "Warnings for obsolete but conforming features":
The
createTFoot()
andtFoot
setter insert tfoot before tbody in some circumstances.I think it is too late to change to the behaviors of
createTFoot()
andtFoot
setter although I'm skeptical thatcreateTFoot
andtFoot
setter are used in the wild.I propose making user agents to report warnings.
Add a note to
tFoot
andcreateTFoot()
such as: