How to implement ARIA on a responsive site - responsive-design

We are working to make one of our responsive sites more accessible, but are struggling to get our heads around ARIA as it seems to go against the core principle of separating design elements from the HTML.
For example if an element is hidden in aria one would indicate it as aria-hidden="true". However most visibility is determined by media queries depending on screen size etc.
In other cases elements work completely different based on media queries. So at some sizes aria-haspopup="true" would be appropriate while on other resolutions the navigation is always visible.
Am I missing something, or are we at font tags all over again with this standard? Are we supposed to add / remove aria tags using javascript as appropriate?

Actually Kenneth, your question makes a lot of sense, and, yes - tooling for responsive sites is not ideal. I don't have an answer for you, but what I have to say is too long to be a comment...
Consider the following example:
You app has a menu button that opens a side drawer using a short sliding animation. Without a11y considerations, your job is easy (lets assume the drawer is on the left and has a width of 250px):
#media ... (min-width: 1000px)
#drawer {
left: 0;
}
#media ... (max-width: 999px)
#drawer {
left: -250px;
}
#drawer.opened {
left: 0;
}
(Not an exact syntax, add your own wizardy for the sliding animation)
To make this accessible, you'd have to do one of the following:
option 1
Don't use aria-hidden='true'. It's generally enough to hide the drawer using visibility:hidden or display:none. Of course, now you need to wait for the end of the sliding out animation to hide the drawer (or you
lose the animation).
option 2
Use aria-hidden='true'. You'll have to catch window resize and add / remove aria-hidden='true' when switching sizes (you lose the media query magic).
To sum things up, you're right. There's definitely room for improvement. This is especially true, considering the general shift to move stuff off of JS to keep things 60fps smooth.

You have to use the window.matchMedia function
For instance:
var mm = window.matchMedia("(min-width: 600px)");
mm.addListener(updateAriaHidden);
updateAriaHidden(mm);
var updateAriaHidden= function (obj) {
if (obj.matches) {
// set aria-hidden true/false when width >= 600px
}
else {
// set aria-hidden true/false when width < 600px
}
}
Using jQuery for instance, you can use the :hidden selector with a custom CSS class to set the aria-hidden attribute dynamically:
$(".toggleable:hidden').attr('aria-hidden', true);
$(".toggleable:visible').attr('aria-hidden', false);
The use of the custom class make it easy to match the elements which would change based on your media queries

Related

ID is being applied to the a element generated by React Bootstrap, not the encompassing div

So, previously I was using the 'ml-auto' class for my navbar, for my dropdown to push itself all the way over to the left. However, I don't want it to push itself all the way to the left when it goes into a small screen, and the navbar changes into a vertical orientation.
I tried giving my NavDropdown the following class and ID:
className={styles.naviDropdown}
id='navigationDropdown'
and apply the following style to it
.naviDropdown#navigationDropdown {
margin-left: auto !important;
}
#media (max-width: 768px) {
.naviDropdown#navigationDropdown {
margin-left: 0 !important;
}
}
So, this seems like it would work perfectly well, but unfortunately, it does not. Doing this makes the website completely disregard any of the CSS, and makes my navbar look all wacky and evenly spaced, as opposed to justifying my links left, and navbar right.
I've found out, through the inspector, that for some reason, the id is being applied to the a element generated by React Bootstrap, not the encompassing div, which is given the proper class.
Any ideas what might be going on?
Any help would be much appreciated, and let me know if I need to provide more info!
Edit:
I tried reformatting my code in the ways specified within this Github discussion, and unfortunately, my issue still remains the same--the ID is assigned to the 'a' element, rather than the dropdown div.
Looks like all i needed to do was surround the dropdown element with a 'div' element and then apply the id to that. There might be some deeper issue at play here, but this fixed my issue.

In Bigcommerce's Stencil, how do i make an object show/hide via responsive classes?

I'm familiar with Bootstrap and how to make it show/hide objects via responsive classes. However, Stencil appears to use it's own class names, and I'm unable to find reference to them. I have found some Stencil documentation, but I can't find this in it.
I'm using the theme Exhibit and found in the sidebar code that I can make an object appear in the drawer on small screens by declaring class="drawer-item drawer-extras". I can't find what is needed to make an object disappear from the sidebar, so that it is not in the drawer on small screens.
You can add css to hide or transform these items by saying something like
#media (max-width 768px) {
.drawer-item {
display: none;
}
}
For information on nesting these media queries, you can check Using multiple #media (max-width) CSS

no scrollbars in options popup ported from Chrome in firefox webextension

I'm porting chrome extension to Firefox and I'm testing on Nightly 51a.. version.
When I click the popup options icons it opens and scrollbars appear and after half a second those disappear.
How to correct this?
At the moment I've given a hyperlink in the top in the optins popup with this code which when clicked opens full view html in a new tab and this works just fine:
<a style="font-size:1.5em;" href="options.html" target="_blank">Open Full Window</a>
The popup that is being shown for a browser_action is, currently, being set to a maximum of 800x600 pixels (at least in my testing). However, your content is being rendered at a much larger size while having the scroll bars not shown to the user (either not rendered at all, or positioned outside of the view into the document provided by the panel).
There are multiple ways to solve this. However, I was not able to find one that did not result in specifying an explicit height and width for the <body>, or a sub element (e.g. a <div> enclosing all content). Several ways showed the scroll bars, but left them disabled.
The simplest way to get the scroll bars to show up, is to change your HTML from:
<body>
to:
<body style="height:580px;width:800px;">
Obviously, you could also change this in your CSS (banks/options.css). From:
body{
min-width:500px;
min-height: 500px;
}
To:
body{
height: 580px;
width: 800px;
min-width: 500px;
min-height: 500px;
}
However, neither of those allow for the possibility that the panel will be shown with different dimensions (e.g. on other sized screens, or if Firefox changes what it is doing).
Thus, my prefered solution is to use JavaScript. In options.js add something like:
function setBodyHeightWidth(){
let width=window.innerWidth;
let height=window.innerHeight;
height -= 20; //Adjust for Save button and horizontal scroll bar
//document.body.style.width=width; //Does not work
//document.body.style.height=height; //Does not work
document.body.setAttribute('style','height:' + height + 'px;width:' + width + 'px;');
}
function onDOMLoaded(){
setBodyHeightWidth();
//Anything else you need to do here.
}
document.addEventListener('DOMContentLoaded', onDOMLoaded);
Using a significantly trimmed down version of the code for your extension (i.e. I removed all your JavaScript, and most of the non-visible HTML), the above code makes it look like:

ExtJS 4.2 render components bigger than body for printing

I am creating a reporting system and i am having a bit trouble with my printing functionallity.
My plan was to place a div in my body element in the index.html
<div class="print" id="printcontainer"></div>
with the following css
#printcontainer{
z-index: -50;
position: absolute;
top: 0;
left: 0;
overflow: visible;
}
Then on print i'll render all report panels in my printcontainer somthing like this:
for (var reportCfg in reports) {
reportCfg.renderTo = 'printcontainer';
createReportPanel(reportCfg);
}
so far so good. If the Browser window is big enough it all works fine. But on a small screen or if you make your browser window smaller the panels are not rendered big enough and the reports are cropped. It only renders the width which the body element has. which is the size of the browser window.
I know i could just add a width to my reportCfg (so my panel gets a fixed width). The problem is these reports all could have different widths depending on their columns.
Is there a solution i could render them bigger than the body width ???
For now i came up with the following hack though im not very happy about it.
I am overwriting the afterRender fn of my report panel and then i check if the grid header has a bigger scrollwidth than the width of the panel.
afterRender: function() {
this.callParent(arguments);
//hack for printing page so panel gets rendered big enough
if (this is panel for printing) {
Ext.resumeLayouts(true);
var header = this.down('[id^="gridpanel"] [id^="headercontainer"]');
if (header && header.el.dom.scrollWidth > this.getWidth()) {
this.setWidth(header.el.dom.scrollWidth);
}
}
},
Is there a better solution to accomplish such a thing? Imo there must be a better solution.
If you need more information, dont hesitate to ask.

Prevent fitVids from englarging videos

I have fitVids working on my site. However, I'm wondering if it is possible to prevent fitVids from enlarging a video beyond its defined height/width. For example, if a video is 600px wide, but the container is 800px, fitVids enlarges the video to 800px wide and it is blurry. I'd only like fitVids to shrink the video when the container shrinks for smaller devices. Is that possible?
jQuery(document).ready(function(){
// Target your .container, .wrapper, .post, etc.
$("#thing-with-videos").fitVids();
});
helgatheviking's solution constrains the width of the video, but not the height. If your container is wider than the video, you end up with a really tall, letter-boxed video. The height is easy to fix, using the same technique to constrain the width. But, there's a third variable.
fitVids wraps the iframe in a div, with the class "fluid-width-video-wrapper", and sets padding-top equal to the aspect ratio of the video. Even if height and width are constrained, the fluid-width-video-wrapper will still be as tall as the video could be, if it didn't have a max-height. So, you end up with a bunch of white-space below the video.
Rather than set all three values (width, height, and padding), you can simplify everything by wrapping the iframe in a div with a max-width, before initializing fitvids.
var vidFrame = $('#fitvids_container').find('iframe');
var vidWidth = vidFrame.attr('width');
if (typeof vidWidth !== undefined) {
// Wrap the iframe in a Div with max-width defined
vidFrame.wrap('<div style="max-width:' + vidWidth + 'px;"></div>');
}
// Initialize fitVids
$('#fitvids_container').fitVids();
Like helgatheviking's solution, if you have more than one video per page, you'll have to calculate the max-width for each video.
One option is to make a small modification to the fitvids code which checks for a data-maxwidth attribute and if found wraps a div with a max-width style to limit the resized iframe.
This allows each videos max width behaviour to be specified independently.
For example. Add the data-maxwidth attribute to the iframe.
<iframe width="560" height="315" data-maxwidth="560" src="https://www.youtube.com/embed/L-UIiRlydow" frameborder="0" allowfullscreen=""></iframe>
Then add the following code snippet to the fitvids.js file, at the end of the $allVideos.each function, just after $this.removeAttr('height').removeAttr('width');
if ($this.data("maxwidth"))
$this.parent('.fluid-width-video-wrapper').wrap('<div></div>').parent().css('max-width', $this.data("maxwidth"));
It simple!
Assuming "thing-with-videos" is the ID of the wrapper on which you are calling .fitvids()
So just set the max width css property for this container.
Example:
#thing-with-videos {
max-width: 600px;
margin: 0px auto;
}
This wont let your video width go beyond 600px. Margin property will center your video container.
Live Edit Demo -
http://bitconfig.com/fit-vids/bitconfig_fitvids.html
Set your custom width in the "Video container width" textbox and watch the preview!
-Patrick
Patrick's answer eventually made me realize that I could put a max-width on the iframe itself.
#fitvids_container {
max-width: 600px;
}
#fitvids_container iframe {
max-width: 500px;
}
However, if you were using a lot of videos (of different sizes), you might want to do this dynamically. With jQuery we can get the width from the iframe attribute and make it a max-width style rule. This only works if you've included the width attribute in your embed code though. This is a single example, but could be adapted to an .each() loop or at least renaming the container div to a class.
var width = $('#fitvids_container').find('iframe').attr('width');
if (typeof width !== undefined) {
$('#fitvids_container').find('iframe').css('maxWidth', width + 'px');
}
See my example: http://jsfiddle.net/Qd4FW/2/

Resources