Are column headers essential in an accessible role="grid" setup? - html

goal: accessibility
target screen readers: JAWS and NVDA
I am adding role="grid" to a list of items. Each row in the grid contains some grid cells representing the item name, description, etc. I cannot change the markup to use a table so this is why I am using role="grid".
My question first question:
Within the context I am working, it is easier for me to add a visually hidden header to each grid cell rather than adding a separate row to the grid with column headers for each column. Is it ok to label each grid cell with a header rather than creating a row of column headers (role="columnheader")? How will this affect the level of accessibility for screen readers? Do users always expect a grid to have column headers?
My second question:
I want to include some content which is not located within the container I have marked with role="grid" as a grid row. Is it possible to associate content outside the grid container with the grid as a grid row?
NOTE: Keep in mind that altering the markup is not an option so suggestions such as "build it as a table" will not help here.
Thank you!

I cannot change the markup to use a table so this is why I am using role="grid".
If you can specify role="grid" in your code then it seems like you could specify role="table". Is there a reason that's not possible? The reason I ask is because grids should be reserved for when the actual cell contents can be edited, kind of like a spreadsheet. The fact that a cell has an interactive element in it does not mean it should be a grid. So my first recommendation is to use role="table".
However, grids are recommended when you have a group of things where you can navigate to each "thing" using the arrow keys.
I'm guessing you already read the spec for grids.
it is easier for me to add a visually hidden header to each grid cell rather than adding a separate row to the grid with column headers for each column. Is it ok to label each grid cell with a header rather than creating a row of column headers
While you could do that, you'll miss out on some of the benefits of real column and row headers. With a basic <table>, it's very helpful for assistive technology users, such as screen readers, to have both <th scope="col"> and <th scope="row">. The latter is often overlooked.
Picture yourself in the middle of a big table. Lots of rows and columns. You know the current value of the cell in the table because the screen reader just announced it. Now you want to navigate down one cell. If you don't have a row header, then you will not hear any context for the next cell value. If you want to navigate left or right one cell, if you don't have a column header, then you will not hear any context for the next cell value.
If you hard code the column header as a visually hidden element, then you will always hear that column header announced for the cell even if you are navigating vertically down a column. That would be unexpected behavior for a screen reader user. The column header should only be announced if you navigate horizontally across a row, not vertically down a column. When you navigate vertically, the row headers should be announced.
I'm not trying to be harsh here but I think you need to go back to your statement:
it is easier for me
and decide if the ease of coding is more important than the end user experience.
If there's a technology reason you can't have column and row headers, because the library you're using doesn't allow it or some other reason, then as a last resort, you can try coding around it with visually hidden element but I would not recommend that as a first choice.
I want to include some content which is not located within the container I have marked with role="grid" as a grid row.
That's a little trickier. The aria-owns attribute is exactly what you need but it's typically used when a child element can't be owned by the parent via normal DOM nesting. In your case, it sounds like most of the elements are nested according to the DOM but you'll also have something outside the DOM.
The tricky part is when you mix the two. As documented in the spec:
If an element has both aria-owns and DOM children then the order of the child elements with respect to the parent/child relationship is the DOM children first, then the elements referenced in aria-owns.
So you might get some funky reading order if the literal DOM children are announced first and then the aria-owns children are announced second. Definitely worth a bit of testing. You might have to put an ID on every row, including the content outside the table, then use all of those IDs in aria-owns of the table even those most of the rows are "naturally" owned by the table because of the DOM.

Related

Expandable area under a Table Row (Semantic UI React)

I'm trying to create Table Rows in a Table that can expand by clicking on them (individually).
For example, if I would click on the specified area in the picture below, a Segment/Container (some sort of area) would drop down with content inside.
I've tried a solution that is mentioned in this thread, but the underlying problem is that every element under a Table Row/Cell is subject to the rules and boundaries of the Table HeaderCell. So if I for example try to create a Table Row with a Segment under it, the result will look like this:
As you can see the Segment is inside the new Row but is limited to the size of the HeaderCell.
When doing this I also get this error:
validateDOMNesting(...): <div> cannot appear as a child of <tr>.
in div (created by Segment)
It seems that Segment under Table Row is therefore a prohibited element structure.
Any idea on how the element structure should look to create some kind of area under a Table Row?
The the warning of a <div> not being allowed as a child of a table row is telling you that it is not valid HTML. That is true whether you are using Semantic UI React or plain HTML.
I'd recommend rendering another row below the row you have in your table already. Set a column inside of that row which spans all of the columns. Now you have a container which you can put other UI inside if you want to. You can customize the style of the wide cell if you need to for some reason.
Then you can set a toggle state on the clickable area of your table. You'll probably want to put the click events on the contents of the cells and not the cells themselves.
I threw together a quick Codepen showing how this would work. This gives you a working concept that you can modify based on your use case.
https://codesandbox.io/s/serene-water-ikco9?file=/example.js

Dynamic Table Rows

I have four cells on one table and another table with about eight
cells.
I have set the max-width to 300px on all cells. Now the problem I face
is that the cells do not drop to a second row if the page is too
small. (Which is in every matter at the moment haha)
I was wondering how I would go about adding dynamic rows to make the extra content beyond the page width, drop below into a new row?
All the code can be seen in the Developers tools for the following website
(Cells/Rows in the products section is the problem I am facing.)
Kind regards,
Jesse M.
Ohh my sweet summer child,
The <table> element is "designed" to behave that way. The table will try to cramp up all the columns in the possible space and based on various css and html attributes, hide/overflow/cramp-up the data in columns, But never will it allow the columns of one row to flow down to another row.
So you are left with a lot of options using CSS and HTML elements.
If you are into frameworks, I recommend Bootstrap that is designed to work exactly that way, and use the provided col-xx-x classes for the elements that need to be in a row at some screen width, and "drop below into a new row" on other screen width.

Way to show wide table neatly

I am making a basic screen which simply shows a grid of data, but the grid can have more columns than the screen can cope with. I plan to use Bootstrap, but just for it's controls, look and feel. The page, however, does not need to scale for mobile.
A very basic example of the data I am showing looks like this:
https://jsfiddle.net/bunwt5cy/1/
So, first column is just an incrementing number, followed by a date, and then the data. The number of columns can range from 1 account, to 20. Each column (cell) then has 3 financial values (2 shown in demo) ranging from 0.00 to 99,999.99 (To show sizes required).
I'm currently using <TABLE>, but is there a better way, using bootstrap, to do this? Can it be done better with DIVs? And if I do, am I limited to 12 Divs per row? If so, that's not an option then, as my grid may have > 12 columns.
Here is an example of some rows. I'm trying to make it neater, and use 'as best as possible' best practice, but also, make pretty.
As a best practice, you should continue to use table element for such spreadsheet-like, tabular data, while using CSS to make it "pretty".
The div element according to the HTML5 specs:
The div element has no special meaning at all ...
Authors are strongly encouraged to view the div element as an element of last resort, for when no other element is suitable. Use of more appropriate elements instead of the div element leads to better accessibility for readers and easier maintainability for authors.
In this case table is available, it is appropriate for tabular data, so in terms of best practice, you should continue using table element for such tabular data rather than div.

how to make a form designer

The Problem in Hand:
I want to make a form designer where user can drag and drop fields of different type and design the layout too, some what similar to wufoo form builder but here the layout is limited to single column whereas I want to make something where user can make the layout as they want.
I understand how to do in single column view, but could not understand how to achieve multiple column layout eg: row 1 there could be 3 elements, row 2 one element stretched to full length, row 3 there could be just 2 elements etc.
What I tried:
I have tried with jquery UI sortable to make a single column layout with using div where new elements can be dragged and repositioned.
Any suggestion on how to proceed further will be helpful
I have tried searching StackOverFlow and google but could not find any link on a similar topic. If anyone could point me to the same, it will be also helpful.
When you reorder elements on wufoo form builder, you can only drag'n'drop up or down. Remove that restriction and as soon as one element is dragged across a certain threshold, it "belongs" to the next column. If the "old" column was the first or last one and the line that the element was moved over was to the "outside" of the form, add a new column there, until the maximal number of columns is reached.
If the used drags the last element of a column into another column, remove the now empty column on element-drop.
You could also remove the dynamic adding/removing of columns and juist have a button ("remove column" & "add column") to do it by code.
An example for the dropping in another column can be found here: http://jqueryui.com/sortable/#connect-lists
Hope this helped!
Edit:
http://jqueryui.com/sortable/#portlets and http://jqueryui.com/sortable/#empty-lists also have elements that you could look into. Good luck! Sounds like a nice project. Can we see any progress or beta?

is it possible to make CSS3 tables that have different number column and column width in each row?

is it possible to use CSS3 table to make it look like this
+---A---+---B---+---C---+---D---+---E---+
>>>>+---A---+---B---+---C---+---D---+<<<< ---> case 1
+---A---+---B---+---C---+---D---+---E---+
case 1: need to margin-left the first cell right? is it any code that make auto to margin
+---A---+---B---+---C---+---D---+---E---+
+-----A-----+-------B-------+---C---+-D-+ ---> case 2
case 2: colspan is work on the cell width is same. what if the cell width is vary. Is it possible?
all of this code must be in CSS3 and HTML5 only. No use <table>, <tr>, <td> only <div>
Should I convert to use grid instead of using table?
Thank you.
Use tables if it is tabular data, if it isn't then use something else.
From your example where column widths don't match, and where colspans don't do what you want it's hard to see how the data could be tabular data.
A couple of options, colspan can work if you do it the right way. For example setting a colspan of 2 on normal single span cells would allow you to make other cells span to halfway through another column.
Or if it really isn't tabular data then use DIV's and position them apropriatley.
Using tables, you would not be able to vary the width of one rows cells without affecting the width of all the other rows cells though, im not even sure you can dynamically change colspan once the table has been drawn, never tried it to be honest).
In all honesty I suspect you are really looking to solve this using DIV's, as your data really doesn't seem to fit the tabular data model. Tbular data will generally have headers on columns with data corresponding to those column headers in the appropriate column. Your cells seem to be able to move freely and therefore would not be fixed under any particular column header.
I am guessing from the layout that you are possibly creating some sort of calendar? and events can span any distance of time etc across the columns? In which case I personally would prefer divs, although I know some people would prefer using tables.