Creating Facebook share button that is accessibility friendly - javascript

Im trying to create a facebook share button for my page that is accessibe by tab-indexing and pressing enter (for accessibility). A lot of the solutions I had created were using javascript and wouldn't load my script until after tabbing out of the share button.
So far I have created this button.
<a tabindex="0" class="fb-share-button" href="javascript:window.location=%22http://www.facebook.com/sharer.php?u=%22+encodeURIComponent(document.location)+%22&t=%22+encodeURIComponent(document.title)" data-layout="button_count">
<img src="/sites/all/themes/saralee/images/icon-facebook.png" alt="facebook icon">
</a>
This almost gives the desired outcome except I need it to open in either a new tab or an iframe. Which I haven't been able to do with keeping a valid url. (since the above button parses the current url). using target="_blank" doesnt work.

Quick Note - The best option would be to build the URL on the server and serve it as part of the HTML, use the JavaScript option below if you are unable to do that for any reason.
All other points other than the URL below are important to make your share 'button' accessible.
Instead of using an inline function on the button, build the URL in a separate JavaScript function and then apply it on document load.
JS
var URL = "http://www.facebook.com/sharer.php?u=%22+encodeURIComponent(document.location)+%22&t=%22+encodeURIComponent(document.title)";
var elements = document.getElementsByClassName("fb-share-button");
elements[0].setAttribute("href", URL); //using [0] to get first element, would be better to use an ID or simply **build the URL on the server before loading the page** and serve it as part of the HTML.
HTML
<a target="_blank" class="fb-share-button" href="fallback URL In Case Of JS Failure" data-layout="button_count">
<img src="/sites/all/themes/saralee/images/icon-facebook.png" alt=""/>
<span class="visually-hidden">Share This Page on Facebook (opens in new window)</span>
</a>
CSS
.visually-hidden {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap; /* added line */
}
Because you are no longer setting window.location using target="_blank" will work as expected (window.location was overriding the functionality of the link).
Also notice that I removed the tabindex as links are focusable by default (so it isn't needed).
I also changed the alt description to "" and added a 'visually hidden' <span> containing the purpose of the link.
I have included the CSS to make something 'visually-hidden' by applying that class to an item, as it is a useful tool to have in your accessibility toolkit!
Note how I indicated the link 'opens in a new window' within brackets to let screen readers know the behaviour of this link.
An empty alt tag is used to mark an image as decorative (make sure it is empty and not null, i.e. alt="" NOT alt).
Visually Hidden text is still accessible to screen readers but will not show visually.

Related

Search and replace a string with hyperlink

I'm not sure if this is possible but I am helping out with a rather large website that was compiled with .aspx
We are wanting to change a link on the website but there is no actual place to edit the text for the link. I can however use CSS or possibly Javascript to edit the site.
<li>
Other Pages
</li>
<li>
Blue Page
</li>
I want to change the link and text that says Blue Page to something such as Red Page.
example:
<li>
Red Page
</li>
Is it possible to search and replace the text for that hyperlink using CSS?
I have already tried creating an overlay that covers the original text and link but it doesn't position properly on
the page depending on the browser the user uses.
example:
<div id="cover"></div>
#cover {
background: url('../images/cover.png') no-repeat;
top: 80%;
margin-left: 0px;
height: 30px;
width: 203px;
position: relative;
}
Anyone have any other ideas on how I can possibly replace text with CSS or Javascript?
Try something like this with JavaScript,
var bluePage = document.querySelectorAll("a[href='bluepage.aspx']");
if (bluePage[0]) {
bluePage[0].setAttribute("href", "redpage.aspx");
bluePage[0].innerHTML="Red Page";
}
CSS would only change the appearance of the link. The href URI would remain the same underneath, and if a user clicked the link, they'd be taken to the old link location. Hence, you need to use Javascript for this.
As per this answer, you can do search and replace with Javascript like so:
<script type="text/javascript">
function replaceScript() {
var toReplace = 'http://google.com';
var replaceWith ='http://yahoo.com';
document.body.innerHTML = document.body.innerHTML.replace(toReplace, replaceWith);
}
</script>
And you can initialize this function on page load like so:
<body onload="replaceScript();">
That should replace the strings throughout the page. However, the major drawback here is that it only replaces the links on page load. The pages saved on your server will still have the old links, which means there will be a small delay (tens to hundreds of milliseconds, probably) when the user loads any page, because the script needs to do its work, which takes a little bit of time. Also, it won't work if the user has JavaScript disabled in their browser, or if it's visited by a non-browser agent (like bot, crawler or web service), which is less than perfect.

How do I find links with no text?

I'm working on WCAG compliance and I need to fix "Empty link" errors.
This is an example of one of the elements providing the error:
<a style="bottom: 0px; left: 7px; width: 25px; cursor: default;" class="histogram_bar_link" title="Less than 2,016 (0)" href="#"
onclick="AjaxControlToolkit.SliderRefinementControl.FindAndSetSliderHandlesAndValuesToRange(" ctl00_ctl43_g_453d6d26_9535_440a_ba72_b7b88de22f31_csr5
", 0, 1, this); return false;" activebarid="ctl00_ctl43_g_453d6d26_9535_440a_ba72_b7b88de22f31_csr5_HistogramActiveBar0" disabled="disabled">
<div id="ctl00_ctl43_g_453d6d26_9535_440a_ba72_b7b88de22f31_csr5_HistogramBgBar0" class="histogram_bar_background">
<div id="ctl00_ctl43_g_453d6d26_9535_440a_ba72_b7b88de22f31_csr5_HistogramActiveBar0" class="histogram_bar_active" style="height: 0px; margin-top: 50px;">
</div>
</a>
I need to find this element and other anchor tags which contain no text within so I can fix them through JS
This is not a link. Do not try to fix it client-side, just correct the HTML. Ideally if you update whatever control generates that HTML, then you do not need to rely on client-side script.
1. Choosing the right control
Let's address the first issue, using the right element...
Does the Control Take Me to Another Page? Use an Anchor
If, when clicked, tapped, or activated by keyboard or voice (or insert novel interaction method here), the user is whisked to another URL (including an anchor on the same page), then use <a href="[URL]">. Make sure you use the href attribute and that it has a real URL, not a “#” (otherwise you’re probably relying on JavaScript, which is not at all necessary for a hyperlink). If an href points to just a “#”, then you’re probably doing it wrong. If it points to a named anchor as part of your progressive enhancement efforts, then that’s totally valid.
Does the Control Change Something on the Current Page? Use a Button
If, when activated, the user is not moved from the page (or to an anchor within the page), but instead is presented with a new view (message boxes, changes in layout, etc.), then use a <button>. While you could use an <input type="button">, it’s more likely you’ll get into conflicts with pre-existing styles and subsequent developers (like me).
Does the Control Submit Form Fields? Use a Submit
If, when activated, information the user has entered (either by manually typing or by choosing items on the screen) is being sent back to the server, then use an <input type="submit">. This had better live within a <form>. If you need more styling control or have to embed more than just a simple text string, use a <button type="submit"> instead. I tend to prefer <input type="submit"> as I find it runs into fewer conflicts (both mentally and stylistically) with developers.
Keyboard User Consideration
Think of keyboard users for a moment. A hyperlink can be fired by pressing the enter key. But a true button can be fired by pressing the enter key or the space bar. When a hyperlink has focus and the user presses the space bar, the page will scroll one screenful. If there isn’t more to scroll then the user just experiences nothing. Given a set of interface elements that look the same, if some work with a space bar and some don’t, you can’t expect users to have much confidence in how the page behaves.
I have a CodePen demo that shows this in action: http://s.codepen.io/aardrian/debug/PZQJyd
I think it’s also worth mentioning that events triggered by a space bar only fire when the key is released, whereas using the Enter key will fire the event as soon as you press the key down (prior to releasing it).
For reference: http://adrianroselli.com/2016/01/links-buttons-submits-and-divs-oh-hell.html
2. Giving it an accessible name
Now let's talk about how you get an accessible name into that button. I assume you do not want it to be seen visually. In that case, give it a class of visually-hidden and apply these styles:
.visually-hidden {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding:0 !important;
border:0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
This will allow it to be read by screen readers. It also means you can (and should) dump that title attribute.
3. Combine it
Now take your control and adjust it accordingly:
<button style="…" class="histogram_bar_link" onclick="…" disabled="disabled">
<span class="visually-hidden">Less than 2,016 (0)</span>
<div id="…" class="histogram_bar_background">
<div id="…" class="histogram_bar_active" style="…"></div>
</div>
</button>
I have turned it into a <button> and given it an accessible name by inserting a <span> with the visually-hidden class to hide it from view.

How can I replace an image being shown via JS?

I want to embed Wanelo's share button.
This is the embed code:
<a class="wanelo-save-button"
href="//wanelo.com/"
data-url=""
data-title=""
data-image=""
data-price=""></a><script async="true" type="text/javascript" src="//cdn-saveit.wanelo.com/bookmarklet/3/save.js"></script>
When I embed it, I get this button:
I want to replace that button with their icon, which looks like this:
Being new to JS, I am unable to understand how I can swap that button from being generated and have this icon be in it's place while still making the share feature work.
Here's their link: http://wanelo.com/about/buttons#save-button
My JSFIDDLE:
http://jsfiddle.net/VCG8c/
Please point me in the right direction.
The button is being loaded dynamically via JS with inline CSS. So in the anchor tag, do this:
style="background:none !important;"
Ok, here is a the updated version of your fiddle, all nice and working. Basically, the little JS snippet at "save.js" changes your anchor by adding an appropriate background image (in this case, the rectangular button that says "Wanelo"). So, that will need to be replaced inline - this will change the background image to the one you want. Of course, the default CSS style associated with "wanelo-save-button" looks like crap, so you'll need to make some stylistic changes in a custom class.
The JS:
setTimeout(function(){
//Get the anchor element
var anchor = document.querySelectorAll('a.wanelo-save-button')[0];
//Change the backgroundImage property
anchor.style.backgroundImage = 'url("http://i.stack.imgur.com/X0r5e.png")';
//Add an appropriate CSS class for styling
anchor.className += ' myCheckerBackground'
}, 3000);
And the CSS:
a.wanelo-save-button.myCheckerBackground{
height: 88px;
width: 101px;
background-repeat: no-repeat;
background-size: cover;
}
You'll notice that I used "setTimeout." This is due to a limitation on jsFiddle. In the production environment, you'll want to place your custom js file AFTER save.js loads, then in THAT file create a DOMContentLoaded listener to make sure the first Wanelo image has loaded before you modify it.
<a class="wanelo-save-button" href="//wanelo.com/">
<img src="whatever image you want here" alt="">
</a>
<script async="true" type="text/javascript" src="//cdn-saveit.wanelo.com/bookmarklet/3/save.js</script>
Works.

Changing The Size of Twitter's Follow Button?

I'm looking at the new Twitter Follow Button (https://twitter.com/about/resources/followbutton), but unfortunately my sidebar is smaller than the default size, thus throwing my whole site out of whack.
Is there an easy way to hack the script to resize the button, or at least to put a line break between the actual follow button and the account name?
If you look at the page source, then your twitter code converts from
<div class="twitter">
<!-- twitter code here -->
</div>
to
<div class="twitter">
<iframe ...>...</iframe>
</div>
Now it's easy to change the width of the button via css:
.twitter iframe {
width: 80px !important;
}
I'd wrap the button in a container with a nice class name and use CSS to adjust the styling.
.twitter-button-container{
width: 100px;
height:100px;
}
Something like that.
UPDATE
On second thought, it seems that the image is a background image to the anchor tag. I don't think it's possible to resize background images using CSS etc. You'd need to have the image in an img tag.

Don't load hidden images

I have a bunch of hidden images on my website. Their container DIVs have style="display: none". Depending on the user's actions, some images may be revealed via javascript. The problem is that all my images are loaded upon opening the page. I would like to put less strain on the server by only loading images that eventually become visible. I was wondering if there was a pure CSS way to do this. Here are two hacky/complicated ways I am currently doing it. As you can see, it's not clean code.
<div id="hiddenDiv">
<img src="spacer.gif" />
</div>
.reveal .img {
background-image: url(flower.png);
}
$('hiddenDiv').addClassName('reveal');
Here is method 2:
<img id="flower" fakeSrc="flower.png" />
function revealImage(id) {
$('id').writeAttribute(
'src',
$('id').readAttribute('fakeSrc')
);
}
revealImage('flower');
The browser will load any images that has a src attribute set, so what you want to do is to use data-src in the markup and use JavaScript to set the src attribute when you want it to load.
<img class="hidden" data-src="url/to/image.jpg" />
I created this tiny plugin that will take care of the problem:
(function($){
// Bind the function to global jQuery object.
$.fn.reveal = function(){
// Arguments is a variable which is available within all functions
// and returns an object which holds the arguments passed.
// It is not really an array, so by calling Array.prototype
// he is actually casting it into an array.
var args = Array.prototype.slice.call(arguments);
// For each elements that matches the selector:
return this.each(function(){
// this is the dom element, so encapsulate the element with jQuery.
var img = $(this),
src = img.data("src");
// If there is a data-src attribute, set the attribute
// src to make load the image and bind an onload event.
src && img.attr("src", src).load(function(){
// Call the first argument passed (like fadeIn, slideIn, default is 'show').
// This piece is like doing img.fadeIn(1000) but in a more dynamic way.
img[args[0]||"show"].apply(img, args.splice(1));
});
});
}
}(jQuery));
Execute .reveal on the image(s) you want to load/show:
$("img.hidden").reveal("fadeIn", 1000);
See test case on jsFiddle.
Here's a jQuery solution:
$(function () {
$("img").not(":visible").each(function () {
$(this).data("src", this.src);
this.src = "";
});
var reveal = function (selector) {
var img = $(selector);
img[0].src = img.data("src");
}
});
It's similar to your solution, except it doesn't use the fakeSrc attribute in the markup. It clears the src attribute to stop it from loading and stores it elsewhere. Once you are ready to show the image, you use the reveal function much like you do in your solution. I apologize if you do not use jQuery, but the process should be transferable to whichever framework (if any) that you use.
Note: This code specifically must be ran before the window has fired the load event but after the DOM has been loaded.
Weirdly, there's no answer about native lazy loading which is implemented in the majority of the browsers already.
you can do it by adding loading="lazy" attribute to your image.
Addy Osmani wrote a great article about it. You can read more about lazy loading here: https://addyosmani.com/blog/lazy-loading/
It partially depends on how your images must be placed in your code. Are you able to display the images as the background of a <div>, or are you required to use the <img> tag? If you need the <img> tag, you may be screwed depending on the browser being used. Some browsers are smart enough to recognize when an image is inside of a hidden object or in an object of 0 width/height and not load it since it's essentially invisible, anyway. For this reason many people will suggest putting an image in a 1x1 pixel <span> if you want the image to be pre-loaded but not visible.
If you don't require the <img> tag, most browsers won't load images referenced by CSS until the element in question becomes visible.
Mind you that short of using AJAX to download the image there's no way to be 100% sure the browser won't pre-load the image anyway. It's not unbelievable that a browser would want to pre-load anything it assumes may be used later in order to "speed up" the average load times.
Using CSS to put the image an unused class, then adding that class to an element with javascript is going to be your best bet. If you don't use image tags at all, this solution becomes a bit more obvious.
Though, for perspective, most people have the opposite problem where they want to preload an image so it shows up instantly when it's told to be shown.
If you are okay relying on scripting, there is the background image method and the image src method. Put simply, set all your hidden images to some very small image (reduce strain on server) or one that does not exist at all (who cares? The visitor cannot see the image-missing [X] anyway, the div is hidden) then change it with script...
<img src="I_do_not_exist.jpg" id="my_image" />
<input type="button" onclick="document.getElementById('my_image').src='I_exist.jpg';" Value="change image" />
<br /><br /><br />
<div id="mydiv" style="width:40px; height:40px; border:2px solid blue"></div>
<input type="button" onclick="document.getElementById('my_div').style.width='455px';document.getElementById('my_div').style.height='75px';document.getElementById('my_div').style.backgroundImage='url(I_exist.jpg)';" Value="change background image" />
I left a width on the above example to show that nothing is in the div image wise until you ask it to load.
If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.
You can do the following for a pure CSS solution, it also makes the img box actually behave like an img box in a responsive design setting (that's what the transparent png is for), which is especially useful if your design uses responsive-dynamically-resizing images.
<img style="display: none; height: auto; width:100%; background-image:
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block
visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
The image will only be loaded when the media query tied to visible-lg-block is triggered and display:none is changed to display:block. The transparent png is used to allow the browser to set appropriate height:width ratios for your <img> block (and thus the background-image) in a fluid design (height: auto; width: 100%).
1078/501 = ~2.15 (large screen)
400/186 = ~2.15 (small screen)
So you end up with something like the following, for 3 different viewports:
<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">
And only your default media viewport size images load during the initial load, then afterwards, depending on your viewport, images will dynamically load.
And no javascript!

Categories