Screenreaders will read whatever string is set to the "alt" attribute. The use of this attribute is specifically for image tags.
If I have a div like so:
<div id=myCoolDiv tabindex="0"> 2 <div>
Is there a way to have a screen reader pickup an attribute to read a string the same way an alt tag is used?
So for the div listed below, the screen reader will say ie: "shopping cart items 2"?
I tried using aria-label but the screenreader won't pick it up:
<div id=myCoolDiv tabindex="0" aria-label="shopping cart items"> 2 <div>
You can just put a title tag in the div which will do the same as an alt tag like so:
<div title="I AM HELLO WORLD">HELLO WORLD</div>
"I AM HELLO WORLD" will be printed once you move your cursor around it on a browser
There are two ways (which can be combined) to have screen reader to read alternative text:
Anything with ARIA role img can (MUST) have alt attribute. See WAI-ARIA img role.
<div role="img" alt="heart">
♥︎
</div>
UPDATE: In 2017 the WAI-ARIA document was changed and the following text does not apply anymore. See comments below.
However this should be used only in case the element really represent an image (e.g. the heart unicode character).
If an element contain actual text, that just need different reading, you should set ARIA role to text and add aria-label with whatever you want to be read by the screen reader. See WAI-ARIA text role.
<div role="text" aria-label="Rating: 60%">
Rating: ★★★☆☆︎
</div>
Do not mismatch it with aria-labeledby which should contain ID of an related element.
You can combine the previous two cases into one using two ARIA roles and adding both alt and aria-label:
<div role="img text" alt="heart" aria-label="heart">
♥︎
</div>
When more ARIA roles are defined, browser should use the first one that is supported and process the element with that role.
One last important thing is that you must set page type to HTML5 (which support ARIA by design).
<!DOCTYPE html>
Using HTML4 or XHTML requires special DTD to enable ARIA support.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+ARIA 1.0//EN"
"http://www.w3.org/WAI/ARIA/schemata/xhtml-aria-1.dtd">
Try role="listitem" or role="group" and aria-labelledby="shopping cart items". See Example 1. The 2 is text content which should be read by screen reader already with the attribute read as context to the content. Refer to this section.
UPDATE 2
Add aria-readonly=true role=textbox if you use an input. If there are doubts whether to use aria-label or aria-labelledby, read this article. In the documentation for JAWS and testing it myself supports the fact that aria-label is ignored. Furthermore, semantics are very important when accessibility is your concern. Using a div when you could use an input is not semantically sound and like I said before, JAWS would accept a form element more readily than a div. I assume that this "shopping cart" is a form or part of a form, and if you don't like it's borders, input {border: 0 none transparent} or use <output>* which would be A+ as far as semantics are concerned.
Sorry, #RadekPech reminded me; I forgot to add that using aria-labelledby needs visible text and that the text needs an id which is also listed as the value(s) of aria-labelledby. If you don't want text because of aesthetics, use color: transparent, line-height: 0, or color:<same as background>. That should satisfy visibility as far as the DOM is concerned* and still be invisible to the naked eye. Keep in mind these measures are because JAWS ignores aria-label.
*untested
EXAMPLE 3
<span id="shopping">Shopping</span>
<span id="cart">Cart</span>
<span id="items">Items</span>
<input id='cart' tabindex="0" aria-readonly=true readonly role="textbox" aria-labelledby="shopping cart items" value='2'>
UPDATE 1
For JAWS, you probably have to configure it a little:
Click the Utilities menu item.
Then Settings Center.
Speech and Sounds Schemes
Modiy Scheme...
HTML Tab
In this particular dialog box, you can add specific attributes and what is said when an element is tabbed to. JAWS will respond to form elements easier because they can trigger the focus event. You'll have an easier time doing Example 2 instead:
EXAMPLE 1
<div id=myCoolDiv tabindex="0" role="listitem" aria-labelledby="shopping cart items"> 2 <div>
EXAMPLE 2
<input id='semantic' tabindex="0" role="listitem" aria-labelledby="shopping cart items" value='2' readonly>
In case you use Bootstrap Framework there is a quick and easy solution. You should use sr-only or sr-only sr-only-focusable Bootstrap's CSS classes in a span element where your screen-reader-only text will be written.
Check the following example, a span element with class glyphicon glyphicon-shopping-cart is also used as cart icon.
<div id="myCoolDiv">
<h5>
<span class="glyphicon glyphicon-shopping-cart"></span> 2
<span class="sr-only sr-only-focusable" tabindex="0">shopping cart items</span>
</h5>
<div>
Screen Reader Output: "two shopping cart items"
provided by Fangs Screen Reader Emulator Addon for Firefox
You can find the above working example in this: Fiddle
As suggested by Oriol, in case you don't use Bootstrap Framework then simply add the following in your CSS file.
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}
According to the text alternative computation algorithm of the W3C and the
Accessible Name and Description: Computation and API Mappings 1.1 you definitely should use aria-label.
That being said, it does not work with Jaws. Text alternative is only computed for elements having an ARIA role.
The remaining option is to use a link that will go to your cart page, using both title and aria-label to satisfy anyone:
2
You can also use a transparent 1 pixel option:
2 <img src="pixel.png" height="1" width="1" alt="shopping cart items" />
No, there is no equivalent to an alt attribute for <div> elements.
For what you are trying to do, an ARIA-based solution is overkill. Not only are you bumping into screen reader compatibility problems, you are applying ARIA attributes where they are not needed (and arguably do not belong if on something like a <div>).
Instead, consider using an off-screen technique (such as this one from The Paciello Group or this one from WebAIM). Content hidden using this technique will still be read by screen readers but will be visually hidden.
From reading your question, I think this is what you are after.
I made a pen demonstrating this technique. It may be easier to test in the full-page version.
Edit: Added HTML and CSS from the example, but please note that both the specs and browser / assistive technology support change over time, so if you are reading this in a year you should continue to use the links above to verify this CSS is still the current best practice.
HTML
<div tabindex="0">
<span class="offscreen">Items in shopping cart: </span>2
</div>
CSS
.offscreen {
position: absolute;
clip: rect(1px 1px 1px 1px);
/* for Internet Explorer */
clip: rect(1px, 1px, 1px, 1px);
padding: 0;
border: 0;
height: 1px;
width: 1px;
overflow: hidden;
}
Accessibility (Screen readers) can be achieved through role and aria-label tags on div. This can be very useful while using svg.
<div role="img" aria-label="I can speak the text">
<svg>...</svg>
</div>
Try:
HTML
<div id=myCoolDiv tabindex="0"><span class="aria-hidden">shopping cart items</span>2<div>
CSS
.aria-hidden {
position: absolute;
left: -100000px;
}
This will announce the text inside the span. And the Parent div will not lose visual focus. Aria-hidden class will hide the span from the visible screen area but will read it as its inside the div that has focus.
You can create a class such as screen-reader-text with the following css:
.screen-reader-text {
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
width: 1px;
overflow: hidden;
position: absolute !important;
}
Then, in your code, you can just add a <span> with the screenreader text as so:
<div>
I am a div!
<span class="screen-reader-text">This is my screen reader text</span>
</div>
See an example over here: https://jsfiddle.net/zj1zuk9y/
(Source: http://www.coolfields.co.uk/2016/05/text-for-screen-readers-only-updated/)
Use an image inside the div that has the label as its alt attribute. That way, those without screen readers just see the number and an image, whereas those with readers will hear the whole sentence:
<div>
<img src="http://tny.im/57j" alt="Shopping cart items" />
2
</div>
Seen as:
2
Read as: "Shopping cart items: 2"
The alt attribute exists for images because there is no way to "read aloud" the content of the image, so the provided text is used instead. But for the div, it already contains text and images. Therefore, if you want it to be read by a screen-reader, you need to include the text and alt text in the content of the div.
I have a page of text and it is formatted similar to this
<div class="container">
<p style="text-align: center;">
<span style="text-decoration: underline;">
<strong>
<img src="//cdn.shopify.com/s/files/1/0652/9219/files/Horizontal.jpg?13817493546805475501" alt="">
</strong>
</span>
</p>
<p style="text-align: center;">
<span style="text-decoration: underline;">
<strong>The Hosting</strong>
</span>
</p>
<p>
The in-laws are arriving, friends are in town, and everyone is heading to your abode for a night filled with holiday cheer. As stress levels tend to rise during these events, expenses do as well. Here are a few tips to nail your hostess game, without breaking the bank and <em>still</em> shopping consciously.
</p>
</div>
I am looking to keep the images which fit the entire content width of the class container the same but only change the text within the paragraph tags to either be a smaller width (so it looks indented on both sides) or have margins but not affect the images at all. I cannot change how the code is outputted so the images will always be wrapped in paragraph tags.
This code is a small sample on the page of content and there are several images and text throughout.
So basically I am looking for a way in css to style only the actual text within the paragraph tags and leave the images unchanged. Any help would be great.
Here is a fiddle example: https://jsfiddle.net/jpautt8v/
If your html is static or if you know which child you want to modify then you could simply use the nth child css selector to apply css like below 3rd in your sample code case. You could play around margins and see what works best for your solution.
p:nth-child(3)
{
margin: 0 50px;
}
Without changing any of the existing markup, you can accomplish what you want using negative margin.
Something like this will work:
img {
width: 120%; max-width: 120%;
margin: 0 -10%;
}
.content > div, .content > p {
margin: 0 10%;
}
You can see it working in this fiddle: https://jsfiddle.net/igor_9000/jpautt8v/1/
Using this plugin works great, but when I stop the scroll fixed position, it creates the following div.
<div style="display: block; width: 1621px; height: 104px; float: none;"></div>
The dimensions resemble to size of the div being scrolled.
Example: http://litl.it/ simply scroll past the maps area, then scroll back up and there will be an odd blank space.
Anyone know how to remove this issue? I've found one other example that has been closed, but the issue was resolved with a work around creating extra containers, with additional css to comply with the 'random' div created. I'd like to avoid that if possible.
code:
<section id="devices" data-speed="10" data-type="background">
<h1>litl.it now, bookmark it for later</h1>
<p>we provides an easy link shortening solution with better features above the competition, you can now shorten & bookmark your links with control.
</section>
<section id="demographic" data-speed="7" data-type="background">
</section>
<div id="mapoverlay">
<div class="mapcontainer">
<h1>litl.it it records data of your audience</h1>
<p>here you can see litl.it users litling links across the world!</p>
</div>
</div>
<section id="trackstats" data-speed="4" data-type="background">
<h1>Tracking Stats</h1>
</section>
This issue occurs in the Windows Chrome browser (based upon additional comments from users), here is an example:
Edit: it occurs for me in all browsers, maybe the issue is due to the window being too large, resulting in the bottom of the page preventing the scroll from passing over the target div.
Can I please ask you to attempt creating the issue with a small window to ensure the scrolling div passes over the tracking stats box.
First of all i'm new at scripting and need your help. I'm trying to achieve the following:
I have four projects i want to show on my website. These projects are visable by images. When people hover over the image a div called "info" will show the additional information of the project they hover on.
So to be clear, data which will be triggered by hovering goes to the same div "info":
Hover over image 1 -> load information of project 1 to -> div "info"
Hover over image 2 -> load information of project 2 to -> div "info"
etc.
A friend told me to use ajax and xml, is that a good combination?
Thanks for the help
You are right that a good way to load content dynamically on a page is to use Javascript and XML. A great way to get into using JavaScript is to load a library to help you operate on the contents of an HTML page. I definitely recommend JQuery.
I would highly recommend not loading the information from separate files, unless the content is a whole bunch of very large images.
Take look at this video: JQuery for Designers they do some really great videos that helped me understand JQuery when I was first starting. The page that I just linked to has some great techniques for switching content into the same place, and will give you some important UX (user experience) tips as well.
Ajax is the best choice to get the data....
But the variations comes at what type of Data...
if you need values from database JSON would be my choice
or
never mind any data can be smoothly framed
if you dont have too much hand on scripting
Just use Jquery Plugins to retrieve data using simple calls
Fancybox plugin CLICK HERE...
and the GUIDE to how to use
GUIDE TO USE FANCYBOX CLICK HERE.....
Thank you all for the response.
I solved the problem temporarily by using the technique given by Mark, using html and css. But, i think using javascript could make things easier and more organised. My knowledge about scripting is not good enough. I posted my html for others underneath.
I still have the question how to use the id of a image as a parameter for retrieving a specific part of information. For example: i have an image with id=img1 and a xml file containing with sub parameters. So when i hover over the image js gets the id of that image and then loads the specific part of the xml onto the "info"div and not the whole xml. (to answer the question of adam, the data type is just text)
enter code here
<!DOCTYPE html>
<html>
<head>
<style>
div.maincontent{
border: none;
margin:0px;
padding:0px;
}
div.leftcol, div.rightcol {
/*
* Note that the left column and the right column use position fixed
* to make placement of the elements on top easier.
*/
position:fixed;
top:0px;
width:200px;
height: 100%;
background-color: green;
color: white;
}
div.leftcol{
left:0px;
}
div.rightcol{
right:0px;
}
div.middlecontent{
/*
* Note the left and right margin to place the div.
* With this margin you can
*/
margin:0px 200px 0px 200px;
position: absolute;
top:0px;
left:0px;
}
div.square{
float:left;
margin:0px;
width:200px;
height:200px;
border:10px solid black;
background-color: blue;
}
div.left_content, .right_content {
/*
*Initially do not display the div.left_content
*and div.right_content.
*I still set the all the styles here the divs have in common.
*/
margin:0px;
position:fixed;
margin:0px;
top:0px;
width:200px;
height: 100%;
background-color: blue;
color:white;
display: none; /* do not display */
}
div.square:hover > div.left_content {
/*
*When you hover over a square take from the children
*those with div.left_content and display them.
*The left one is displayed on top of the left div.leftcol
*/
left:0px;
display:block;
}
div.square:hover > div.right_content {
/*
*When you hover over a square take from the children
*those with div.right_content and display them.
*The right one is displayed on top of the right div.rightcol
*/
right:0px;
display:block;
}
</style>
</head>
<body>
<div class="maincontent">
<div class="leftcol">
<p>
Hover over the blue divs in the middle
</p>
<p>
This trick uses the > to find children of an element.
The children are only displayed when hovering over the parent element.
Look at the CSS how that is done. for instance for the left div it is
div.square:hover > div.left_content
</p>
<p> something inside the left column</p>
</div>
<div class="rightcol">
<p>something inside the right column</p>
</div>
<div class="middlecontent">
<div class="square">
<!--
this div has two children
a div with class="left_content" and
a div with class="right_content"
-->
<div class="left_content">
<p> first div </p>
<p> something as left content </p>
</div>
<div class="right_content">
<p> first div </p>
<p> something as right content </p>
</div>
</div>
<div class="square">
<div class="left_content">
<p> second div </p>
<p> something as left content </p>
</div>
<div class="right_content">
<p> second div </p>
<p> something as right content </p>
</div>
</div>
<div class="square">
<div class="left_content">
<p> third div </p>
<p> something as left content </p>
</div>
<div class="right_content">
<p> third div </p>
<p> something as right content </p>
</div>
</div>
</div>
</div>
</body>
</html>
So I'm making a gallery of fabrics and backgrounds for letters for a fraternity/sorority store in my college's town. If you don't know what I'm talking about, this is a fabric letter. You can see how it has a white outline (background) and a red inside (foreground). WELL, I want to make it so you can change both the foreground and background, simply by clicking it's similar image.
This is what I have so far
<script type="text/javascript">// <![CDATA[
function changeImage(filename)
{
document.mainimage.src = filename;
}// ]]></script>
with these for each fabrics:
<a href="javascript:changeImage('/wp-content/themes/collegiateconnectionbg/images/fabrics/foregrounds/37.jpg')">
<img src="/wp-content/themes/collegiateconnectionbg/images/fabrics/foregrounds/37.jpg"
alt="" width="100px" height="50px" /></a>
I really like how this works, but it's only good for one layer. Is there anyway I can add a layer below it, but still make it show at the top of the page? I know I'll have to use photoshop and transparency for both options, thats no problem, but I wanted to make sure I can do this before I start creating 600+ images.
I know I can play with z-index and css, but since I'm using wordpress the one example I read about here wasn't working or I didn't completely understand it, and messed up my entire page.
Also here's my tester webpage to see the current code in work. (if you click the navy&white stars image, you can see a very rough makeshift "A")
Thanks in advance!
I think I've got a solution for you.
Live Demo: http://jsfiddle.net/hM6dj/4/
More or less, you just need to create some images of the letters and leave their insides transparent.
Example
You'll notice that the area around the 'A' is white while the area within the lines of the 'A' is transparent.
Code
Then all you need to do is place this image in front of another image. The image in the background will bleed through the transparent image on top resulting in an 'A' with a pattern.
NOTE: I used data urls for the foreground letter so I wouldn't have to host the images anywhere. You can read about that here.
HTML
<div class='container'>
<div class='foreground foreground-Black'> </div>
<div class='background background-Cow'> </div>
</div>
<h2>Foreground Options</h2>
<input type='button' class='btnforeground' data-class='foreground-Black' value="Black" />
<input type='button' class='btnforeground' data-class='foreground-Red' value="Red" />
<input type='button' class='btnforeground' data-class='foreground-Green' value="Green" />
<h2>Background Options</h2>
<input type='button' class='btnbackground' data-class='background-Cow' value="Cow" />
<input type='button' class='btnbackground' data-class='background-Stars' value="Stars" />
<input type='button' class='btnbackground' data-class='background-Dots' value="Dots" />
JS
$('input[type="button"].btnforeground').click(function(){
$('div.container > div.foreground').removeClass().addClass('foreground').addClass($(this).attr('data-class'));
});
$('input[type="button"].btnbackground').click(function(){
$('div.container > div.background').removeClass().addClass('background').addClass($(this).attr('data-class'));
});
CSS
.container{
position:relative;
width: 200px;
height: 200px;
}
.foreground, .background{
width: 200px;
height: 200px;
background-repeat: no-repeat;
position:absolute;
z-index:100;
}
.background{
background-repeat:repeat;
z-index:50;
}
.background-Cow{
background-image:
url(http://www.collegiateconnectionbg.com/wp-content/themes/collegiateconnectionbg/images/fabrics/foregrounds/424.jpg);
}
.background-Stars{
background-image:
url(http://www.collegiateconnectionbg.com/wp-content/themes/collegiateconnectionbg/images/fabrics/foregrounds/48.jpg);
}
.background-Dots{
background-image:
url(http://www.collegiateconnectionbg.com/wp-content/themes/collegiateconnectionbg/images/fabrics/foregrounds/521.jpg);
}
/* Omitted due to StackOverflow character restrictions.
.foreground-Black{
background-image: url();
}
.foreground-Green{
background-image: url();
}
.foreground-Red{
background-image: url();
}
*/
EDIT
Using Google Chrome's Developer tools, it looks like you have some HTML intermixed with your JavaScript (notice the Paragraph Tags <p>, </p>).
Also I would wrap the jQuery events in a ready function (The JS Fiddle did this automatically so it wasn't obvious from the code example).
JS
$(function(){
$('input[type="button"].btnforeground').click(function(){
$('div.container > div.foreground').removeClass().addClass('foreground').addClass($(this).attr('data-class'));
});
$('input[type="button"].btnbackground').click(function(){
$('div.container > div.background').removeClass().addClass('background').addClass($(this).attr('data-class'));
});
});
EDIT2
A few things.
Your classes:
.foreground
.background
.foreground-Black
.foreground-Cow
etc...
have almost none of the properties set from my example. You should be able to take the css verbatim from the jsfiddle I provided.
You've named the container the class .viewer, but are referencing .container in your JavaScript. These elements must match for the JavaScript to be able to find the appropriate html element to update.