How to make a Select element accessible if it has no label? - javascript

I'm learning about accessibility in HTML and I came across an example of a Select dropdown HTML element, this element doesn't have any text label next to it, just the context of a title higher up the page gives an idea to what this element contains e.g. for example a list of countries on a section about countries.
When running an accessibility tool on it, the tool complains that there is no accessible name, I was wondering if there is a way to give this a name for a screen reader without having to add a label if that is not wanted as part of the design?

Short Answer
It isn't about what you want as part of your design, it is about what makes the page usable for as many people as possible. You should make the design work with a visible and properly associated label.
Longer Answer
There are ways we can add a label that isn't visible, one way being aria-label:
<select aria-label="label for the select">
</select>
Or we could use a visually hidden class on a <label> element so that it is still reachable by Assistive Tech (screen readers etc.) but does not show visually:
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<label for="select1" class="visually-hidden">Label Text</label>
<select id="select1">
<option>Option 1</option>
<option>Option 2</option>
</select>
But although that helps people using Assistive Tech (AT) such as a screen reader, it doesn't help everybody else.
What if someone has a learning difficulty and cannot associate the options in your select with the heading further up?
What if someone is using a screen magnifier and needs a label close to the control to know what it is for?
What if someone is using a custom style sheet that changes your layout and the association based on the layout doesn't work anymore?
So the answer is to add a <label> that is visible and properly associated to make it accessible and better for everybody.
The design should not suffer from a visible label (and if it does, your graphic designer / UI team need to up their game!) and it is likely to have the added bonus that people will feel like the form is easier to fill out, increasing conversions (as you reduce "friction").
So the best thing is to add a visible label:
<label for="select1">The label</label>
<select id="select1">
<option>Option 1</option>
<option>Option 2</option>
</select>
Note the use of an explicit label using for="IDofSelect", rather than an implicit label - where you wrap the <select> in a <label>, as implicit labels can cause problems with voice software such as Dragon Naturally Speaking

Related

Changing fontSize of * (everything) with JavaScript

In my project I want users to be able to zoom in on the webpage. But as the in-browser-zoom-function with JS isn't widely supported, I figured another way to zoom is to change the font-size: n%; as I have used rem units for everything size related.
If I change the font-size for * in css, everything else scales with the font-size. E.g.:
*{font-size: 110%;} Would be the same as changing browser-zoom to 110%.
Additionally, I would like to use a select > option to choose between 50% and 150%. That way I could utilize onchange="this.value"
How do I change the fontSize/font-size of * in CSS with Javascript?By * (CSS) I mean every element on the page, not just a div, form or id.
Edit:
As I used REM units on every element, all I needed to do was to change the fontSize of the root/<html> element. Here's the code I used for it to work out for me:
<html id="html">
----------------
<select onchange="document.getElementById('html').style.fontSize = this.value;">
<option value="125%">125%</option>
<option value="120%">120%</option>
<option value="115%">115%</option>
<option value="110%">110%</option>
<option value="105%">105%</option>
<option value="100%" selected>100%</option>
<option value="95%">95%</option>
<option value="90%">90%</option>
<option value="85%">85%</option>
<option value="80%">80%</option>
<option value="75%">75%</option>
</select>
Please don't do this!
As this is marked accessibility I cannot recommend doing exactly what you suggested.
Offering users the option to increase font size - massive bonus points.
Scaling everything on the page by an equal amount - massive no no.
The big problem with this is that the page will grow in width as you increase font size.
This will result in horizontal scrolling as well as vertical scrolling which is a big no no!
Why does it matter?
The people most likely to increase your font size are also likely to be the people who rely on a screen magnifier.
Scrolling in both directions is a nightmare for Screen Magnifier users, as part of a sentence may be off the screen.
It is also a bad experience for people with dyslexia etc.
They often struggle with making sure they don't skip a line, having to scroll side to side while reading makes this problem 100 times worse.
Why does browser zoom work for accessibility then?
The difference between increasing the size of everything and using the browser zoom is that when you zoom your browser it also calculates the effective width of the page in CSS pixels.
So if you zoom a 1920px wide screen 200% it exposes the width as 960px, which will trigger any media queries designed for a tablet view (for example) and adjust your styles accordingly.
What should you do?
As I said at the beginning, letting people change their font size - big bonus points!
However what you should do instead of scaling everything is that you should make sure all containers on the page can accept your larger font size and define all fonts in em or rem.
This way all you need to do is change the <HTML> font size and every single font on the page will scale by the same amount.
It will also obey user font size settings if you set your HTML units as percentages.
In the following example all you would do is change the HTML from 100% to 150% and all font sizes would increase without affecting container sizes etc.
The below example also illustrates what happens if you increase your font size and a container does not allow enough space at 150% font size.
Also try the below example with your browser font size set to maximum and you will see the text scales without affecting the container size.
Font size 100% example
html{
font-size: 100%;
}
h1{
font-size: 3rem;
}
p{
font-size: 1rem;
}
.container{
width: 33%;
background-color: #ddd;
overflow: hidden;
}
<div class="container">
<h1>Heading</h1>
<p>text</p>
</div>
font size 150% example
html{
font-size: 150%;
}
h1{
font-size: 3rem;
}
p{
font-size: 1rem;
}
.container{
width: 33%;
background-color: #ddd;
overflow: hidden;
}
<div class="container">
<h1>Heading</h1>
<p>text</p>
</div>
Don't define containers in the same units (as a general rule) so that they do not scale beyond the bounds of the page.
If you do this you will make the page far more accessible without introducing issues that actually reduce the accessibility of the page by forcing users to scroll in two directions.
Set form-elements font or font-size to inherit (in order to override browser defaults)
If your elements have relative font-size, all it takes is to control the font-size of body element
Stop using inline JS. Use Element.addEventListener() instead. It's easier to debug JS when you're not using it withing HTML tags.
document.querySelector("#fontSize").addEventListener("input", function() {
document.body.style.fontSize = this.value +"%";
});
h1 {
font-size: 4em; /* Demo */
}
input,
textarea,
button {
font: inherit; /* override browser defaults */
}
<label><input id="fontSize" type="range" min="10" max="2000" step="1" value="100"></label>
<h1>H1 title</h1>
<p>Lorem ut florem</p>
<blockquote>
blockquote
</blockquote>
<form>
<input type="text" value="Lorem ut florem">
<button type="button">Button</button>
</form>

Changing Line color on focus inside input or textarea

I've come across a lot of online editors (for ex. dillinger), where, when the user clicks inside the textarea, the line which has focus changes color. I'm curious to know how stuff works here. Not just the line color but any styling which is possible in an editor's editing portion, I'm completely unaware of it. I came across the concept of zebra striping while googling about it, but I don't think it has anything to do with editable portions where a single line has to be focused dynamically.
It seems achievable though, but how?
PS: Please don't provide any existing tool/utility to achieve this. I prefer reinventing the wheel. If it is not an easy road, at least provide the best to your knowledge.
Thanks in advance.
This is a textarea, but it has many divs underneath it (i.e. a lower z-index) to style it in a particular way. More specifically this is an Ace editor so they may detail some of their effects in the documentation.
For example, if you inspect the source of that page you will find the class ace_active-line which you can see is a div that is located underneath the textarea. The textarea has a transparent background which is why you're able to see the div underneath.
Most simply put this is achieved through the utilization of CSS selectors, in specific :focus.
Even with layered divs and other accompanying elements, you can style these divs when the topmost div is in focus, for instance:
input div.inner-input {
border: 1px black;
}
input:focus div.inner-input {
border: 1px orange;
}
This can also be further achieved through jQuery to edit another div's class or attributes when an input comes into focus.
input.onFocus() {
$('.under-div').addClass('active-line');
}
Well, if you want to reinvent the wheel, you'll need to build the roads to use the wheels on too.
In this case you cannot be working in a textarea (as mentioned in the tags). Instead, the rendering of the editor will be all yours.
One of the approaches would be:
Create a <div> container for the area where the text will entered.
Create another <div> inside the first one. This will be our overlay. Make sure that it has a low z-index. Let's say it's z-index: 1.
Create a third <div> container under the first one. This will be the actual text editor. It has to have transparent background and a higher z-index.
Put a <div> inside the container #2. It's going to be our row highlighter.
For every line in the editor you'll need to render its own <div>, with a <span> inside of it for text. Yup, a lot of custom code: you'll need to write proper functions to push new <div> when user hits Enter to start a new line and so on and so forth.
You'll also need to make sure that the height of these row-div's is fixed to a certain minimum value (up to you to figure out the value and the formula behind the calculation, probably something based on the window height, maybe user preferences or font size). It can grow though, for example when user has word wrapping enabled.
When all of it is done the real magic can begin: highlighting. Let's imagine we have a three-line document loaded. It will look like this:
<div id="textContainer">
<div id="overlay" style="z-index: 1">
<div id="highlighter" style="background: yellow; display: block;">
</div>
</div>
<div id="textEditor" style="background: transparent; z-index: 100;">
<div>
<span>Line 1</span>
</div>
<div>
<span>Line 2</span>
</div>
<div>
<span>Line 2</span>
</div>
</div>
</div>
Now you can determine the exact position and width of the textContainer on the screen: it's required to easily (and with little performance overhead) handle different screen/window sizes.
When user focuses on a certain row you'll need to run some JavaScript which grabs the current top and height values of the row (<div>) the user focused on and sets the <div id="highlighter"> location and height to be the same.
Use css focus function to change the outline color when focus on input box.
input[type=text]:focus, textarea:focus {
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
padding: 3px 0px 3px 3px;
margin: 5px 1px 3px 0px;
border: 1px solid rgba(81, 203, 238, 1);
}
Working fiddle : https://jsfiddle.net/gwLgckvf/

HtmlService - Suppress Firefox arrow in select element

Edit: This question is already different from the one that was voted duplicate, How to remove the arrow from a select element in Firefox. That question was referenced in the question from the start - before trying to get your daily limit of close votes, please read the question.
I'm using the HtmlService of Google Apps Script to display an HTML form, including jQuery and javascript. Using the recommended stylesheet for Google Doc add-ons, this is how a select box appears in Chrome:
Here's the same thing, in Firefox. Note the extra superimposed arrow.
How can I get rid of that overlay in Firefox?
I've tried the techniques described in How to remove the arrow from a select element in Firefox, but the accepted and highest voted answers stopped working in more recent versions of FF, and didn't work for me. Other solutions involving overflowing the select and hiding the overflow with an enclosing div are interesting, but since they also eliminate the desired "up/down" arrows, they aren't acceptable for this application.
HTML
<div class="block form-group">
<label for="my-selection">Select an option:</label>
<select class="width-100" id="my-selection">
<option value="Option 1"></option>
<option value="Option 2"></option>
<option value="Option 3"></option>
</select>
</div>
CSS
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<!-- The CSS package above applies Google styling to buttons and other elements. -->
<style>
.width-100 {
width: 100%;
}
select {
height: 31px;
}
</style>
I tried your code in Firefox v37.0.1 and it looks exactly the same as Chrome and Safari (no extra arrow). Maybe google updated their css file?
Other solutions involving overflowing the select and hiding the overflow with an enclosing div are interesting, but since they also eliminate the desired "up/down" arrows, they aren't acceptable for this application.
You just need to re-implement the up/down arrows. I think you can manage two triangles. In my experience, this is the only reliable solution to this problem.
Try,
select {
-moz-appearance: none;
text-indent: 0.01px;
text-overflow: '';
}
You may use above. However this trick is reported to be not working somewhere between Firefox v30 - Firefox v35.
For firefox v30 wise, below seems to be working according to the source.
You may throw javascript agent to find browser source to act accordingly.
(window.navigator.userAgent)
.styled-select {
overflow: hidden;
width: 200px;
}
#-moz-document url-prefix(){
.styled-select select { width: 110%; }
}
Follow this Github link for further reference.
https://gist.github.com/joaocunha/6273016

Styling a select box with a size attribute?

For the life of me I can't figure out how to style a select box that uses the size attribute. Almost all of the tutorials out there are for a single-item select box. Does anybody have any experience with select boxes that use the size attribute?
For reference, this is what I'm talking about:
<select class="awesome_select" size="5">
<option>1</option>
<option>2</option>
</select>
I'm developing on Chrome/Safari/Firefox for Mac. I have tried the -moz-appearance: none; and -webkit-appeareance: none; properties for both the select box and the individual options. I have also tried setting a border on the select and the options.
I am able to style the select box in the sense that I can resize it, move it around, and change the font size, but I am completely unable to style the individual options.
edit 1 Here's an example of what I want to do:
select.awesome_select {
border: 1px solid #ACADAC;
padding: 0;
outline: none;
-webkit-appeareance: none;
}
select.awesome_select option {
padding: 5px;
background-color: #FF0000;
-webkit-appearance: none;
}
If I have a regular select (without using the size attribute) I can style this however I'd like. WITH the size attribute, the options suddenly are not able to be modified in any way.
Since you're open to use jQuery and since original SELECT doesn't suit your need, I suggest using Selectable from jQueryUI
If this doesn't suit you, Google for others, but search for "listbox" (e.g. "jQuery listbox), you will find alternatives like http://kalnitsky.org/projects/listbox.js/en/.
Most of them won't convert your existing SELECT element into a new one, but there're some that would.
give a class to the select element and do your css there.
<select class="classname" size="5">
<option>1</option>
<option>2</option>
</select>
//css
.classname {width:0;
height:0;
background:# ;//etc }

Styling HTML FORM elements with padding, with width 100%

I'm styling a form by using a table with fixed-width columns and I want the input elements inside the <td> to fill the container. I know the CSS box model and I know the elements would bleed through with width: 100%, but the problem is with its consistency.
<input> elements bleed through as expected but <select> elements don’t. This results in making my fields not line up properly. I've tried all properties like overflow, display, whitespace... it doesn’t make any difference. What’s with the <select> element? I can see in Firebug that they have the same box model properties with the input element, but they don’t render the same.
I’m using HTML 5 doctype and this happens both in Firefox and Chrome.
Right now, I’m fixing this using a JS function which selects all elements with class stretch and computes and sets the static width to make it fit inside the container. This perfectly lines up the elements of the form. (I had to exclude <select> elements because their widths were already okay... weird quirk.)
Is there a pure CSS solution to this? I wouldn’t want to run this function everytime a part of the page is updated, like on AJAX calls...
You could use box-sizing: border-box; on textfields and textarea's.
It solves te difference with the selectbox.
The best way is to fake the borders of the elements with a div.
<div class="formholder>
<textarea></textarea>
</div>
With this CSS:
.formholder {padding:10px;background:white;border:1px solid #ccc}
.formholder textarea {width:100%;padding:0;margin:0;background:white;border:0}
Of course, you can expand that for other fields. Some browsers might give you issues. Chrome and webkit allow you to resize textareas but if you add resize: none; to your CSS, it should disable it but YMMV.
It may help you to know the following results from various usability studies.
1) For most forms, people prefer to see the label just above the form element:
2) People find it useful if the form elements are sized appropriately to help suggest how much information is expected.
<ul>
<li><label for="firstname">First Name</label><br>
<input type="text" id="firstname" name="firstname" size="15"></li>
<li><label for="age">Age</label><br>
<input type="text" id="age" name="age" size="3"></li>
<!-- ... more list items -->
</ul>
Note: the list in this example would be styled so that it doesn't appear as a bullet-point list. Using lists in this way helps with accessibility as screen readers will tell the user how many items are contained in the list.
I thought this might be useful as it suggests that your efforts may be a bit wasted trying to layout the form in a table and stretch all inputs to the same length.
http://dev.w3.org/html5/markup/input.html#input
Not the most helpful answer, but CSS styling of form elements is pretty unreliable between browsers. A JavaScript solution like yours is the best bet.
Two reasons for the unreliability:
Some features of form elements can’t be described by CSS. The <select> element is a good example: there aren’t any CSS properties that can describe the different ways a <select> element looks on different operating systems.
Trying to work out which CSS properties should affect form elements, and how, is a rat’s nest for browser makers, so they’ve mostly left it alone. Safari is a notable exception; see e.g. http://webkit.org/blog/17/the-new-form-controls-checkbox-2/
You can argue that form elements should look the same between sites regardless of the site owners’ intentions, so that users know what they’re clicking on.
See http://meyerweb.com/eric/thoughts/2007/05/15/formal-weirdness/ for a deeper examination.
Say your html looks somewhat like this:
<form><table><tr>
<td><input type="text" /></td>
<td><select><option /><option /></select></td>
</tr></table></form>
How about just using the input and select for setting the width?
td { width: auto; }
input[type=text] { width: 100px; }
select { width: 100px; }
Or did I get your problem wrong?
The following CSS works for Moz Firefox, for html input elements (submit, button, text), textarea elements, and even select elements. The select elements are nearly equal length in the browser I'm trying.
table {width:100%;}
form input { width: 100%; }
form textarea { width: 100%; overflow-y: scroll; resize: vertical; }
form select { width: 100%; }

Categories

Resources