In #414190: Add WAI-ARIA landmark roles to Garland the issue of WAI-ARIA landmark roles was discussed. I believe that it would be a good idea for themes, including core themes, to be able to indicate the WAI-ARIA landmark role for each region that is defined.

See also:
#963760: Decide if ARIA will be permitted in markup
http://www.w3.org/TR/wai-aria/roles#landmark_roles

CommentFileSizeAuthor
#24 search-role.patch456 byteststoeckler
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Everett Zufelt’s picture

Issue tags: +Accessibility

tagging

Everett Zufelt’s picture

Note: I realize that themes can specify landmark roles in their tpl.php files. But I think it would be nice, possibly, to allow this to be specified in theme.info. I'm not a themer, so perhaps the current ability to specify landmark roles in tpl.php files is sufficient. Would like to hear some discussion.

bowersox’s picture

+1 for the idea; I'm not sure what themers would like best. As a developer, I see the appeal of defining roles in the theme.info file.

Would we need to allow the theme.info roles to be over-ridden by the actual blocks or content that end up in those regions? For example, a role="navigation" region might be used in a special situation by a block that needs role="search" or "navigation". For that reason, it seems better to have all this applied in code rather than hard-coding roles into a page.tpl.php file.

mgifford’s picture

I think we'll find some good leadership & best practices from themes that have taken the #d7ax pledge.

Everett Zufelt’s picture

We now know that Drupal 8 will be html5, so there is no issue in including WAI-ARIA landmarks in markup, whether directly or programmatically.

I would love to hear from themers, and anyone else, if there is a benefit either way of applying landmark roles in theme template files, or theme info files.

Jeff Burnz’s picture

Title: Allow themes to specify WAI-ARIA landmark roles for regions » Allow themes to specify WAI-ARIA landmark roles

By and large, regions should not have roles. Regions are dumb containers - they have no idea what they contain. Its the content in the region that should get a role, i.e. roles should be applied to block and entity wrappers etc.

I'm actually being so bold as to changing the title, because really, adding roles to regions is a no go because it makes way to many assumptions about what a region might contain (is it a menu, or an article, or a form - regions don't know and don't care).

Not even role="main" belongs on a region, it belongs on the main content block.

There are two ways to add roles, both are currently available to themers right now:

1. $attributes variable - we can push new attributes via preprocess functions to any template.
2. hard code them in template files.

I would push hard for us picking one and being very consistent with it - my vote goes to $attributes.

Everett Zufelt’s picture

@Jeff

Is there a contrib theme using the $attributes approach that you can point me to?

Am I correct in assuming that with this approach we could add the attribute to core preprocess functions, and that themes that wish to remove the attribute can override the function?

Jeff Burnz’s picture

Issue tags: +html5, +Front end

I don't know of one as yet Everett, although the next versions of my D7 themes will do this, I've just lacked time to implement it.

You are right, core can push out these attributes, and themes could remove them.

There are a couple of exceptions I can think of that can't be done with the current use of attributes - namely role="banner", which applies to the site header, and role="contentinfo", which applies to the site footer - both of which could either be hard coded or we could add new attribute variables just for these exceptions (there could be others, I can't recall right now).

By and large though modules/core could add these attributes. For example menu module could add "role="navigation" to menu blocks and the search module could add role="search" to search forms/blocks etc.

Everett Zufelt’s picture

@Jeff

Do you think that this is better to do all in one issue, or to break it apart for each different Core module? One thing that we may get stuck on, as we will for html5 semantic elements, is, for example, when a menu block isn't used for navigation.

Do we perhaps need a method of blocks registering their 'type' and then mapping these types, in preprocess functions, to html5 semantics and ARIA roles?

A developer could set the 'type' for a block in code.
A site builder could override the 'type' as they do with block titles.
A user created block could have a type set by the user

So, if I decide to use a menu block for something that isn't 'navigation' I could override the type to something different, including 'none'.

Of course this still doesn't resolve the issue of the same block being used in multiple ways, which may not share the same semantics, is this a real concern?

Jeff Burnz’s picture

I cant think of a situation where a menu block is not navigation.

I don't think we should have a front facing UI specifically for roles, that would likely confuse and overwhelm the majority of users. We could do a reasonable job of mapping roles to HTML5 elements if we have a way to select wrappers in D8 for user created blocks - so that is a possibility.

The way I see it working is that we can do a pretty good job with automation, meaning using attributes variables, and layer something on top of this such as mapping roles to HTML5 wrappers - ideas are needed here.

Jeff Burnz’s picture

Title: Allow themes to specify WAI-ARIA landmark roles » Decide how to include WAI-ARIA landmark roles

Changing title, I think its really a no brainer for us to use roles, so first we need to figure out how we're going to include roles, then work through the actual implementation of each role.

Lets make this issue about how we include them - so far we have proposed using $attributes or adding them directly into templates (maybe a combination of those two), also maybe there is some other way I have not thought of?

Everett Zufelt’s picture

Would love any feedback on WAI-ARIA Roles , part of the html5 initiative documentation. Once we decide on a methodology we can document it at the bottom of this page.

mgifford’s picture

I'd think that we could start pretty easily with Genesis as an example and then move from there.

Is there a proposed approach to moving Bartik to HTML5? We're dropping Garland & Seven at the least needs to be renamed.

Do we want to add ARIA to Stark?

Everett, great work with - http://drupal.org/node/1179668 - my only suggestion is a few links to external resources to examine ways of implementing it in other contexts.

dvessel’s picture

subscribing

Everett Zufelt’s picture

As an example, I wrote a function today to add a role="search" to the search form:

function search_preprocess_block(&$variables) {
  if ($variables['block']->module == 'search') {
    $variables['attributes_array']['role'] = 'search';
  }
}

This function can go in search.module and sets the block attribute role to "search". Since there is only one block in the search module I didn't have to target a specific block in the preprocess function.

I wonder about the value of using preprocess functions vs just putting the attribute in the theming function or template file. I like that the attributes are all rendered and applied together using the preprocess method. But, there is definitely simplicity in simply adding the role to a theme template file. Using the preprocess function the code is called for every block that is rendered, whereas with the template file it is only used for the specific element being themed.

Everett Zufelt’s picture

@mgifford

I'd think that we could start pretty easily with Genesis as an example and then move from there.

* I think that we should focus efforts on core at the moment.

Is there a proposed approach to moving Bartik to HTML5? We're dropping Garland & Seven at the least needs to be renamed.

* See http://drupal.org/node/1089770

Do we want to add ARIA to Stark?

* By adding aria to core templates and preprocess functions we will be adding it to stark. If contrib D8 themes do not want aria / html5 they will override / alter the templates and preprocess variables.

Everett, great work with - http://drupal.org/node/1179668 - my only suggestion is a few links to external resources to examine ways of implementing it in other contexts.

* Can you be more clear about what you mean by "implementing it in other contexts"?

mgifford’s picture

<input title="Enter the terms you wish to search for." placeholder="Search" required="" role="Search" type="search" id="edit-search-block-form--2" name="search_block_form" value="" size="15" maxlength="128" class="form-text form-search">

This is what I added to my Genesis subtheme to add the role & also a placeholder for this block:

function MY_SUBTHEME_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'search_block_form':
      // HTML5 placeholder attribute
      $form['search_block_form']['#attributes']['placeholder'] = t('Search');
      $form['search_block_form']['#attributes']['required'] = '';
      $form['actions']['submit']['#type'] = 'submit';
      $form['actions']['submit']['#value'] = t('Go');
      $form['search_block_form']['#attributes']['role'] = t('Search');
      break;
  }
}

As far as Genesis, I like practical examples that we can execute now, where possible. Totally understand that the end goal is core.

On your post, I was looking for links mostly. I like to look at examples where code has been implemented to get a sense of where I might find the best way to capture the role for whatever widget you're trying to best describe.

Everett Zufelt’s picture

@mgifford

A couple of points about your example.

1. You are applying role="search" to the input element, it should be applied to the block wrapper, form wrapper, or form element itself. "searchh" is a navigational landmark, not a widget role.
2. You shouldn't t('search') for the role. It is a semantic role with an english API

Once we have some examples in core I'd be happy to see them added to the docs.

mgifford’s picture

Drat. How about:

      <form action="/blog" method="post" id="search-block-form" accept-charset="UTF-8"><div><div class="container-inline" role="search"> 
      <h2 class="element-invisible">Search form</h2> 
    <div class="form-item form-type-searchfield form-item-search-block-form"> 
  <label class="element-invisible" for="edit-search-block-form--2">Search </label> 
 <input title="Enter the terms you wish to search for." placeholder="Search" required="" type="search" id="edit-search-block-form--2" name="search_block_form" value="" size="15" maxlength="128" class="form-text form-search" /> 
</div> 
<div class="form-actions form-wrapper" id="edit-actions"><input type="submit" id="edit-submit" name="op" value="Go" class="form-submit" /></div><input type="hidden" name="form_build_id" value="form-h-rNzTBHQbtFGVBIetSn1e45o6Frux9-fTtXYlKpC98" /> 
<input type="hidden" name="form_token" value="6_SykYAhlZ7JlA2uRhSvNQ5_nNZLe0xuKLueRiEUcEk" /> 
<input type="hidden" name="form_id" value="search_block_form" /> 
</div> 
</div></form> 

via customizing search-block-form.tpl.php :

<div class="container-inline" role="search">
  <?php if (empty($variables['form']['#block']->subject)) : ?>
    <h2 class="element-invisible"><?php print t('Search form'); ?></h2>
  <?php endif; ?>
  <?php print $search_form; ?>
</div>

form_alter could probably work too, to apply it to the form element, but otherwise.....

Jeff Burnz’s picture

What we're looking for Mike is a very consistent way to apply roles - afaict we can do this with attributes arrays in most cases - so block and entity HTML wrappers, and special case the roles such as banner and contentinfo (such as create new attributes variables for our page header and footer) seems to make sense, we can place the role on the very outer wrapper in each case.

voxpelli’s picture

One thought: What happens when a non WAI-ARIA theme is used if we include WAI-ARIA support into core? Will we then end up with a semi-WAI-ARIA site that perhaps could be worse than a non-WAI-ARIA site?

I'm not very familiar with WAI-ARIA but looking at how Microformats has sometimes been implemented by frameworks they have often been broken by third party themes not being aware of their existence or of how to use them - thus ending up with an unusable and/or misleading the Microformat markup. No Microformats markup would in those cases have been better than a broken misleading one.

If the case could be the same with WAI-ARIA in Drupal then I think it should be an opt-in for themes in their info file so that themes not opting in won't have a broken WAI-ARIA implementation.

Makes sense?

Everett Zufelt’s picture

@voxpelli

Good question.

All WAI-ARIA roles do is provide enhanced semantics for markup. Basically allowing us to say "this div isn't meaningless, it is a search region". There is no way that this will break down for contributed themes in Drupal 8. A page can have 0 to many roles assigned, and provided that the roles used are used properly there are no problems

The only concern is if someone wants a pure xhtml 1.0 theme in Drupal 8. In that case they will need to override a lot of html5 themed functions and markup anyway, and to stop using a lot of contributed modules that rely on that markup. Basically I see it pretty unlikely / improbable that people will be using xhtml 1.0 in D8.

mgifford’s picture

Thanks Jeff. Definitely good to seek a consistent way to implement this.

@voxpelli - It might matter to validators that haven't kept up, but I don't see how having a few extra attributes will matter to users. If anything someone who uses AT will get a better experience. I certainly haven't heard people say that it's all or nothing with ARIA.

tstoeckler’s picture

FileSize
456 bytes

What really speaks against utilizing #attributes? It seems very sensible that the module declaring the block would know if and which role is to be applied.

I attached a sample patch for search module, which I tested locally.

Everett Zufelt’s picture

@tstoeckler

Your patch appears to be applying the attribute to the form, not the block. This isn't wrong, but it wouldn't be consistent with an approach where the role is applied to the container, rather than the contents.

I agree with Jeff that we need to implement this in a consistent way across Core, to make things easier for those adding ARIA to core, for those wishing to remove it in contrib, and for general ease of understanding the code in the future.

That is not to say that we * must * use preprocess functions, but it would seem like they have the advantage of:
1. Being easily used consistently.
2. The attributes added can easily be removed by later preprocess hooks.

Liam Morland’s picture

@#21, #22: A possible solution would be to have a installation or theme configuration boolean called use_aria (or whatever). Then drupal_attributes() can be patched so that it would remove any ARIA attributes if use_aris is false. I came up with this idea in #405360: Use aria-describedby to link form elements with form element descriptions#38.

Jeff Burnz’s picture

The HTML5 initiative is planning on having a theme in contrib that will fully support XHTML, so that theme could include overrides that remove roles.

Alternatively we could have an ARIA roles module, that is enabled by default?

Everett Zufelt’s picture

@Jeff

I am in favor of applying role and aria-* within the theming layer, and having a d8 core theme that overrides / removes the markup to be xhtml 1.0 valid.

This means that role and aria-* attrs * cannot * be applied outside of the theming layer in D8 Core.

I don't really see the benefit of a module, theme setting, or other on / off switch, other than that it would be easier to turn ARIA off. And, for the few edge cases where this is desired in D8 developers can deal with it themselves. By offering an easy out we are giving developers the option to say "I don't know what that is, I don't have disabled users, etc." and then disabling the module.

tstoeckler’s picture

The reason I find this easier for developers to implement e.g. in hook_block_view() rather than in e.g. template_preprocess_block() is because the specific role chosen has an intimate relationship with the data it surrounds, so as a developer it makes sense to specify the role right where the data is specified rather than in a theming hook which conceptually has (more or less) nothing to do with the actual data.

Jeff Burnz’s picture

Lets try to think though what our broader requirements are, that should lead us closer to an implementation - this is what I am thinking we need:

1. Roles are ON by default
2. They can be overridden easily (like classes)
3. They can be turned off easily (like RDFa)

This is what lead to me to the module idea and doing it in the theme layer - easy to override and you can just turn it off. I'm not pushing real hard for this, its just an idea that I can see would work (maybe you think differently).

tstoeckler’s picture

Well my approach would allow to override and remove the roles from e.g. template_preprocess_block(), so 2. would be fine.
I don't know if this is comparable to RDF module. The markup that is added is relatively leightweight; if I get it correctly maybe something like 10 attributes on a page would be realistic. That's why I'm not sure it makes sense to put this into a module.

Jeff Burnz’s picture

Sure, it would be like 10 on an average page, what I am thinking more of is XHTML validation, if site builders are locked into that as a client requirement and don't know anything about preprocess functions etc. I would assume the proposed "legacy theme" is going to have to remove these so it will be done there, maybe that's enough.

Everett Zufelt’s picture

Everett Zufelt’s picture

After adding ARIA roles to core blocks in #1183042: Regression: Add WAI-ARIA roles to Core blocks I am starting to ponder if it wouldn't be better logic to add the roles in hook_block_view, as @tstoeckler sugests.

1. This is easier to understand for developers.
2. The role is added when the block is generated.
3. hook_preprocess_block implementations have to be fired for every block, hook_block_view is only fired for blocks from that module (AFAIK).
4. The roles can still be overridden with a myTheme_preprocess(&$variables) {unset($variables['attributes_array']['role']);}

tstoeckler’s picture

I totally agree.

Just a note that #25 is correct in that using the patch in #24 the role is applied to the fom itself not to the container. That should doable, though.

Everett Zufelt’s picture

Is it possible to access attributes_array from hook_block_view(), or is that only available in preprocess?

Everett Zufelt’s picture

Component: theme system » markup
Everett Zufelt’s picture

Status: Active » Fixed

It is not possible to access attributes_array from hook_block_view() as it is generated in template_preprocess().

I think we have decided here to add in preprocess functions, I am sure there there may be tiny edge cases like role=main where the role needs to be applied to the region instead.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

tstoeckler’s picture

Status: Closed (fixed) » Needs review

Just wanted to point people to #1302482: Ensure render arrays properly handle #attributes and add them there instead of preprocess hooks, which would allow for exactly what was discussed here above. That doesn't mean we have to do it that way, but I still think #29 is a killer argument (hehe :)).

Status: Needs review » Needs work

The last submitted patch, search-role.patch, failed testing.

Everett Zufelt’s picture

Status: Needs work » Fixed
mgifford’s picture

Issue tags: +aria

Adding tag for WAI-ARIA.

Status: Fixed » Closed (fixed)
Issue tags: -Accessibility, -aria, -html5, -Front end

Automatically closed -- issue fixed for 2 weeks with no activity.